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

Incompatible with Webpack 2.1.0-beta.23 configuration validation #99

Closed
kylecesmat opened this Issue Sep 19, 2016 · 42 comments

Comments

Projects
None yet
@kylecesmat
Copy link

kylecesmat commented Sep 19, 2016

The latest webpack beta now validates the configuration object, which breaks this usage as the postcss key in the configuration is not part of the validated schema. See release notes here: https://github.com/webpack/webpack/releases/tag/v2.1.0-beta.23

module.exports = {
    module: {
        loaders: []
    },
    postcss: function () {}
}

The entire output is:

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

I understand this is for a webpack 2 beta, and probably should wait until the features stabilize. Who knows if this configuration validation will land in the final version...

For now I've locked webpack@2.1.0-beta.21

@ai ai added the enhancement label Sep 20, 2016

@ai

This comment has been minimized.

Copy link
Member

ai commented Sep 20, 2016

I will start this feature after we will stabilize config #97

@donaldpipowitch

This comment has been minimized.

Copy link

donaldpipowitch commented Sep 20, 2016

Would this work as an ad-hoc fix? webpack/webpack#2974 (comment)

@phaistonian

This comment has been minimized.

Copy link

phaistonian commented Sep 20, 2016

@donaldpipowitch I am also curious. Would using this approach enable us use postCSS on the latest beta?

@wellyshen

This comment has been minimized.

Copy link

wellyshen commented Sep 20, 2016

Same issue +1

@SpaceK33z

This comment has been minimized.

Copy link

SpaceK33z commented Sep 20, 2016

See webpack/webpack#3018 (comment) for a temporary workaround, which should work without a fix in postcss-loader. Note that this is meant to be temporary, because it is now possible to configure the options in the query object (but it looks like you already know this).

@kevinSuttle

This comment has been minimized.

Copy link

kevinSuttle commented Sep 20, 2016

So, are the Webpack options for postcss or the postcss-plugins? e.g.
What would the new syntax look like compared to the current?

postcss()
  .use(smartImport({
    path: ["src/css"],
    transform: require("css-whitespace")
  }))
  .process(cssString)
  .then(function (result) {
    var css = result.css
  })
@MoOx

This comment has been minimized.

Copy link
Contributor

MoOx commented Sep 20, 2016

We must implement this asap. I can handle it, this change is required for me to cut a release for phenomic which require webpack 2.
I will try to push a PR quickly. It should be easy to support webpack 1 & 2 at the same time since query can know accept normal JS (so function).

@MoOx

This comment has been minimized.

Copy link
Contributor

MoOx commented Sep 20, 2016

Well according to #97 I am going to wait. @ai I think with webpack 2 something could be done to support both version of webpack. I wrote several webpack loaders so poke me if you need a hand ;)

@MoOx

This comment has been minimized.

Copy link
Contributor

MoOx commented Sep 20, 2016

Problem is, the workaround mentionned earlier is not working if you use css modules. @ai poke me when you are ready to more forward, this is a small "big deal" we have to handle here :D

@ai

This comment has been minimized.

Copy link
Member

ai commented Sep 21, 2016

@MoOx do we have any webpack 2 loader API changelog?

What changes do you suggest?

@MoOx

This comment has been minimized.

Copy link
Contributor

MoOx commented Sep 21, 2016

Changelog is: you can't rely on "random" properties in webpack global config.
So what you use to call via this.options.postcss have to be replaced.
The good news is: your params (the "query" associated with the loader) now accept real JS, not just json (like it used to). So we "simply" need to normalize options passed to the loader by only using the "query". This will basically deprecate the "pack" option since it won't be necessary anymore.

tl;dr: no more this.options.postcss and everything should be in params.

For backward compat we can refactor the code and simply read options like this

const options = {
   ...{ some default ? },
   ...this.options.postcss,  // backward compat with v1
   ...loaderUtils.parseQuery(this.query)
}

It's what I am doing for eslint-loader and it's working like a charm https://github.com/MoOx/eslint-loader/blob/f965eecfd5dac6489abeaebeb8fc7e5fa010bade/index.js#L128-L136

@artkravchenko

This comment has been minimized.

Copy link

artkravchenko commented Sep 22, 2016

Validation succeeds for me:

plugins: [
  new webpack.LoaderOptionsPlugin({
    options: {
      context: __dirname,
      postcss: [
        autoprefixer
      ]
    }
  }
]

Where autoprefixer is

const autoprefixer = require('autoprefixer');

See more at webpack/webpack#3018 (comment)

@kevinSuttle

This comment has been minimized.

Copy link

kevinSuttle commented Sep 22, 2016

@Oopscurity Can you not use import ?

@MoOx

This comment has been minimized.

Copy link
Contributor

MoOx commented Sep 26, 2016

You can use it, by passing the function as you used too.

@kevinSuttle

This comment has been minimized.

Copy link

kevinSuttle commented Sep 26, 2016

So it beta 25 the stable one now?

@dkrutsko

This comment has been minimized.

Copy link

dkrutsko commented Sep 27, 2016

@Oopscurity: I was having an issue with extract-loader as well because it couldn't find the output.publicPath definition. So in addition to context, you also need to provide any additional options for the loaders you are using. I'm guessing webpack.LoaderOptionsPlugin creates a localized webpack configuration environment.

@kevinSuttle

This comment has been minimized.

Copy link

kevinSuttle commented Sep 28, 2016

Following up on: #99 (comment)

Before, there was this method:

// dependencies
var fs = require("fs")
var postcss = require("postcss")
var customProperties = require("postcss-custom-properties")

// css to be processed
var css = fs.readFileSync("input.css", "utf8")

// process css using postcss-custom-properties
var output = postcss()
  .use(customProperties())
  .process(css)
  .css

but now the API has changed.

webpack config

new webpack.LoaderOptionsPlugin({
        options: {
          postcss: function (webpack) {
            return [
            importCSS({
              addDependencyTo: webpack
            }),
              customProperties({
                   preserve: true,
                   appendVariables: true,
              }),
              cssApply,
              autoprefixer,
            ]
          }
        }
      }),

Directory structure

  • webpack.config.js
  • /src/Buttons/Button.jsx
    • (contains a require(./Buttons.css),
    • which relies on the custom properties defined in ./src/Styles/Index.css
    • which are imported from ./node_modules/ (

Yet I still get warnings the custom properties as used without fallbacks, unless I @import ./Styles/Index.css into every single component's css file (e.g. Buttons.css).

That solves one problem, but then introduces another:
Now every single component has the imports inlined, bloating up the CSS.

I've noticed that there are multiple style tags too, but I'm not sure why that's happening.
I suppose it's because I'm not using Extract-Text.

With this new API, I'm not sure which file should be imported where and when, etc.
I have a repo I can send privately if it helps.

@MoOx

This comment has been minimized.

Copy link
Contributor

MoOx commented Sep 28, 2016

@kevinSuttle This have NOTHING to do with how postcss-loader works, or webpack 2 update. This is why you have a way to define variables directly from your customProperties config. See readme of postcss-custom-properties.

MoOx referenced this issue in iamdustan/webpack-2-extract-css-modules-repro Oct 4, 2016

@ai

This comment has been minimized.

Copy link
Member

ai commented Oct 7, 2016

Fix by #104

Now we have plugins option to query.

@ai ai closed this Oct 7, 2016

@ai

This comment has been minimized.

Copy link
Member

ai commented Oct 8, 2016

I finished all changes and ready for release. Could somebody test this plugin on real application? (Just replace version in package.json to postcss/postcss-loader)

@kevinSuttle

This comment has been minimized.

Copy link

kevinSuttle commented Oct 8, 2016

I can, but I don't see a newer version than 0.13.0 (the one I have now)?

@SpaceK33z

This comment has been minimized.

Copy link

SpaceK33z commented Oct 8, 2016

@kevinSuttle, as @ai said, you need replace postcss-loader temporarily in package.json with this:

"postcss-loader": "postcss/postcss-loader"

@ai ai referenced this issue Oct 9, 2016

Closed

Doesn't compiles css #106

@ai ai reopened this Oct 9, 2016

@kevinSuttle

This comment has been minimized.

Copy link

kevinSuttle commented Oct 10, 2016

Er, I thought it worked with "postcss":"postcss/postcss-loader", but now I'm getting this:

ERROR in ./~/css-loader?{"importLoaders":1}!./~/postcss-loader?{}!./src/Tooltips/Tooltips.css
Module build failed: Error: Cannot find module 'postcss-load-options/lib/loadOptions.js'
    at Function.Module._resolveFilename (module.js:455:15)
    at Function.Module._load (module.js:403:25)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/postcss-load-config/index.js:9:19)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/postcss-loader/index.js:2:19)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at loadLoader (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/loader-runner/lib/loadLoader.js:13:17)
    at iteratePitchingLoaders (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/loader-runner/lib/LoaderRunner.js:164:2)
    at iteratePitchingLoaders (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/loader-runner/lib/LoaderRunner.js:160:10)
    at /Users/kevinSuttle/Code/ui-primitives-react/node_modules/loader-runner/lib/LoaderRunner.js:168:18
    at loadLoader (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/loader-runner/lib/loadLoader.js:36:3)
    at iteratePitchingLoaders (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/loader-runner/lib/LoaderRunner.js:164:2)
    at runLoaders (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/loader-runner/lib/LoaderRunner.js:357:2)
    at NormalModule.doBuild (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/webpack/lib/NormalModule.js:131:2)
    at NormalModule.build (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/webpack/lib/NormalModule.js:179:15)
    at Compilation.buildModule (/Users/kevinSuttle/Code/ui-primitives-react/node_modules/webpack/lib/Compilation.js:127:9)
 @ ./src/Tooltips/Tooltips.css 4:14-152
 @ ./src/Inputs/FormControl.js
 @ ./src/Selects/index.js
 @ ./src/index.js
 @ multi main

My config:

module.exports = {
  entry: ['./src/'],
  resolve: {
    descriptionFiles: ["package.json"],
  },
  output: {
    filename: 'ui-primitives-react.js',
    path: path.resolve(__dirname, 'build'),
    library: 'WatsonIoTUIPrimitives',
    libraryTarget: 'commonjs2',
  },
  externals: nodeEnv === 'production' ? {
    'react': 'var React',
    'react-dom': 'var ReactDOM',
  } : null,
  module: {
    rules: [{
      test: /\.js?$/,
      loader: 'babel-loader',
      exclude: /(node_modules|bower_components)/,
    }, {
      test: /\.css$/,
      use: [
        'style-loader', {
          loader: 'css-loader',
          options: {
            importLoaders: 1
          }
        }, {
          loader: 'postcss-loader',
          options: {
            plugins: function () {
              return [
                require('postcss-import')(),
                require('cssnext')({
                  features: {
                    customProperties: {
                      preserve: true,
                      appendVariables: true
                    }
                  }
                }),
                postCSSPrefix(CssClassPrefix, {
                  ignore: [/react-autosuggest/]
                }),
              ];
            }
          }
        }
      ]
    }]
  },
@farwayer

This comment has been minimized.

Copy link

farwayer commented Oct 11, 2016

@michael-ciniawsky

This comment has been minimized.

Copy link
Collaborator

michael-ciniawsky commented Oct 12, 2016

@ kevinShuttle @farwayer

fixed in postcss-load-config v1.0.0-beta

@ai

This comment has been minimized.

Copy link
Member

ai commented Oct 12, 2016

Guys! Thanks for you tests.

Now we fixed most of them. Could you test postcss-loader from GitHub again?

After 3 “working” reports, I will release new version ;).

@farwayer

This comment has been minimized.

Copy link

farwayer commented Oct 12, 2016

I'm afraid config from readme is not working:

{
    loader: 'postcss-loader',
    options: {
        plugins: function () {
            return [
                require('precss'),
                require('autoprefixer')
            ];
        }
    }
}

Please read webpack/webpack#3018 (comment).

@ai

This comment has been minimized.

Copy link
Member

ai commented Oct 12, 2016

@farwayer hm, very strange it works for one users, and doesn’t work for rest :-/

@farwayer

This comment has been minimized.

Copy link

farwayer commented Oct 12, 2016

@ai syntax with loader options or with LoaderOptionsPlugin?

@ai

This comment has been minimized.

Copy link
Member

ai commented Oct 12, 2016

@farwayer new syntax in rules and options/plugins works fine in my test https://github.com/ai/webpack2-postcss-test

@farwayer

This comment has been minimized.

Copy link

farwayer commented Oct 12, 2016

Something wrong with style-loader webpack/webpack#3018 (comment)

@ai

This comment has been minimized.

Copy link
Member

ai commented Oct 14, 2016

OK. @michael-ciniawsky publish postcss-load-confg release candidate. Let’s check postcss-loader last time.

@farwayer

This comment has been minimized.

Copy link

farwayer commented Oct 14, 2016

Loader options configurations will not work with style-loader but it's webpack core issue so nothing to do. Maybe it is better to keep note about this in readme before webpack/webpack#3136 will be fixed.

@ai

This comment has been minimized.

Copy link
Member

ai commented Oct 16, 2016

1.0 was released. Thanks to everyone for help.

@ai ai closed this Oct 16, 2016

@fmal

This comment has been minimized.

Copy link

fmal commented Oct 21, 2016

@ai i've updated to 1.0 and followed instructions in readme for webpack 2.x config (i'm using latest webpack beta.25). Due to issue mentioned by @farwayer i couldn't make it work. Providing options via webpack.LoaderOptionsPlugin solved the problem.

new webpack.LoaderOptionsPlugin({
  options: {
    postcss () {
      return [ ... ];
    }
  }
});

Please consider updating the readme, so that people using beta builds of webpack don't waste time running into this.

@ai

This comment has been minimized.

Copy link
Member

ai commented Oct 21, 2016

@fmal postcss-loader 1.0 doesn't need LoaderOptionsPlugin.

Could you show your config, I will try to find issue there.

@farwayer

This comment has been minimized.

Copy link

farwayer commented Oct 21, 2016

@ai add style-loader to loader chain and configuration via options will not work. Please check this issue. Of course it is not postcss-loader bug but using postcss with style is very often used configuration in dev.
So adding warning to readme is very desirable.

@Birowsky

This comment has been minimized.

Copy link

Birowsky commented Nov 12, 2016

@fmal postcss-loader 1.0 doesn't need LoaderOptionsPlugin.

@ai I couldn't a guide for how to specify plugins without creating a new file. Help?

@ai

This comment has been minimized.

Copy link
Member

ai commented Nov 12, 2016

@Birowsky

This comment has been minimized.

Copy link

Birowsky commented Nov 12, 2016

@ai I prefer keeping all the config inside the webpack config file. So I'll stick with the LoaderOptionsPlugin. Thanx anyways.

@michael-ciniawsky

This comment has been minimized.

Copy link
Collaborator

michael-ciniawsky commented Nov 13, 2016

@Birowsky

webpack: >v2.0.0-beta.25

webpack.config.js

module: {
 rules : [{
   test: /\.(sass|less|styl|sss|css)$/,
   use: [
        ...// style-loader, css-loader
        {
          loader: 'postcss-loader',
          options: { options: { /* PostCSS Options */ }, plugins: () => [ /* PostCSS Plugins */ ]  }
        }
       ...// less-loader, sass-loader, stylus-loader
    ]
  }]
}

Basically like in LoaderOptionsPlugin, the plugin was more of an 'polyfill' for webpack 2 < beta.25, webpack 2 development is still a bit in flux :)

@farskid

This comment has been minimized.

Copy link

farskid commented Feb 20, 2017

@Oopscurity Your solution worked for me on webpack@2.2.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.