Skip to content

Webpack 5 compatibility: Options from some rules are applied to others #1620

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

Closed
Lyrkan opened this issue Dec 22, 2019 · 2 comments · Fixed by #1653
Closed

Webpack 5 compatibility: Options from some rules are applied to others #1620

Lyrkan opened this issue Dec 22, 2019 · 2 comments · Fixed by #1653

Comments

@Lyrkan
Copy link

Lyrkan commented Dec 22, 2019

Version

15.8.3

Reproduction link

https://github.com/Lyrkan/repro-vue-loader-webpack5

Steps to reproduce

  1. Create a basic project using the latest version of vue-loader and Webpack 5 with the three following rules :
  • { test: /\.js$/, use: [ { loader: 'babel-loader', options: {} } ] }
  • { test: /\.css$/, use: [ { loader: 'css-loader', options: { url: true } } ] } (url can be replaced by any option that exists in css-loader but not in babel-loader)
  • { test: /\.vue$/, loader: 'vue-loader' }
  1. Import a .vue file that contains a <script> tag

  2. Try to compile the project

What is expected?

Should compile fine

What is actually happening?

The build fails because the url option meant for the css-loader is passed to the babel-loader:

ERROR in ./src/App.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib??ruleSet[0].rules[0].use[0]!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js&)
Module build failed (from ./node_modules/babel-loader/lib/index.js):
ReferenceError: Unknown option: .url. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.

It does not happen when using Webpack 4
It does not happen either when not using Rule.use or when options is not specified in the babel-loader rule.

@lovetingyuan
Copy link

webpack 5 rewrite the whole logic of rules, so the rules cloned by vue-loader may have same ident. A simple way is to add ident value or change use to a function.

{
  test: /\.css$/,
  use: () => [{
    loader: 'css-loader',
    options: {
      url: true
    }
  }]
}
// or
{
  test: /\.css$/,
  use: [{
    loader: 'css-loader',
    options: {
      url: true
    },
    ident: 'css-loader-ident'
  }]
}

@ryanelian
Copy link

ryanelian commented Jan 5, 2020

Related issue, this kind of configuration does not work anymore in webpack 5. The CSS loader for CSS module grabs the configuration from non-CSS-module CSS loader.

// EDIT: code removed, see fixed configuration below

EDIT: Fixed by adding ident to ALL loaders in my webpack configuration...

Gonna paste this for people who need updated CSS loader configuration for Vue loader.

const vueStyleLoader: webpack.RuleSetLoader = {
            loader: LoaderPaths.vueStyle,
            ident: 'vue-style-loader'
        };
        // https://vue-loader.vuejs.org/guide/css-modules.html#usage
        const cssModulesLoader: webpack.RuleSetLoader = {
            loader: LoaderPaths.css,
            ident: 'vue-css-module-loader',
            options: {
                // enable CSS Modules
                modules: {
                    localIdentName: '[local]_[contenthash:8]'
                },
                url: false
            }
        };
        const cssLoader: webpack.RuleSetLoader = {
            loader: LoaderPaths.css,
            ident: 'vue-css-loader',
            options: {
                url: false
            }
        };

        return {
            test: /\.css$/,
            resourceQuery: /\?vue/,
            oneOf: [
                {
                    // this matches <style module>
                    // ./HelloWorld.vue?vue&type=style&index=0&module=true&lang=css&
                    resourceQuery: /module=true/,
                    use: [vueStyleLoader, cssModulesLoader]
                },
                {
                    // this matches plain <style> or <style scoped>
                    // HelloWorld.vue?vue&type=style&index=0&lang=css&
                    use: [vueStyleLoader, cssLoader]
                }
            ]
        };

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

Successfully merging a pull request may close this issue.

4 participants