Files
Donny/강동윤andGitHub 3a5b73d2d6 perf(turbopack): Remove ImportBinding fragments (#78470)
### What?

Make the `ImportBinding` node a phantom node.

### Why?

Because they are not used. We have to import directly from the original
module because of the static analysis like `next/dynamic`. So I modified
the tree shaking to import directly with
https://github.com/vercel/next.js/pull/71704. But #71704 didn't remove
the concept of `ImportBinding`. This PR finishes the work of using
direct imports.

Additionally, this PR introduces `ReexportBinding` fragments because
these are not phantom nodes. I'll check if it would be possible to
remove `ReexportBinding` fragments with follow-up PRs.

### How?

 - Closes PACK-4366
2025-04-28 15:10:59 +00:00

15 KiB

Items

Count: 17

Item 1: Stmt 0, ImportOfModule

import { upper } from "module";

  • Hoisted
  • Side effects

Item 2: Stmt 0, ImportBinding(0)

import { upper } from "module";

  • Hoisted
  • Declares: upper

Item 3: Stmt 1, VarDeclarator(0)

export let foobar = "foo";

  • Declares: foobar
  • Write: foobar

Item 4: Stmt 2, VarDeclarator(0)

export const foo = foobar;

  • Declares: foo
  • Reads: foobar
  • Write: foo

Item 5: Stmt 3, VarDeclarator(0)

const bar = "bar";

  • Declares: bar
  • Write: bar

Item 6: Stmt 4, Normal

foobar += bar;

  • Reads: bar, foobar
  • Write: foobar

Item 7: Stmt 5, VarDeclarator(0)

let foobarCopy = foobar;

  • Declares: foobarCopy
  • Reads: foobar
  • Write: foobarCopy

Item 8: Stmt 6, Normal

foobar += "foo";

  • Reads: foobar
  • Write: foobar

Item 9: Stmt 7, Normal

console.log(foobarCopy);

  • Side effects
  • Reads: foobarCopy

Item 10: Stmt 8, Normal

foobarCopy += "Unused";

  • Reads: foobarCopy
  • Write: foobarCopy

Item 11: Stmt 9, Normal

function internal() {
    return upper(foobar);
}

  • Hoisted
  • Declares: internal
  • Reads (eventual): upper, foobar
  • Write: internal

Item 12: Stmt 10, Normal

export function external1() {
    return internal() + foobar;
}

  • Hoisted
  • Declares: external1
  • Reads (eventual): internal, foobar
  • Write: external1

Item 13: Stmt 11, Normal

export function external2() {
    foobar += ".";
}

  • Hoisted
  • Declares: external2
  • Write: external2
  • Write (eventual): foobar

Phase 1

graph TD
    Item1;
    Item2;
    Item3;
    Item4;
    Item5;
    Item6;
    Item7;
    Item8;
    Item9;
    Item10;
    Item11;
    Item12;
    Item13;
    Item14;
    Item14["export foobar"];
    Item15;
    Item15["export foo"];
    Item16;
    Item16["export external1"];
    Item17;
    Item17["export external2"];

Phase 2

graph TD
    Item1;
    Item2;
    Item3;
    Item4;
    Item5;
    Item6;
    Item7;
    Item8;
    Item9;
    Item10;
    Item11;
    Item12;
    Item13;
    Item14;
    Item14["export foobar"];
    Item15;
    Item15["export foo"];
    Item16;
    Item16["export external1"];
    Item17;
    Item17["export external2"];
    Item4 --> Item3;
    Item6 --> Item5;
    Item6 --> Item3;
    Item6 -.-> Item4;
    Item7 --> Item6;
    Item7 --> Item3;
    Item8 --> Item6;
    Item8 --> Item3;
    Item8 -.-> Item7;
    Item9 --> Item7;
    Item9 --> Item1;
    Item9 -.-> Item2;
    Item9 --> Item8;
    Item9 -.-> Item11;
    Item10 --> Item7;
    Item10 -.-> Item9;
    Item14 --> Item8;
    Item14 --> Item3;
    Item15 --> Item4;
    Item16 --> Item12;
    Item17 --> Item13;

Phase 3

graph TD
    Item1;
    Item2;
    Item3;
    Item4;
    Item5;
    Item6;
    Item7;
    Item8;
    Item9;
    Item10;
    Item11;
    Item12;
    Item13;
    Item14;
    Item14["export foobar"];
    Item15;
    Item15["export foo"];
    Item16;
    Item16["export external1"];
    Item17;
    Item17["export external2"];
    Item4 --> Item3;
    Item6 --> Item5;
    Item6 --> Item3;
    Item6 -.-> Item4;
    Item7 --> Item6;
    Item7 --> Item3;
    Item8 --> Item6;
    Item8 --> Item3;
    Item8 -.-> Item7;
    Item9 --> Item7;
    Item9 --> Item1;
    Item9 -.-> Item2;
    Item9 --> Item8;
    Item9 -.-> Item11;
    Item10 --> Item7;
    Item10 -.-> Item9;
    Item14 --> Item8;
    Item14 --> Item3;
    Item15 --> Item4;
    Item16 --> Item12;
    Item17 --> Item13;
    Item11 --> Item2;
    Item11 --> Item8;
    Item11 --> Item3;
    Item12 --> Item11;
    Item12 --> Item8;
    Item12 --> Item3;
    Item13 -.-> Item14;
    Item13 --> Item3;

Phase 4

graph TD
    Item1;
    Item2;
    Item3;
    Item4;
    Item5;
    Item6;
    Item7;
    Item8;
    Item9;
    Item10;
    Item11;
    Item12;
    Item13;
    Item14;
    Item14["export foobar"];
    Item15;
    Item15["export foo"];
    Item16;
    Item16["export external1"];
    Item17;
    Item17["export external2"];
    Item4 --> Item3;
    Item6 --> Item5;
    Item6 --> Item3;
    Item6 -.-> Item4;
    Item7 --> Item6;
    Item7 --> Item3;
    Item8 --> Item6;
    Item8 --> Item3;
    Item8 -.-> Item7;
    Item9 --> Item7;
    Item9 --> Item1;
    Item9 -.-> Item2;
    Item9 --> Item8;
    Item9 -.-> Item11;
    Item10 --> Item7;
    Item10 -.-> Item9;
    Item14 --> Item8;
    Item14 --> Item3;
    Item15 --> Item4;
    Item16 --> Item12;
    Item17 --> Item13;
    Item11 --> Item2;
    Item11 --> Item8;
    Item11 --> Item3;
    Item12 --> Item11;
    Item12 --> Item8;
    Item12 --> Item3;
    Item13 -.-> Item14;
    Item13 --> Item3;

Final

graph TD
    N0["Items: [ItemId(0, ImportOfModule)]"];
    N1["Items: [ItemId(0, ImportBinding(0))]"];
    N2["Items: [ItemId(1, VarDeclarator(0))]"];
    N3["Items: [ItemId(2, VarDeclarator(0))]"];
    N4["Items: [ItemId(3, VarDeclarator(0)), ItemId(4, Normal)]"];
    N5["Items: [ItemId(5, VarDeclarator(0))]"];
    N6["Items: [ItemId(6, Normal)]"];
    N7["Items: [ItemId(7, Normal), ItemId(8, Normal)]"];
    N8["Items: [ItemId(9, Normal)]"];
    N9["Items: [ItemId(10, Normal), ItemId(Export(("external1", #2), "external1"))]"];
    N10["Items: [ItemId(11, Normal), ItemId(Export(("external2", #2), "external2")), ItemId(Export(("foobar", #2), "foobar"))]"];
    N11["Items: [ItemId(Export(("foo", #2), "foo"))]"];
    N3 --> N2;
    N8 --> N6;
    N4 --> N2;
    N4 -.-> N3;
    N5 --> N4;
    N5 --> N2;
    N6 --> N4;
    N6 --> N2;
    N6 -.-> N5;
    N9 --> N6;
    N7 -.-> N8;
    N7 --> N6;
    N7 -.-> N1;
    N7 --> N0;
    N7 --> N5;
    N10 --> N2;
    N9 --> N8;
    N1 --> N0;
    N11 --> N3;
    N8 --> N2;
    N9 --> N2;
    N8 --> N1;

Entrypoints

{
    ModuleEvaluation: 7,
    Export(
        "external1",
    ): 9,
    Export(
        "external2",
    ): 10,
    Export(
        "foo",
    ): 11,
    Export(
        "foobar",
    ): 10,
    Exports: 12,
}

Modules (dev)

Part 0

import "module";

Part 1

import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};

Part 2

let foobar = "foo";
export { foobar as a } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 3

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
const foo = foobar;
export { foo as b } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 4

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 3
};
const bar = "bar";
foobar += bar;
export { bar as c } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 5

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 4
};
let foobarCopy = foobar;
export { foobarCopy as d } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 6

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 4
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 5
};
foobar += "foo";

Part 7

import { d as foobarCopy } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -5
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 8
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 1
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};
console.log(foobarCopy);
foobarCopy += "Unused";
export { };

Part 8

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};
import { upper } from "module";
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
function internal() {
    return upper(foobar);
}
export { internal as e } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 9

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import { e as internal } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -8
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
function external1() {
    return internal() + foobar;
}
export { external1 };
export { external1 as f } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 10

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
function external2() {
    foobar += ".";
}
export { external2 };
export { foobar };
export { external2 as g } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 11

import { b as foo } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -3
};
export { foo };

Part 12

export { external1 } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export external1"
};
export { external2 } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export external2"
};
export { foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export foobar"
};
export { foo } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export foo"
};

Merged (module eval)

import { d as foobarCopy } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -5
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 8
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 1
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};
console.log(foobarCopy);
foobarCopy += "Unused";
export { };

Entrypoints

{
    ModuleEvaluation: 7,
    Export(
        "external1",
    ): 9,
    Export(
        "external2",
    ): 10,
    Export(
        "foo",
    ): 3,
    Export(
        "foobar",
    ): 11,
    Exports: 12,
}

Modules (prod)

Part 0

import "module";

Part 1

import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};

Part 2

let foobar = "foo";
export { foobar as a } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 3

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
const foo = foobar;
export { foo };
export { foo as b } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 4

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
const bar = "bar";
foobar += bar;
export { bar as c } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 5

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 4
};
let foobarCopy = foobar;
export { foobarCopy as d } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 6

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 4
};
foobar += "foo";

Part 7

import { d as foobarCopy } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -5
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
console.log(foobarCopy);
export { };

Part 8

import { d as foobarCopy } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -5
};
foobarCopy += "Unused";

Part 9

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};
import { upper } from "module";
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
function internal() {
    return upper(foobar);
}
function external1() {
    return internal() + foobar;
}
export { external1 };
export { internal as e } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};
export { external1 as f } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 10

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
function external2() {
    foobar += ".";
}
export { external2 };
export { external2 as g } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 11

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
export { foobar };

Part 12

export { foo } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export foo"
};
export { external1 } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export external1"
};
export { external2 } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export external2"
};
export { foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export foobar"
};

Merged (module eval)

import { d as foobarCopy } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -5
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
console.log(foobarCopy);
export { };

Entrypoints

{
    ModuleEvaluation: 7,
    Export(
        "external1",
    ): 9,
    Export(
        "external2",
    ): 10,
    Export(
        "foo",
    ): 3,
    Export(
        "foobar",
    ): 11,
    Exports: 12,
}

Merged (external1)

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};
import { upper } from "module";
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
function internal() {
    return upper(foobar);
}
function external1() {
    return internal() + foobar;
}
export { external1 };
export { internal as e } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};
export { external1 as f } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Entrypoints

{
    ModuleEvaluation: 7,
    Export(
        "external1",
    ): 9,
    Export(
        "external2",
    ): 10,
    Export(
        "foo",
    ): 3,
    Export(
        "foobar",
    ): 11,
    Exports: 12,
}

Merged (external1,external2)

import { a as foobar } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: -2
};
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 0
};
import { upper } from "module";
import "__TURBOPACK_PART__" assert {
    __turbopack_part__: 6
};
function internal() {
    return upper(foobar);
}
function external1() {
    return internal() + foobar;
}
export { external1 };
export { internal as e } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};
export { external1 as f } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};
function external2() {
    foobar += ".";
}
export { external2 };
export { external2 as g } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};