[Bug]: Cannot access '[class x]' before initialization. when rspack handles class dependencies, the scope elevation does not take effect for the class.
System Info
System: OS: macOS 14.4 CPU: (32) x64 13th Gen Intel(R) Core(TM) i9-13900KF Memory: 12.73 GB / 32.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 21.6.1 - /usr/local/bin/node npm: 10.2.4 - /usr/local/bin/npm pnpm: 9.4.0 - /usr/local/bin/pnpm Watchman: 2024.06.10.00 - /usr/local/bin/watchman
Details
rspack build output used in app error:
location for error code:
class dependencie [LexicalNode] defind in the last bottom:
rollup build output [LexicalNode] in the top(before used):
I tried all possible configurations of swc and rspack, and finally concluded that this issue might be due to the omission of some scenarios of class scope hoisting.
It could also be a circular dependency causing the scope to be hoisted incorrectly.
Reproduce link
https://github.com/openages/lexical
Reproduce Steps
pnpm run rspack for rspack build output.
pnpm run build for rollup build output.
use "lexical":"workspace:*" in the monorepo/packages/app.
https://lexical.dev/docs/getting-started/quick-start
By the way, this also may cause by pure esm(rspack handle pure esm is experimental).
Reproduce when use rollup(export LexicalNode instead of export type LexicalNode):
So question is, why rspack treat export type LexicalNode as a actually export, the rollup handle this case is right.
Tested export order, that may cause output same error, fixed by export * from ''.
But rspack still scope to be hoisted incorrectly.
@ahabhgk "same as webpack" It means that webpack is the same, so will it not be fixed?
No, it means we will fix it for both rspack and webpack
This is caused by circular imports and the case is very complex, so we may need more time to find the root issue and then fix it
Is there any progress?
any news?
I might take another look at this in a few days if my time available, currently the case is too complex, which is very hard to debug and find the root cause, if someone can provide a simpler one would be very helpful
Is it still in progress?
This issue has been automatically marked as stale because it has not had recent activity. If this issue is still affecting you, please leave any comment (for example, "bump"). We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
Is it still in progress?
question +1
This is caused by the inconsistency between the module order and the original order due to side effects optimization. This package is marked with "sideEffects: false" in the package.json, which indicates that all the re-exports in this package can be optimized away by side effects (a -> b (re-exports) -> c is optimized to a -> c). Note that side effects optimization does not guarantee that these optimized dependencies will maintain the original order.
a -> b (re-exports) -> c
-> d
is optimized to
a -> d
-> c
This is actually reasonable because if a module has no side effects, then its order doesn't matter.
Looking at the code of this package again, it makes extensive use of circular references, re-exports, and classes, which leads to the change of the original order among modules after the re-exports are optimized. As a result, the error message "Cannot access '[class x]' before initialization", that is, the TDZ (Temporal Dead Zone) error, appears. The TDZ error can also be regarded as a kind of side effect. However, due to the "sideEffects: false" flag in the package.json, rspack/webpack ignores the side effects of TDZ during the bundling. So currently, it is required that this package change the "sideEffects" in its package.json.
But this is definitely not the best approach. There are some side effects that are relatively easy to identify, but there are also many that are very difficult to identify. In fact, it is extremely difficult to correctly identify side effects.
Currently, there is a potentially better solution, side effects optimization can maintain the order of the optimized dependencies and keep the order unchanged (https://github.com/vercel/next.js/issues/72846#issuecomment-2487489855). This can solve this problem well and also have better fault tolerance for incorrect sideEffects markings (so that unexpected error messages and runtime errors won't occur). However, we still need some time to follow up and research this solution.
(The above only applies to side effects optimization in bundlers such as rspack, and webpack, etc. As for rollup and esbuild, I'm not sure whether they have fully implemented the side effects optimization or whether they really need this optimization. They often perform scope hoisting on all ES modules into one module, and the way they bundle is quite different from rspack/webpack, so the implementations of side effects also vary from one to another.)
This issue has been automatically marked as stale because it has not had recent activity. If this issue is still affecting you, please leave any comment (for example, "bump"). We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!