ampproject / ampproject/rollup-plugin-closure-compiler
Support rollup output.preserveModules
- Dominant language
- TypeScript
- Stars
- 293
- Forks
- 28
- PR merge metrics
- No merged PRs in 30d
Description
**Please only file bugs/feature requests for rollup-plugin-closure-compiler here.**
Rollup provides an output option called preserveModules.
> Instead of creating as few chunks as possible, this mode will create separate chunks for all modules using the original module names as file names.
Generating one big fat esm chunk is less effective than multiple small modules because of latter can benefit from [sideEffects](https://github.com/webpack/webpack/issues/9337#issuecomment-507179765), while a single file can only rely on dead code elimination for unused export.
## Is your feature request related to a problem? Please describe.
However, when I add this flag when aggregating exports like this happens,
test/aggregating-export/fixtures/re-export.js
``` js
export * as dep from './foo-dep'
export * as dep1 from './bar-dep'
```
the below error occurs:
```
✖ aggregating-export › re-export › re-export works correctly with Promise returned by test never resolved
Unhandled rejection in test/aggregating-export/re-export.test.js
/workspaces/rollup-plugin-closure-compiler/node_modules/acorn/dist/acorn.js:2927
SyntaxError: Export 'fooDep' is not defined (1:7)
Parser.pp$4.raise (node_modules/acorn/dist/acorn.js:2927:15)
Parser.pp$1.parseTopLevel (node_modules/acorn/dist/acorn.js:763:16)
Parser.parse (node_modules/acorn/dist/acorn.js:555:17)
Function.parse (node_modules/acorn/dist/acorn.js:578:37)
Object.parse (node_modules/acorn/dist/acorn.js:5095:19)
Object.parse (src/acorn.ts:52:19)
ImportTransform.post (src/transformers/chunk/imports.ts:159:27)
Object.chunkLifecycle (src/transform.ts:92:50)
processTicksAndRejections (node:internal/process/task_queues:95:5)
Object.postCompilation (src/transformers/chunk/transforms.ts:100:10)
```
I add a [mini repo](https://github.com/icy0307/rollup-plugin-closure-compiler/tree/test/preserve-modules-with-aggregating-module) to reproduce this problem
test/aggregating-export/re-export.test.js
``` js
const rollup = require('rollup');
const fs = require('fs');
const test = require('ava');
const { default: compiler } = require('../../transpile-tests/index');
async function compile() {
const rollupConfig = {
input: 'test/aggregating-export/fixtures/re-export.js',
output: {
format: 'esm',
dir: 'lib',
preserveModules: true,
},
plugins: [compiler()],
};
const bundle = await rollup.rollup(rollupConfig);
const bundles = await bundle.generate(rollupConfig.output);
return bundles.output;
}
async function testReExport() {
const output = await compile();
const code = output.find((ele) => ele.fileName === 're-export.js').code;
const minified = await fs.promises.readFile('test/aggregating-export/fixtures/re-export.esm.default.js', 'utf8');
return { code, minified };
}
test('re-export works correctly with ', async (t) => {
await testReExport();
t.is(code, minified);
});
```
test/aggregating-export/fixtures/foo-dep.js
test/aggregating-export/fixtures/bar-dep.js
``` js
export const export1 = 1;
export function export2() {
return 2;
}
```
## Describe the solution you'd like
Turns out that the order of chunk transformers causes this issue.
```js
const TRANSFORMS: Array = [
HashbangRemoveTransform,
// Acorn can parse content starting here
ConstTransform,
IifeTransform,
CJSTransform,
LiteralComputedKeys,
StrictTransform,
ExportTransform,
ImportTransform,
ASITransform,
// Acorn cannot parse content starting here.
HashbangApplyTransform,
];
```
rollup transpiles the above code into:
``` js
import * as fooDep from './foo-dep.js';
export { fooDep as dep };
import * as barDep from './bar-dep.js';
export { barDep as dep1 };
```
In the posting closure compiler phrase,`ExportTransform` which adds the exports back first
generates something like
``` js
export{fooDep as dep,barDep as dep1}
````
which lacks the `form` keyword
## Describe alternatives you've considered
Change the transform order to add back import first.
But I can't find a way to do it elegantly.
## Additional context
The Rollup version must be close to 2.28.1, the higher version produces more problems due to the tests being quite fragile.
Simple string comparison highly relies on rollup's implementation for output.
However, the package.json file states that all versions above 1.27 are compatible.
``` json
"peerDependencies": {
"rollup": ">=1.27"
},
```
Contributor guide
Research direction
Start with test/aggregating-export/re-export.test.js and its fixtures, then inspect src/transformers/chunk/imports.ts, src/transform.ts, and the listed TRANSFORMS order. Reproduce the preserveModules build with Rollup near 2.28.1 and compare the generated re-export.js with the expected fixture; done means the aggregation test completes without the Acorn export error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, rollup, typescript
- Domain
- build-system, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100