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

Unexpected behavior of the LoaderOptionsPlugin #2684

Closed
kiurchv opened this issue Jun 23, 2016 · 10 comments
Closed

Unexpected behavior of the LoaderOptionsPlugin #2684

kiurchv opened this issue Jun 23, 2016 · 10 comments
Labels

Comments

@kiurchv
Copy link

kiurchv commented Jun 23, 2016

I'm submitting a bug report

Webpack version:
2.x

Please tell us about your environment:
OSX 10.x

Current behavior:
I'm using LoaderOptionsPlugin to pass options to postcss-loader. When using the plugin, other loaders in the chain unable to access the webpack options object and failing with TypeError: Cannot read property 'path' of undefined at Object.module.exports ([project path]/node_modules/sass-loader/index.js:227:52). It seems that this plugin overriding entire options property in the loader context with the given values.

Expected/desired behavior:
LoaderOptionsPlugin should extend webpack options in the loader context with the given options instead of overriding entire object and making webpack options unaccessible for loaders.

  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem along with a gist/jsbin of your webpack configuration.

Used loaders:

{
  test: /\.scss$/i,
  loaders: [
    "style-loader",
    {
      loader: "css-loader",
      query: {
        sourceMap: true,
        modules: true,
        importLoaders: 2
      }
    },
    {
      loader: "sass-loader",
      query: {
        sourceMap: true,
      }
    },
    {
      loader: "postcss-loader"
    }
  ]
}

LoaderOptionsPlugin config:

new webpack.LoaderOptionsPlugin({
  test: /\.scss$/i,
  options: {
    postcss: {
      plugins: [autoprefixer, postcssReporter({ clearMessages: true })],
      syntax: scssSyntax
    }
  }
});

Loader versions:

  • style-loader: 0.13.1
  • css-loader: 0.23.1
  • sass-loader: 3.2.0
  • postcss-loader: 0.9.1

- **Browser:** all - **Language:** all
@sokra
Copy link
Member

sokra commented Jun 24, 2016

This behavior is intended. Loaders should not access the webpack options (all passed options should be explicit). The plan (for webpack 3) is to remove the default this.options in the loader context and make loaders more independent from webpack env.

The sass-loader accesses this.options.output.path, which it shouldn't do. cc @jhnns

As workaround you can still pass output.path via the LoaderOptionsPlugin.

@jhnns
Copy link
Member

jhnns commented Jun 26, 2016

The css-loader accesses this.options as well 👅

I think a loader needs access to the context from the webpack options. I don't think that it should be configurable like it is in the css-loader. It would be nicer if things just work out-of-the-box.

@MoOx
Copy link
Contributor

MoOx commented Sep 20, 2016

@jhnns I just faced this issue and need to add context: __dirname...

@hansoksendahl
Copy link

hansoksendahl commented Sep 22, 2016

@MoOx I think you meant context: __dirname.

    new webpack.LoaderOptionsPlugin({
      options: {
        postcss: () => options.postcssPlugins,
        context: __dirname,
      },
    }),

That fixed our problems at work.

@jhnns
Copy link
Member

jhnns commented Oct 5, 2016

We should still allow to read from the webpack config to allow sane defaults. But I agree that it is good practice to make it overwritable.

@nagarajay
Copy link

@sokra @jhnns - Need help!
I have been trying to use React-toolbox in my project. I have finally been able to do everything but the setup of theme.

For sass-loader in webpack V1 i had used the following code in the configuration.
sassLoader: {
data: '@import "theme/_config.scss";',
includePaths: [resolve(__dirname, './src/client')]
}.

This was working as desired and the theme was reflected.

Now for webpack V2 I understand that we are not allowed to give it this way. So I have
new webpack.LoaderOptionsPlugin({
minimize: false,
debug: false,
options: {
postcss: [ autoprefixer({ browsers: ['last 5 versions'] })],
sassLoader: {
data: '@import "theme/_config.scss";',
includePaths: [resolve(__dirname, './src/client')]
}
}})

Somehow everything compiles fine but the variable values marked in config.scss do not change the theme.

Appreciate your help. Cheers

@jhnns
Copy link
Member

jhnns commented Oct 20, 2016

You should apply it this way:

new webpack.LoaderOptionsPlugin({
  test: /\.scss$/,
  minimize: false,
  debug: false,
  options: {
    postcss: [ autoprefixer({ browsers: ['last 5 versions'] })],
    sassLoader: {
      data: '@import "theme/_config.scss";',
      includePaths: [resolve(__dirname, './src/client')]
    }
  }
})

@nagarajay
Copy link

@jhnns - Firstly thanks for listening to my concern. I will just share my setup so that I am clear.

Boilerplate with Webpack V2, React-hot-loader V3, React-Router V4, React-toolbox (this has theming capabilities as given in their website react-toolbox.com), Webpack-dev-middleware and webpack-hot-middleware.

With Webpack V1 and Webpack-Dev-server, hot reloading on. Themeing was working fine but with browser refresh.

With Webpack V2 and the boilerplate mentioned above, using the above code did not pick the changes marked in the theme variable scss file. Even on browser refresh somehow the default configuration was loading with the output bundle file.

So I am not confident but I think this is not working. Autoprefixer is working for sure but the sassLoader is not possibly.

I have solved my problem with a hack using npm scripts to actually overwrite the node_modules global file thus giving me exactly what I need but yeah it certainly is and feels a hack :).

@jhnns
Copy link
Member

jhnns commented Oct 21, 2016

Could you create a simple repo that demonstrates your problem? React has nothing to do with it. Just try to compile a simple scss file this way and then you'll see if the options are working as expected.

@nagarajay
Copy link

nagarajay commented Oct 21, 2016

@jhnns Great News! It works. repo Tested both regular scss file and react-toolbox stuff too.

I have to debug more as to why it is not working with my project with RHL3 and RR4.

Cheers!!

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

No branches or pull requests

7 participants