Skip to content
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

feat: Added warning when modules is not false (#477) #485

Closed

Conversation

wardpeet
Copy link

Please Read the CONTRIBUTING Guidelines
In particular the portion on Commit Message Formatting

Please check if the PR fulfills these requirements

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe:

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?

  • Yes
  • No

If this PR contains a breaking change, please describe the following...

Other information:

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
@wardpeet wardpeet force-pushed the feature/add-warning-withmodules branch from 3d15909 to cdb8bf2 Compare June 27, 2017 22:16
@wardpeet
Copy link
Author

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
@@ -9,6 +9,10 @@ const resolveRc = require("./resolve-rc.js");
const pkg = require("../package.json");
const fs = require("fs");

const presetsToCheckForModules = ["es2015", "env"];
const modulesWarningMsg = `We've noticted the option modules isn't set to false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: noticted -> noticed

Copy link
Author

@wardpeet wardpeet Jun 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
`)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message can of course be improved in terms of spelling, but the message convention should be like above :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loaderwarning

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great thanks!

src/index.js Outdated
}

if (
presetsToCheckForModules.indexOf(name) > -1 &&
Copy link
Contributor

@michael-ciniawsky michael-ciniawsky Jun 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just add the {Array} here :)

src/index.js Outdated
@@ -9,6 +9,10 @@ const resolveRc = require("./resolve-rc.js");
const pkg = require("../package.json");
const fs = require("fs");

const presetsToCheckForModules = ["es2015", "env"];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these two really to only ones ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also could add latest although I think it is deprecated.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how many there are to be honest..

@nathanhammond
Copy link

nathanhammond commented Jun 28, 2017

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.

@wardpeet
Copy link
Author

@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.
Copy link
Member

@danez danez Jun 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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."

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you maybe forget to push? :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes sorry :)

(opts && !opts.hasOwnProperty("modules")) ||
(opts && opts.modules)))
) {
emitCache.set(options.presets, true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be name instead of options.presets? Otherwise can you explain why you are setting the array as key?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

@loganfsmyth loganfsmyth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@@ -149,6 +152,37 @@ module.exports = function(source, inputSourceMap) {
options.sourceFileName = relative(options.sourceRoot, options.filename);
}

if (this.version > 1 && options.presets) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do Array.isArray(options.presets), so if the user passes an invalid valid, it'll pass through to babel-core to validate?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also seems like we could check && !emitsCache.has(options.presets) here instead?

@@ -9,6 +9,9 @@ const resolveRc = require("./resolve-rc.js");
const pkg = require("../package.json");
const fs = require("fs");

// we keep track of each preset config
const emitCache = new Map();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 = {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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")) ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 // ...
}

@wardpeet
Copy link
Author

wardpeet commented Nov 6, 2017

closing in favor of #529

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants