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

4.0 KiB

Items

Count: 6

Item 1: Stmt 0, ImportOfModule

import { NextResponse } from "next/server";

  • Hoisted
  • Side effects

Item 2: Stmt 0, ImportBinding(0)

import { NextResponse } from "next/server";

  • Hoisted
  • Declares: NextResponse

Item 3: Stmt 1, VarDeclarator(0)

export const GET = (req)=>{
    return NextResponse.json({
        pathname: req.nextUrl.pathname
    });
};

  • Declares: GET
  • Reads: NextResponse
  • Write: NextResponse, GET

Item 4: Stmt 2, VarDeclarator(0)

export const runtime = "edge";

  • Declares: runtime
  • Write: runtime

Phase 1

graph TD
    Item1;
    Item2;
    Item3;
    Item4;
    Item5;
    Item5["export GET"];
    Item6;
    Item6["export runtime"];

Phase 2

graph TD
    Item1;
    Item2;
    Item3;
    Item4;
    Item5;
    Item5["export GET"];
    Item6;
    Item6["export runtime"];
    Item3 --> Item2;
    Item5 --> Item3;
    Item6 --> Item4;

Phase 3

graph TD
    Item1;
    Item2;
    Item3;
    Item4;
    Item5;
    Item5["export GET"];
    Item6;
    Item6["export runtime"];
    Item3 --> Item2;
    Item5 --> Item3;
    Item6 --> Item4;

Phase 4

graph TD
    Item1;
    Item2;
    Item3;
    Item4;
    Item5;
    Item5["export GET"];
    Item6;
    Item6["export runtime"];
    Item3 --> Item2;
    Item5 --> Item3;
    Item6 --> Item4;

Final

graph TD
    N0["Items: [ItemId(0, ImportOfModule), ItemId(1, VarDeclarator(0)), ItemId(Export(("GET", #2), "GET"))]"];
    N1["Items: [ItemId(0, ImportBinding(0))]"];
    N2["Items: [ItemId(2, VarDeclarator(0)), ItemId(Export(("runtime", #2), "runtime"))]"];
    N0 --> N1;

Entrypoints

{
    ModuleEvaluation: 0,
    Export(
        "GET",
    ): 0,
    Export(
        "runtime",
    ): 2,
    Exports: 2,
}

Modules (dev)

Part 0

import { NextResponse } from "next/server";
import "next/server";
const GET = (req)=>{
    return NextResponse.json({
        pathname: req.nextUrl.pathname
    });
};
export { GET };
export { GET as a } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};
export { };

Part 1

const runtime = "edge";
export { runtime };
export { runtime as b } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 2

export { GET } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export GET"
};
export { runtime } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export runtime"
};

Merged (module eval)

import { NextResponse } from "next/server";
import "next/server";
const GET = (req)=>{
    return NextResponse.json({
        pathname: req.nextUrl.pathname
    });
};
export { GET };
export { GET as a } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};
export { };

Entrypoints

{
    ModuleEvaluation: 0,
    Export(
        "GET",
    ): 0,
    Export(
        "runtime",
    ): 2,
    Exports: 2,
}

Modules (prod)

Part 0

import { NextResponse } from "next/server";
import "next/server";
const GET = (req)=>{
    return NextResponse.json({
        pathname: req.nextUrl.pathname
    });
};
export { GET };
export { GET as a } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};
export { };

Part 1

const runtime = "edge";
export { runtime };
export { runtime as b } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};

Part 2

export { GET } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export GET"
};
export { runtime } from "__TURBOPACK_PART__" assert {
    __turbopack_part__: "export runtime"
};

Merged (module eval)

import { NextResponse } from "next/server";
import "next/server";
const GET = (req)=>{
    return NextResponse.json({
        pathname: req.nextUrl.pathname
    });
};
export { GET };
export { GET as a } from "__TURBOPACK_VAR__" assert {
    __turbopack_var__: true
};
export { };