webpack: beta23 doesn't start if config object includes loader configs because of schema

I’m submitting a bug report

Webpack version: 2.1.0-beta.23

Please tell us about your environment: Windows 10

Current behavior:

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
  - configuration has an unknown property 'htmlLoader'. These properties are valid:
    object { amd?, bail?, cache?, context?, devServer?, devtool?, entry, externals?, loader?, module?, name?, dependencies?, node?, output?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }

Expected/desired behavior: Schema should handle loader configurations, maybe?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 15
  • Comments: 55 (23 by maintainers)

Most upvoted comments

Thank you guys for messing up my build. Big thanks for making me waste hours trying to fix this without documentation of any sort on these changes.

Hm, I think some comments are going too far. It’s in beta for a reason, and using beta software means you are OK with the risks come with it.

@MoOx I hear you are a bit upset about this breaking change. Let me explain it.

The real problem was that loader query doesn’t accept any object but only JSON. But some loaders needed plugins. This resulted in a workaround for loader. They took options from webpack configuration. I didn’t really like it, because this means there are two ways of passing options to a loader. But as there was no other way it was fine for me.

beta.23 now adds support for any object as loader query. This means you can now pass your loader plugins via the options/query parameter to the loader. With most loaders this will work out of the box as they merged query object with options from configuration. But technically this could require a change in the loader. Because of this the “old” of passing options to the loader is still possible.

beta.23 also adds a schema validation to the configuration. For this we also disallow custom properties in the configuration. Elsewise you won’t get a hint for typos (i. e. modul instead of module, it would be a custom property). That’s because any extra property you want to push to the loader need to be provided with the LoadersOptionsPlugin. On long term they should move into the loader options/query object.

I try to document this change in the webpack 1 migration guide.

We not trying to break your stuff, just trying to make it more clear and easy. But this requires some breaking changes…

That’s a shame you introduced this breaking change with no easy way to handle it. Having to use a plugin offers a really poor DX as it require more boilerplate. Webpack beginner (and even people confortable with) will be really frustrated with this. The real problem is that query does not accept anything than json. And since we are in a js file, it’s really awkard and frustrating. That’s why a lot of loaders started to use this pattern (use an object in exports).

I think your best shot here is to accept real JS in loader query options. Currently if you pass JS (a function or a regex), you do not get any warnings. Your stuff magically disappear! (Unless you changed this behavior?)

We need to do something and saying to people to use a plugin in addition to the loader seriously sucks. Like a lot.

Is there any real reason query object only accept json? I guess it’s a legacy thing due to the string limitation, but I think it’s seriously time to reconsider this.

lots folks angry that beta software isn’t 100% stable…like what do folks expect. easy to get cut living on the edge

validation is awesome and I’m glad your making it strict. this directly addresses one of the most frustrating issues with using webpack. thanks for all the excellent work!

For people who came here looking for the solution of how to fix:

resolve: {
    modulesDirectories: ['node_modules', 'bower_components', 'web_modules']
  }

with the error of:

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.resolve has an unknown property 'modulesDirectories'. These properties are valid:
   object { alias?, aliasFields?, cachePredicate?, descriptionFiles?, enforceExtension?, enforceModuleExtension?, extensions?, fileSystem?, mainFields?, mainFiles?, moduleExtensions?, modules?, plugins?, resolver?, symlinks?, unsafeCache? }

Just change your webpack.config.js to:

    resolve: {
        modules: [
            'node_modules',
            'bower_components',
            'web_modules'
        ]
    }

Also, this page is very helpful:

https://github.com/webpack/webpack.js.org/blob/develop/content/how-to/upgrade-from-webpack-1.md#resolveroot-resolvefallback-resolvemodulesdirectories

@eshimischi This one works for me:

plugins: [
    new webpack.LoaderOptionsPlugin({
      // debug  : true,
      minimize : ENV === 'production',
      options: {
        context  : __dirname,
        babel    : {
          presets: ['es2015', 'stage-0'],
          plugins: ['transform-runtime'],
        },
        postcss: [
          precss,
          rucksack({
            fallbacks   : true,
            autoprefixer: { browsers: 'last 3 versions' },
          }),
        ],
      },
    }),
    ...
]

I have no problem understanding the risks involved with beta software. However, mind you we are talking about beta 24 which seems something really close to a release version. On such a change, as good as it may be (and it is good to have strict enforcement), it would be preferred to either accompany it with a description of what changed and what to do to make it right again (and there was no readme about these, I see now that there is) or show a deprecated notice instead of abruptly removing the legacy way. I for one do take note of all deprecation notices and in reasonable time I mend the code to abide to the new directions.

For me, in the timespan of a day or so, in between the time I updated my local modules and made the deployment to a staging server, this update appeared, and while locally all was green I was left with surprising errors on the staging side, since the build there always runs the install. You may say it was bad timing, but…

I’d just like to point out to everyone that this is a beta version of the software and as a beta version it is still in heavy development, as such breaking changes should be expected. If this is going to cause problems for you in your development life cycle then you really should be using the previous stable version or if you absolutely have to have the latest then lock down your version to a previously known working implementation when issues like this arise.

@AlexandruCiobanu sorry for the time wasted. For what it’s worth we published these in our release notes github.com/webpack/webpack/releases

If you have a constructive idea or suggestion for ways we can communicate this better, we are happy to take that into consideration.

If you have a constructive idea or suggestion for ways we can communicate this better, we are happy to take that into consideration.

Simplest way to be clear would be to call it 3.0 instead of 2.1 - see http://semver.org

Here’s a link to those release notes in the event anyone still hasn’t read them . Also here’s a link to some early documentation on migrating from 1.x.x.. I also found this what’s new in Webpack 2.1 documentation helpful.

If you don’t want to break anything when deploying to live environments AND you want to use the beta, just remove the ^ from the webpack version in your package.json and be a bit more intentional about tracking with the release notes - especially when there’s a breaking change. Shrinkwrap is a good resource to help with this!

As for helpful/constructive feedback on the awesomeness that is happening in 2.1, the only thing i’m a little stuck on is using postcss-loader with css-modules. I think they are tracking it and have a potential solution - https://github.com/postcss/postcss-loader/issues/99 - so any feedback you could provide there for the best way to approach this would be much appreciated.

Thank you @sokra and @TheLarkInn !!!

@MoOx It looks like the css-loader relies on the context option of the configuration. When using the LoaderOptionPlugin you are overriding the options passed to the loader. This means you need something like this when not passing context directly to the loader:

new webpack.LoaderOptionsPlugin({
  options: {
    context: __dirname,
    // ...
  }
})

or

module.rules: [
  {
    test: /\.css$/,
    loader: "css-loader",
    options: {
      context: __dirname
    }
  }
]

@Akkuma you need to see this change in the context of webpack 1 to webpack 2 migration. Here a proper validation is more valuable as you need the modify the configuration anyway. It doesn’t prevent you from running webpack, it just requires a 4 line change. The validation tells you what’s wrong.

For the webpack 2 release you’ll have a complete upgrade guide where this is all explained in detail. Until then using webpack 2 beta is a bit bleeding edge. If using you should stay up-to-date with the webpack development.

And… give us a day or two to sort out all the stuff regarding breaking changes. They (hopefully) will eventually have positive implications for webpack 2.

Simplest way to be clear would be to call it 3.0 instead of 2.1 - see http://semver.org

Was 2.0 ever released?

@MoOx the css-loader does not even use options in configuration. So it should not be affected of these change. You should not even need to change the configuration for the css-loader. Could you add your configuration?

@hustcer https://github.com/webpack/webpack.js.org/blob/develop/content/how-to/upgrade-from-webpack-1.md#resolveroot-resolvefallback-resolvemodulesdirectories

@mofodojodino Thanks ❤️

@Akkuma we decided in the end that it was a justifiable tradeoff. I will publish a short migration guide if this will assist you also.

I understand why it was how it was.

beta.23 now adds support for any object as loader query.

Ok this makes me un-upset. I am not used to see release notes for webpack releases so I missed that.

On long term they should move into the loader options/query object.

Totally agree.

Thanks for you explanations.

Is there an option to disable validation?

@princemaple Yes, we just dropped this today, and I’ve been working furiously on a blogpost, and guide.

Easiest migration steps for custom loader properties in config.

plugins: [
  new webpack.LoaderOptionsPlugin({
    options: {
      htmlLoader: {
       whateverProp: true
      }
    }
  })
]

Having an empty extensions string ( extension: ['', ...] ) apears to no longer be necessary in webpack2. I am unsure why this isn’t documented in the migration documentation.

If you remove the empty string value in your extensions array, that error should go away.

@TheLarkInn @sokra

Would you consider leaving context alone even if you specify options through LoaderOptionsPlugin?. Context is kinda important (used for [hash] in css-modules) and it it’s unfortunate that it get’s dropped just because you specify extra options throughLoaderOptionsPlugin