feat: Added warning when modules is not false (#477)#485
feat: Added warning when modules is not false (#477)#485wardpeet wants to merge 3 commits intobabel:masterfrom
Conversation
When webpack is version 2 or higher and we're using es2015 or env preset We throw a warning saying that webpack can't treeshake correctly Closes babel#477
3d15909 to
cdb8bf2
Compare
|
it's not done yet. I have to add a check so it only fires the warning once and add some more tests to make sure it works 100%. Note that I only check modules on es2015 and env preset. |
src/index.js
Outdated
| const fs = require("fs"); | ||
|
|
||
| const presetsToCheckForModules = ["es2015", "env"]; | ||
| const modulesWarningMsg = `We've noticted the option modules isn't set to false, |
There was a problem hiding this comment.
Nit: noticted -> noticed
There was a problem hiding this comment.
thanks not sure this is the message we want to show though 😛 Just wrote something quick.
src/index.js
Outdated
| (opts && !opts.hasOwnProperty("modules")) || | ||
| (opts && opts.modules)) | ||
| ) { | ||
| this.emitWarning(new Error(modulesWarningMsg)); |
There was a problem hiding this comment.
this.emitWarning(`
⚠️ Babel Loader\n
We've noticed that module transpilation (`option.modules`) is enabled.
webpack supports ES2015 Modules natively and module transpilation disables tree shaking.
It is recommended to disable it (https://github.com/babel/path/to/explanation)
`)
There was a problem hiding this comment.
The message can of course be improved in terms of spelling, but the message convention should be like above :)
src/index.js
Outdated
| } | ||
|
|
||
| if ( | ||
| presetsToCheckForModules.indexOf(name) > -1 && |
There was a problem hiding this comment.
Just add the {Array} here :)
src/index.js
Outdated
| const pkg = require("../package.json"); | ||
| const fs = require("fs"); | ||
|
|
||
| const presetsToCheckForModules = ["es2015", "env"]; |
There was a problem hiding this comment.
Are these two really to only ones ?
There was a problem hiding this comment.
we also could add latest although I think it is deprecated.
There was a problem hiding this comment.
I don't know how many there are to be honest..
|
Notes from the meeting: Your goal is to allow the syntax to parse, but enable Webpack to do the transformation. We don't want to tie this to the preset string, instead we want to ensure that Babel knows that the babel syntax plugin is enabled and the transform plugin is not being run. That doesn't mean that we won't accept this in present state to alleviate the worst problems, just that we have a target for the future. The issue is that if you make your own preset it won't provide any warning to the user. This PR at present covers the 95% use case for minimal effort which is a significantly positive improvement. |
|
@nathanhammond perhaps there is a way to see if babel has ran the module transformation? |
src/index.js
Outdated
| this.emitWarning( | ||
| new Error( | ||
| `\n\n⚠️ Babel Loader\n | ||
| It looks like your Babel configuration specifies a module transformer. Please disable it. |
There was a problem hiding this comment.
Can we maybe give a little bit more information? Like "... . Please disable it, in order to allow webpack to create optimized bundles." Or "... . This disables tree shaking in webpack and will produce larger bundles. Please disable it."
| (opts && !opts.hasOwnProperty("modules")) || | ||
| (opts && opts.modules))) | ||
| ) { | ||
| emitCache.set(options.presets, true); |
There was a problem hiding this comment.
should this be name instead of options.presets? Otherwise can you explain why you are setting the array as key?
There was a problem hiding this comment.
The reason why I chose options.presets over name is that I cache a whole collection instead of just 1 preset.
Let me explain a bit more clearly. Lets say you have different load rules which use a different set of rules.
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015'],
plugins: [require('babel-plugin-transform-object-rest-spread')]
}
}
},
{
test: require.resolve('legacy-module'),
use: {
loader: 'babel-loader',
options: {
presets: ['es2015'],
}
}
}
Now I get 2 warnings because I've setup 2 load rules instead of just 1 as the presets are different
loganfsmyth
left a comment
There was a problem hiding this comment.
We were just talking about this issue again today and I figured I'd look over this PR. Not sure if you're even still interested in working on it since it's a bit stale now, but wanted to give my feedback. We can always take it from here too if you'd like.
| options.sourceFileName = relative(options.sourceRoot, options.filename); | ||
| } | ||
|
|
||
| if (this.version > 1 && options.presets) { |
There was a problem hiding this comment.
Can we do Array.isArray(options.presets), so if the user passes an invalid valid, it'll pass through to babel-core to validate?
There was a problem hiding this comment.
Also seems like we could check && !emitsCache.has(options.presets) here instead?
| const fs = require("fs"); | ||
|
|
||
| // we keep track of each preset config | ||
| const emitCache = new Map(); |
There was a problem hiding this comment.
Seems like this should be a Set rather than Map, and should ideally be a WeakSet?
| if (this.version > 1 && options.presets) { | ||
| options.presets.forEach(preset => { | ||
| let name = preset; | ||
| let opts = {}; |
There was a problem hiding this comment.
Seems easier to default to undefined since the object requires more steps to validate.
| ["es2015", "env", "latest"].indexOf(name) > -1 && | ||
| (!emitCache.has(options.presets) && | ||
| (!opts || | ||
| (opts && !opts.hasOwnProperty("modules")) || |
There was a problem hiding this comment.
I'd avoid opts.hasOwnProperty as an instance property. Also you never validate that opts is an object, so this would throw if someone passed an invalid config instead of passing through to babel-core's validation. I'd go with
const PRESET_WHITELIST = new Set(["es2015", "env", "latest"]);
// ...
const { modules } = typeof opts === "object" && opts || {};
if (PRESET_WHITELIST.has(name) && modules !== false) {
this.emitWarning // ...
}
|
closing in favor of #529 |

Please Read the CONTRIBUTING Guidelines
In particular the portion on Commit Message Formatting
Please check if the PR fulfills these requirements
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
What is the current behavior? (You can also link to an open issue here)
#477
What is the new behavior?
When webpack is version 2 or higher and we're using es2015 or env preset
We throw a warning saying that webpack can't treeshake correctly
Does this PR introduce a breaking change?
If this PR contains a breaking change, please describe the following...
Other information: