Skip to content

Commit

Permalink
Support shared imports in route chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
markdalgleish authored Oct 2, 2024
1 parent 6564892 commit cb037e6
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 32 deletions.
20 changes: 20 additions & 0 deletions packages/react-router-dev/vite/route-chunks-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,26 @@ describe("route chunks", () => {
`);
});

test("shared imports", () => {
const code = dedent`
import { shared } from "./shared";
export const chunk = shared("chunk");
export const main = shared("main");
`;
expect(hasChunkableExport(code, "chunk", ...cache)).toBe(true);
expect(hasChunkableExport(code, "main", ...cache)).toBe(true);
expect(getChunkedExport(code, "chunk", {}, ...cache)?.code)
.toMatchInlineSnapshot(`
"import { shared } from "./shared";
export const chunk = shared("chunk");"
`);
expect(getChunkedExport(code, "main", {}, ...cache)?.code)
.toMatchInlineSnapshot(`
"import { shared } from "./shared";
export const main = shared("main");"
`);
});

test("re-exports using shared statement", () => {
const code = dedent`
export { chunk1, chunk2, main } from "./shared";
Expand Down
41 changes: 9 additions & 32 deletions packages/react-router-dev/vite/route-chunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function assertNodePathIsStatement(
}`
);
}

function assertNodePathIsVariableDeclarator(
path: NodePath | NodePath[] | null | undefined
): asserts path is NodePath<VariableDeclarator> {
Expand Down Expand Up @@ -469,11 +470,6 @@ export function hasChunkableExport(
return false;
}

invariant(
dependencies.topLevelStatements.size > 0,
`Expected export "${exportName}" to have top level statements if the set exists`
);

// Loop through all other exports to see if they have top level non-import
// statements in common with the export we're trying to chunk.
for (let [currentExportName, currentDependencies] of exportDependencies) {
Expand All @@ -498,35 +494,16 @@ export function hasChunkableExport(
}
}

// Loop through all other exports to see if they have imported identifiers
// in common with the export we're trying to chunk.
if (dependencies.importedIdentifierNames.size > 0) {
for (let [
currentExportName,
currentDependencies,
] of exportDependencies) {
if (currentExportName === exportName) {
continue;
}

// As soon as we find any imported identifiers in common with another
// export, we know this export cannot be placed in its own chunk. Note
// that the chunk can still share top level import statements with
// other exports because we filter out all unused imports, so we can
// treat each imported identifier as a separate entity in this check.
if (
setsIntersect(
currentDependencies.importedIdentifierNames,
dependencies.importedIdentifierNames
)
) {
return false;
}
}
// If the export we're trying to chunk depends on more than one exported
// variable declarator (where one of them might be the chunked export
// itself), it means it must depend on other exports and can't be chunked,
// so we can bail out early before comparing against other exports.
if (dependencies.exportedVariableDeclarators.size > 1) {
return false;
}

// Loop through all other exports to see if they have exported variable
// declarators in common with the export we're trying to chunk.
// Loop through all other exports to see if they depend on the export
// we're trying to chunk.
if (dependencies.exportedVariableDeclarators.size > 0) {
for (let [
currentExportName,
Expand Down

0 comments on commit cb037e6

Please sign in to comment.