Skip to content

Commit 5726d14

Browse files
committed
fix: remove unnecessary chunks
1 parent 4496c26 commit 5726d14

File tree

3 files changed

+95
-26
lines changed

3 files changed

+95
-26
lines changed

src/cli.ts

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { cleanDist } from './utils/clean-dist.js';
1414
import type { EntryPointValid } from './utils/get-entry-points/types.js';
1515
import type { SrcDistPair } from './types.js';
1616
import { entrySymbol } from './rollup/types';
17+
import { filterUnnecessaryOutputs } from './rollup/plugins/filter-unnecessary-outputs.js';
1718

1819
const { stringify } = JSON;
1920

@@ -217,32 +218,7 @@ if (tsconfigTarget) {
217218
return Promise.all(rollupConfig.output.map(
218219
(outputOption) => {
219220
const inputNames = outputOption[entrySymbol].inputNames!;
220-
221-
/**
222-
* pkgroll merges shared configs, which causes it to build extra entry points
223-
* that weren't actually requested. We need to filter those out here to:
224-
* - Avoid generating unnecessary output files
225-
* - Prevent unexpected files from overwriting the ones we actually want
226-
*/
227-
outputOption.plugins = [{
228-
name: 'filter-unnecessary-outputs',
229-
generateBundle: (_options, bundle) => {
230-
for (const fileName in bundle) {
231-
if (!Object.hasOwn(bundle, fileName)) {
232-
continue;
233-
}
234-
235-
const chunk = bundle[fileName];
236-
if (
237-
'isEntry' in chunk
238-
&& chunk.isEntry
239-
&& !inputNames.includes(chunk.name)
240-
) {
241-
delete bundle[fileName];
242-
}
243-
}
244-
},
245-
}];
221+
outputOption.plugins = [filterUnnecessaryOutputs(inputNames)];
246222

247223
return build.write(outputOption);
248224
},
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import type { Plugin, OutputChunk } from 'rollup';
2+
3+
/**
4+
* pkgroll merges shared configs, which causes it to build extra entry points
5+
* that weren't actually requested. We need to filter those out here to:
6+
* - Avoid generating unnecessary output files
7+
* - Prevent unexpected files from overwriting the ones we actually want
8+
*/
9+
export const filterUnnecessaryOutputs = (
10+
inputNames: string[],
11+
): Plugin => ({
12+
name: 'filter-unnecessary-outputs',
13+
generateBundle: (_options, bundle) => {
14+
const allChunkFileNames = Object.keys(bundle).filter(
15+
fileName => bundle[fileName]!.type === 'chunk',
16+
);
17+
18+
const queue: string[] = [];
19+
for (const fileName of allChunkFileNames) {
20+
const chunk = bundle[fileName] as OutputChunk;
21+
if (
22+
chunk.isEntry
23+
&& inputNames.includes(chunk.name)
24+
) {
25+
queue.push(fileName);
26+
}
27+
}
28+
29+
const chunksToKeep = new Set<string>();
30+
while (queue.length > 0) {
31+
const fileName = queue.shift()!;
32+
const chunk = bundle[fileName];
33+
if (
34+
// Can be an externalized import
35+
!chunk
36+
|| chunksToKeep.has(fileName)
37+
) {
38+
continue;
39+
}
40+
41+
chunksToKeep.add(fileName);
42+
for (const imported of (chunk as OutputChunk).dynamicImports) {
43+
queue.push(imported);
44+
}
45+
}
46+
47+
for (const fileName of allChunkFileNames) {
48+
if (!chunksToKeep.has(fileName)) {
49+
delete bundle[fileName];
50+
}
51+
}
52+
},
53+
});

tests/specs/builds/output-dual.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,45 @@ export default testSuite(({ describe }, nodePath: string) => {
3131
'value.mjs',
3232
]);
3333
});
34+
35+
test('no unnecessary chunks', async () => {
36+
await using fixture = await createFixture({
37+
src: {
38+
'index-a.js': 'import("./chunk-a.js")',
39+
'chunk-a.js': 'console.log(1)',
40+
41+
'index-b.js': 'import("./chunk-b.js")',
42+
'chunk-b.js': 'console.log(1)',
43+
44+
'index-c.js': 'import("./chunk-b.js")',
45+
},
46+
'package.json': createPackageJson({
47+
exports: {
48+
'./a': './dist/index-a.cjs',
49+
'./b': './dist/index-b.mjs',
50+
'./c': './dist/index-c.cjs',
51+
},
52+
}),
53+
});
54+
55+
const pkgrollProcess = await pkgroll([], {
56+
cwd: fixture.path,
57+
nodePath,
58+
});
59+
expect(pkgrollProcess.exitCode).toBe(0);
60+
expect(pkgrollProcess.stderr).toBe('');
61+
62+
const files = await fs.readdir(fixture.getPath('dist'));
63+
files.sort();
64+
65+
expect(files).toStrictEqual([
66+
'chunk-a-BeOsALY6.cjs',
67+
'chunk-b-BeOsALY6.cjs',
68+
'chunk-b-BrZXlwf9.mjs',
69+
'index-a.cjs',
70+
'index-b.mjs',
71+
'index-c.cjs',
72+
]);
73+
});
3474
});
3575
});

0 commit comments

Comments
 (0)