-
Notifications
You must be signed in to change notification settings - Fork 90
Description
Describe the bug
We have an in-house microfrontend framework, and we are in the process of adopting @module-federation/vite to deduplicate our shared libraries and reduce the network overhead and browser memory usage.
However, on our trial projects, we are encountering an odd issue: The process of using @module-federation/vite is causing our browser code to gain an eval() statement.
This is specifically called out by rollup in a warning:
node_modules/@module-federation/sdk/dist/index.cjs.js (670:83): Use of eval in "node_modules/@module-federation/sdk/dist/index.cjs.js" is strongly discouraged as it poses security risks and may cause issues with minification.
Even weirder, on further investigation, this eval() statement seems only relevant for NodeJS, and is never touched or invoked by our web project.
A few things stand out here:
Why is rollup consuming the CJS bundle?
@module-federation/sdk has the proper entries in its package.json to specify ESM builds, which are far more tree-shakable. But, vite seems to be consuming the cjs build instead...
Is it really being included in the bundle?
It's hard to tell with minify on, but yes:
{filename,importModuleDynamically:(_vm_constants_USE_MAIN_CONTEXT_DEFAULT_LOADER=(_vm_constants=vm.constants)==null?void 0:_vm_constants.USE_MAIN_CONTEXT_DEFAULT_LOADER)!=null?_vm_constants_USE_MAIN_CONTEXT_DEFAULT_LOADER:importNodeModule});script.runInThisContext()(scriptContext.exports,scriptContext.module,eval("require"),urlDirname,filename);const exportedInterface=scriptContext.module.exports||scriptContext.exports;if(attrs&&exportedInterface&&attrs.globalName){const o=exportedInterface[attrs.globalName]
With a bit of cross-eyed staring, this code is definitely the createScriptNode function that includes our rogue eval statement, and should in theory be totally unnecessary for a web project.
If we force rollup to consume the mjs bundle, does it tree-shake away the NodeJS code?
...No. We tried this using a resolve alias:
resolve: {
alias: {
"@module-federation/sdk": import.meta.resolve("@module-federation/sdk"),
},
},
Which properly resolves to the esm build, but we still get the same error, only pointing at the esm this time:
node_modules/@module-federation/sdk/dist/index.esm.mjs (668:83): Use of eval in "node_modules/@module-federation/sdk/dist/index.esm.mjs" is strongly discouraged as it poses security risks and may cause issues with minification
And we can still see it in the bundle:
{filename,importModuleDynamically:(_vm_constants_USE_MAIN_CONTEXT_DEFAULT_LOADER=(_vm_constants=vm.constants)==null?void 0:_vm_constants.USE_MAIN_CONTEXT_DEFAULT_LOADER)!=null?_vm_constants_USE_MAIN_CONTEXT_DEFAULT_LOADER:importNodeModule});script.runInThisContext()(scriptContext.exports,scriptContext.module,eval("require"),urlDirname,filename);const exportedInterface=scriptContext.module.exports||scriptContext.exports;if(attrs&&exportedInterface&&attrs.globalName){const s=exportedInte
Here's that reproduction: https://github.com/SunsetFi/vite-module-federation-createScriptNode/tree/with-esm
Will @module-federation/sdk tree-shake when used directly?
Yep!
https://github.com/SunsetFi/vite-module-federation-createScriptNode/tree/direct-usage-tree-shake
When we disable module federation and try importing createScript directly, createScriptNode is nowhere to be found in the source, and as such the eval function disappears from the bundled code.
Two things of note here though:
- We still get the error about using eval.
- Vite is properly using the ESM version of the sdk, not the cjs one.
Impact
This is affecting our usage in a few ways:
-
We are getting 'eval' code into our web builds, flagging warnings for our security scanners.
-
This will cause issues for deploying this code to production due to the Content Security Policy we use.
-
We are getting larger builds than we would like, as we are carrying around NodeJS specific code we do not need. Given that this is happening in the runtimeInit chunk that generates for every federated library, this is going to be compounded over the many, many, many microfrontends we are planning on using @module-federation/vite with.
Version
6.2.1
Reproduction
https://github.com/SunsetFi/vite-module-federation-createScriptNode
Relevant log output
node_modules/@module-federation/runtime-core/node_modules/@module-federation/sdk/dist/index.cjs.js (670:83): Use of eval in "node_modules/@module-federation/runtime-core/node_modules/@module-federation/sdk/dist/index.cjs.js" is strongly discouraged as it poses security risks and may cause issues with minification.Validations
- Read the docs.
- Read the common issues list.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- The provided reproduction is a minimal reproducible example of the bug.