vue-cli: transpileDependencies make commonjs modules conflict with webpack module model
Version
3.0.0-rc.1
Reproduction link
https://gitlab.com/MiausF2E/f2e-todos-cli-demo
Steps to reproduce
- comment out
process.env.VUE_CLI_BABEL_TRANSPILE_MODULES = trueinbabel.config.js yarn serveand take a look in browser console
What is expected?
no error.
What is actually happening?
es6 import conflict with commonjs declaration
I had discussed in #1248, but it seems no response if I don’t file an issue.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 3
- Comments: 17 (7 by maintainers)
Commits related to this issue
- fix error for 'exports is readonly' (https://github.com/vuejs/vue-cli/issues/1568) — committed to twhtanghk/orgchart by twhtanghk 6 years ago
I came across something similar in a topic on forum.vuejs.org and took another look. I think I found the underlying issue with the help of this issue in the webpack repo:
https://github.com/webpack/webpack/issues/4039
The problem
node_modulesin vue-cli’stranspileDependenciesoption because it contains code we have to transpileimportstatement into that module for the polyfillstrictmodestrictmode,exportsis readonly.So we end up with the error:
Possible Workarounds
useBuiltIns: 'entry'One workaround is to switch from
useBuiltIns: 'usage'(the default for@vue/babel-preset-app) touseBuiltIns: 'entry'…and add the
import '@babel/polyfill'that this setting requires to the top ofmain.js. The obvious downside is that we probably end up with unnecessary polyfills in our bundle, increasing its size Plus, this workaround doesn’t prevent all edge cases: If the module in question contains code that will make babel insert a helper fromtransform-runtime(i.e. helpers forclasssyntax), those will also be injectedimportstatements, again switching the module intostrictmodemodules: 'commonjs'By default, our babel preset doesn’t transpile ES6 modules to commonjs, because webpack >=2 understands those and they enable webpack to do tree shaking.
But if we tell babel to transpile all modules to commonjs, we never enter strict mode, so that should also prevent this error.
Can we really fix this?
I don’t think there’s much we can do except maybe document this edge case including possible workarounds, and offer a warning that under some rare circumstances, even that won’t work.
Other ideas?
Yeah, a warning block under
transpileDependenciesand in the polyfills section would help. Essentially,transpileDependencieswould only work for deps with ES module formats.Also note that:
transpileDependenciesis primarily designed for dependencies that ship plain ES2015 code.babel.config.js@yyx990803 @LinusBorg in my project, it’s useful. more
using
transpileDependenciesoption, it’s very likely to transpile module which has already been transpiled. e.g.need_transpile_module/node_modulewhich has already been transpiled will be processed by babel-loader in vue cli, because RegExp is used to decide if module need to transipleI tried to write complex regexp to solve it. recently I found
sourceType: 'unambiguous'in babel option can solve this problemAre these related to this issue? @LinusBorg I think it is necessary to remind people who use
transpileDependenciesoption.Ok, ran the production and can verify the behaviour. Not sure why that happens / how to handle it right now.
Sidenote: there are actually two things to consider:
1. When not transpiling to commonjs, you can’t use
importon a commonjs module.so this statement;
has to be changed to
That allows it to compile correctly, but is not the heart of the issue
2. When requiring this module and transpiling, we get this error in the browser:
There is an open issue from early 2017 in the webpack repo about this error here, but it’s not clear to me what the status on this is and if it’s really / still a bug, an incompatibility or something resolvable in userland.