New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
variable is used before declaration #4187
Comments
I've got the same issue when bundling glob, on Windows 10 19043.1110, Node v14.17.3. Bundling fails on rollup 2.52.8 through 2.53.3, 2.52.7 works. |
This issue is likely related to Rollup now respecting ECMAScript rules governing Temporal Dead Zone (TDZ) for const/let variables. Before rollup would incorrectly process code like the following and mask user created and library errors:
expected ECMAScript runtime behavior:
rollup v2.52.7 incorrect output:
rollup v2.53.3 correct output:
|
A simple way to determine whether your code or some imported library has a TDZ error is to run the old (or new) version of rollup with Edit: NOTE: |
@kzc You are right. there is a TDZ error. |
In this case, globSync is a function, and aren't functions hoisted in ECMAScript? |
I wonder if it is an artifact of the commonjs conversion and the issue is not present in the original sources. Maybe we need a flag to disable TDZ detection after all until we can fix the CommonJS plugin, which is definitely harder. |
The function may be hoisted, but the property access in var Glob = require('./glob.js').Glob is not hoisted. The commonjs plugin replaces the require call with a variable that is undefined when used due to the imperfectly resolved circular dependency. It probably works in the original sources because here, the require calls are basically run like function calls. Until now, Rollup does not support circular CommonJS dependencies properly, unfortunately. |
I don't think adding a flag to disable TDZ detection to have non-standard ES behavior could help considering that the problem also occurs when tree shaking is disabled altogether:
But I'm still missing what's the actual problem. If we can create the smallest possible program demonstrating the issue we can compare it to an unbundled set of source files running directly in NodeJS and see whether it works there. |
The problem is very likely that the commonjs plugin does not wrap commonjs modules into function calls, maintaining a registry to resolve require calls. Instead, it tries to rewrite them to ESM directly. This works surprisingly well except when there are circular require calls in the code. In that case, the "correct" logic would be to
It is the "half-finished exports object" that is usually missing and breaking things. |
@szdailei Just out of curiosity could you please try running both rollup 2.52.7 and rollup 2.52.8 with |
Confirmed that the workaround suggested above works... Given:
Expected:
Reproduction of issue:
Workaround:
The diff between the two rollup output bundles above: --- failing.mjs
+++ working.mjs
@@ -76,4 +76,2 @@
-pathModule.normalize;
-
// Regexp that finds the next partion of a (partial) path
@@ -1882,3 +1880,2 @@
var minimatch$1 = minimatch_1;
-glob_1.Glob;
var path$1 = require$$0; Ironically, the problematic line and local variable
and probably can be safely removed from the upstream package. |
Here's a minimal repro of a bug where the previous workaround does not work...
Expected output with node v14 and v16:
Actual:
The old version of rollup cited above also doesn't work in this case:
fwiw, esbuild can handle require cycles:
|
To your point - but it also occurs without require cycles:
Expected:
Actual:
It's interesting that the rollup commonjs require ordering hasn't been noticed before. It must not be an issue with many projects. |
@kzc I have added --treeshake --no-treeshake.unknownGlobalSideEffects --no-treeshake.propertyReadSideEffects and upgrade to rollup 2.54.0, it works. |
It's not a general solution for require cycles, but it does work for bundling
It's possible that
|
@kzc You are right again. Only --no-treeshake.propertyReadSideEffects is required. --treeshake and --no-treeshake.unknownGlobalSideEffects are not necessary. |
We are finalizing a new version of the commonjs plugin in rollup/plugins#1038. It is pre-published as |
Rollup Version
2.52.8
Operating System (or Browser)
Linux
Node Version (if applicable)
v14.16.0
Link To Reproduction
https://github.com/szdailei/www/tree/main/packages/api-server
Expected Behaviour
Rollup 2.52.7 bundle glob 7.1.6 sync.js.
Bundled code is:
var sync = globSync$1;
globSync$1.GlobSync = GlobSync$1;
var fs$5 = fs__default;
var rp$1 = fs_realpath;
var minimatch$1 = minimatch_1;
var path$5 = path__default;
var assert$2 = require$$6;
var isAbsolute$1 = pathIsAbsolute.exports;
var common$1 = common$2;
common$1.alphasort;
common$1.alphasorti;
Actual Behaviour
Rollup 2.52.8 bundle glob 7.1.6 sync.js. glob_1 is used before declaration.
Bundled code is:
var sync = globSync$1;
globSync$1.GlobSync = GlobSync$1;
var fs$5 = fs__default;
var rp$1 = fs_realpath;
var minimatch$1 = minimatch_1;
glob_1.Glob;
var path$5 = path__default;
var assert$2 = require$$6;
var isAbsolute$1 = pathIsAbsolute.exports;
var common$1 = common$2;
common$1.alphasort;
common$1.alphasorti;
The text was updated successfully, but these errors were encountered: