rollup / plugins

🍣 The one-stop shop for official Rollup plugins
MIT License
3.57k stars 568 forks source link

Terser plugin generates duplicate imports with `preserveModules` and `mangle` and `nameCache` #1660

Closed Basssiiie closed 6 months ago

Basssiiie commented 6 months ago
  1. This branch.
  2. Run npm install
  3. Run npm build to generate incorrect minified files.
  4. Optionally run npm run build:examples to see the examples unable to import the library because it contains duplicate imports in some files.
  5. Look in dist/esm/src/ to find the output files.

Expected Behavior

Expect no duplicate imports in each module.

Actual Behavior

Duplicate imports in certain files, for example in this file theres's two imports called x:

import { __extends as t } from '../../../node_modules/tslib/tslib.es6.mjs';
import { isStore as x } from '../../bindings/stores/isStore.mjs'; // Duplicate 'x' 1
import { read as S } from '../../bindings/stores/read.mjs';
import { isNumber as ft, isNullOrUndefined as ct, isObject as x } from '../../utilities/type.mjs'; // Duplicate 'x' 2
import { openEvent as vt, updateEvent as lt } from '../constants.mjs';
import { Control as T } from './control.mjs';

File: dist/esm/src/elements/controls/viewport.mjs

Which file it picks changes often when I try something different. Sometimes it's multiple files in the project.

When another project then tries to use this library, the build failes with:

[!] RollupError: Identifier "x" has already been declared
../../dist/esm/src/elements/controls/viewport.mjs (8:62)
 6: import { read as S } from '../../bindings/stores/read.mjs';
 7:
 8: import { isNumber as ft, isNullOrUndefined as ct, isObject as x } from '../../utilities/type.mjs';
                                                                  ^
 9:
10: import { openEvent as vt, updateEvent as lt } from '../constants.mjs';
    at Object.error (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\parseAst.js:279:30)
    at Module.error (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\rollup.js:14184:28)
    at Module.addImport (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\rollup.js:14734:22)
    at ImportDeclaration.initialise (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\rollup.js:11400:28)
    at new NodeBase (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\rollup.js:6069:14)
    at new ImportDeclaration (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\rollup.js:11393:1)
    at Program.parseNode (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\rollup.js:6180:27)
    at new NodeBase (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\rollup.js:6068:14)
    at new Program (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\rollup.js:12422:9)
    at Module.setSource (D:\Projects\Typescript\OpenRCT2-FlexUI\examples\AllWidgets\node_modules\rollup\dist\shared\rollup.js:14565:20)

Additional Information

I've spend hours looking into it, testing various scenarios and browsing this plugin's and Terser's source code, and I'm suspecting it has something to do with the default mangle.nth_identifier. In some specific scenarios it seems to generate a duplicate id which does not get discarded with a specific setup of imports. I've also been able to reproduce it by replacing the default identifier with my own very predictable identifier.

Furthermore:

I've also spent a few hours trying to create a smaller example set up, but unfortunately I wasn't successful in that, as this id generator is just too unpredictable for me to really understand it. So I'm sorry for the big example project.

I hope there's someone out there who knows a bit more about how this works internally.

Thank you for your time!