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

beta23 doesn't start if config object includes loader configs because of schema #3018

Closed
princemaple opened this issue Sep 20, 2016 · 55 comments

Comments

@princemaple
Copy link

princemaple commented Sep 20, 2016

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?

@princemaple
Copy link
Author

Well, can be worked around by moving the options into the loader object... Not sure if this should be closed, leaving it to maintainers.

@TheLarkInn
Copy link
Member

@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
      }
    }
  })
]

@TheLarkInn
Copy link
Member

Well, can be worked around by moving the options into the loader object... Not sure if this should be closed, leaving it to maintainers.

That is also a solution as well.

@TheLarkInn
Copy link
Member

See #2974 (comment)

@princemaple
Copy link
Author

Thanks! I think this is a good move!

On Tue, 20 Sep 2016, 12:47 Sean Larkin notifications@github.com wrote:

@princemaple https://github.com/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
}
}
})
]


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#3018 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABRKNBrb-nJ3tXfGwOd3ppnOOLrCnjJnks5qr0lcgaJpZM4KBF2J
.

@le0nik
Copy link

le0nik commented Sep 20, 2016

Is there an option to disable validation?

@MoOx
Copy link
Contributor

MoOx commented Sep 20, 2016

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.

@Jessidhia
Copy link
Member

There is an options object that takes a raw JS object (though it is possible that further validation forbids non-serializable code), but it seems no loaders besides css-loader correctly support it (a53799c#commitcomment-19089585).

@sokra
Copy link
Member

sokra commented Sep 20, 2016

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

@MoOx
Copy link
Contributor

MoOx commented Sep 20, 2016

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.

@Akkuma
Copy link
Contributor

Akkuma commented Sep 20, 2016

@sokra I understand what you're trying to do, but preventing people from running webpack at all because of their existence is silly. Looking at the original PR it looks like people were in agreement that this should be a warning at best until there is proper time for people to update their configs. In my own opinion, forcing people to correct schema changes when the webpack build successfully ran before without issues is the opposite of a good user experience.

@TheLarkInn
Copy link
Member

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

@sokra
Copy link
Member

sokra commented Sep 20, 2016

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

@Akkuma
Copy link
Contributor

Akkuma commented Sep 20, 2016

My webpack broke from inconsequential properties existing on it. Literally, removing them didn't impact my build before or after the update to beta23, so I don't see how breaking something that had no impact on my build is a positive or justifiable tradeoff. I would have greatly appreciated being told I had useless properties sitting in my config as warnings. I did not appreciate it when it killed my build.

@kevinSuttle
Copy link

kevinSuttle commented Sep 20, 2016

I'm seeing this same thing. Breaks postcss.

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration has an unknown property 'postcss'. These properties are valid:

Even though webpack-validator says it's fine.

@TheLarkInn
Copy link
Member

@kevinSuttle please refer to #3018 (comment)

@developerdino
Copy link

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.

@MoOx
Copy link
Contributor

MoOx commented Sep 20, 2016

@TheLarkInn the solution based on LoaderOptionsPlugin is breaking stuff for css-loader (eg: [path] is missing in localIdentName and [hash] is a global one, so some CSS supposed to be "modules" become global with the same name, so 💥). Unusable in my case.

@hustcer
Copy link

hustcer commented Sep 20, 2016

How about:

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? }

@sokra
Copy link
Member

sokra commented Sep 20, 2016

@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

@princemaple
Copy link
Author

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?

@eshimischi
Copy link

eshimischi commented Sep 22, 2016

.. changed everything as @hustcer said and now i have troubles with resolve-url-loader (1.6.0)
my webpack.config.js:

const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';
const scssLoader = [
  `css-loader?${sourceMapQueryStr}?modules&importLoaders=2`,
  'postcss-loader',
  `resolve-url-loader?${sourceMapQueryStr}`,
  `sass-loader?${sourceMapQueryStr}`
];
module: {
    loaders: [
    {
        test: /\.css$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style',
          loader: [
            `css?${sourceMapQueryStr}`,
            'postcss'  
          ]
        })
      },{
        test: /\.scss$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({fallbackLoader: 'style', loader: scssLoader.join('!')})  
   },
  resolve: {
    modules: [
      config.paths.assets,
      'node_modules',
      'assets/bower'
    ],
    enforceExtension: false
  },
plugins: [
new webpack.LoaderOptionsPlugin({
      minimize: config.enabled.minify,
      debug: config.enabled.watcher,     
      stats: { colors: true },
      quiet: true,
      options: {
        context: __dirname,
        postcss: [
          postcssCssnext({
            sourcemap: true,
            browsers: [
              'last 2 versions',
              'android 4',
              'opera 12',
            ]
          }),
          postcssBrowserReporter(),
          postcssReporter({
            clearMessages: true
          })
        ]
      }
    })
]

hm, what else i need to change?? cause i got:

ERROR in ../~/css-loader?-sourceMap?modules&importLoaders=2!../~/postcss-loader!../~/resolve-url-loader?-sourceMap!../~/sass-loader?-sourceMap!./styles/main.scss
    Module build failed: TypeError: Cannot read property 'path' of undefined
        at Object.resolveUrlLoader (/Volumes/Stuff/www/project/wordpress/*****/site/web/app/themes/****-v1/node_modules/resolve-url-loader/index.js:38:55)

@sivabudh
Copy link

sivabudh commented Sep 22, 2016

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

@joshhunt
Copy link

@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

@eshimischi
Copy link

A little hack to solve my issue with resolve-url-loader is #issuecomment-249522569 here

@farwayer
Copy link

farwayer commented Oct 11, 2016

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.

@sokra but what is correct way to access this options object from plugin? query is still string so useless in many cases. Plugin has access to webpack common config with options property but it's hard to find concrete plugin options in config tree. And LoaderOptionsPlugin overriding this options property with removing all previous values.
So how can plugin get his config options as unchanged object?

@sokra
Copy link
Member

sokra commented Oct 12, 2016

this.query is an object when an object is passed. loader-utils parseQuery normalizes this.

@farwayer
Copy link

@sokra Just tested on master. parseQuery() parses query string. All ok before you trying to pass object which contains functions. It's real life case for using loader plugins. For example postcss-cssnext constructor returns object with functions so if you try to pass this plugin to postcss-loader inside options object then build will fail.

import cssNext from 'postcss-cssnext'

...
options: {
  plugins: [cssNext()]
}

LoaderOptionsPlugin can be used as workaround of course. But as I know it is not recommended.

Maybe it will be better to provide access to "honest" javascript object? webpack can merge string options to object options before passing it to plugin so plugin will no need to call parseQuery() more. And this is another positive thing.

@farwayer
Copy link

Hm sorry look like problem was in concrete use case. I found very strange bug. If style-loader included in use chain than query will become string.

@iyn
Copy link

iyn commented Oct 13, 2016

@hustcer your solution saved me a lot of work and stress (and I already spend a few of), thank you so much!

@sokra
Copy link
Member

sokra commented Oct 14, 2016

@farwayer yep that's a bug. Could you open a separate issue?

@TheLarkInn
Copy link
Member

@sokra is this issue in loader-utils or in core itself? I could try and take a stab at fixing this.

@farwayer
Copy link

@TheLarkInn bug is in core #3136

@anil1712
Copy link

Hi,
I am still getting these errors in v2.2.0-rc.1

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

Please provide me some solution for the same
Thanks

@sokra
Copy link
Member

sokra commented Dec 23, 2016

@sokra sokra closed this as completed Dec 23, 2016
@diegodesouza
Copy link

Still getting the following error:

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
  - configuration.resolve.extensions[0] should not be empty.

under version 2.2.0

.../node_modules/webpack/lib/webpack.js:19
		throw new WebpackOptionsValidationError(webpackOptionsValidationErrors);
		^

Error
    at webpack 
...node_modules/webpack/lib/webpack.js:19:9)
    at Object.<anonymous> 
...node_modules/webpack-dev-server/bin/webpack-dev-server.js:198:12)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:420:7)
    at startup (bootstrap_node.js:139:9)
    at bootstrap_node.js:535:3

@narthollis
Copy link

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.

@diegodesouza
Copy link

Thanks @narthollis that helped with that specific error i was having.

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

No branches or pull requests