webpack: define rule.use as a function, loader can't find options with ident

Bug report

What is the current behavior? When I define rule.use as a function and returns an array of loaders, but it will crash with this error: error: Module not found: Error: Can't find options with ident 'ref--xxx'

If the current behavior is a bug, please provide the steps to reproduce.

module: {
    rules: [
      {
        test: /\.scss$/,       
        use: (data) => {
         return [
            'style-loader',
            {
              loader: 'css-loader',
              options: {
                importLoaders: 2
              }
            },
            {
              loader: 'postcss-loader',
              options: {
                ident: 'postcss',
                plugins: () => [
                  require('autoprefixer')({
                    browsers: ['Chrome > 40', 'ios >= 7', 'android >= 4']
                  }),
                  require('postcss-px2rem')
                ],
                sourceMap: true
              }
            },
            'fast-sass-loader',         
          ];
        }
      }
    ]
  } 

What is the expected behavior? It should work correctly as rule.use defining a plain array.

Other relevant information: webpack version: 4.25.1 Node.js version: v8.11.3

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 8
  • Comments: 19 (4 by maintainers)

Most upvoted comments

Still seems to be an issue.

I’ve reproduced this issue here using vue-loader + babel-loader: jmoo/webpack-use-function-bug

Steps to reproduce:

  1. Create two rules w/ loaders
  2. Set up one of the rules with ‘use’ using a function
  3. Make sure that the ‘use’ function returns a loader + options (it will succeed if ‘options’ is not used)
  4. Create an entry that will trigger both rules + loaders.
{
    test: /\.vue$/,
    loader: 'vue-loader'
},
{
    test: /\.js$/,
    exclude: /(node_modules)/,
    use: i => ([
        {
            loader: 'babel-loader',
            options: {} // will succeed if we remove this line
        }
    ])
}
ERROR in ./vue-loader-test.vue?vue&type=script&lang=js&
Module not found: Error: Can't find options with ident 'ref--1-0'
 @ ./vue-loader-test.vue?vue&type=script&lang=js& 1:0-177 1:193-196 1:198-372 1:198-372
 @ ./vue-loader-test.vue
 @ ./index.js

Why is this closed? It’s still very much an issue in the circumstance that @dietergeerts describes.

Any progress on this? As I can read from the comments, there is a reproduction of the issue. And like others, I have this with vue-loader in combination with rules that use oneOf and a function for use.

It’s a pity we can’t use these options because of this bug, as that makes the webpack config bigger and more confusing, and some things just can’t be done without these features.

@evilebottnawi I’m not using fast-sass-loader

I tried this but still can’t get it to work.

     {
        test: /\.s?css$/,
        use: [
          'style-loader',
          info => ({ 
            loader: 'css-loader',
            options: {
              ident: 'css-loader',
              modules: true,
              importLoaders: 2,
            },
          }),
          'postcss-loader',
          {
            loader: 'resolve-url-loader',
            options: {
              sourceMap: true,
              debug: true,
              root: path.join(__dirname, 'src', 'images'),
            }
          },
          {
            loader: 'sass-loader',
            options: {
              includePaths: [
                path.join(__dirname, 'src', 'styles'),
              ],
              sourceMap: true,
              sourceMapContents: false,
            }
          },
        ]
      },

This gives me the following error:

ERROR in ./src/components/molecules/Works.scss
Module not found: Error: Can't find options with ident 'css-loader'
 @ ./src/components/molecules/Works.scss 2:14-257
 @ ./src/components/molecules/Works.jsx
 @ ./src/components/organisms/Issuer.jsx
 @ ./src/components/pages/Issuer.jsx
 @ ./src/components/routes/Issuer.jsx
 @ ./src/components/Router.jsx
 @ ./src/components/App.jsx
 @ ./src/index.jsx

Same for every import [classNames from] './index.scss'.

Also tried placing the ident immediately outside options. Same result.

Problem on fast-sass-loader sire, fast-sass-loader is not compatibility with webpack by design, you use this loader at one’s own risk

@nskazki, you absolutely legend. I’ve been trying to figure this out for hours, and inlining the options works great. Thanks.

@jmoo thanks for pointing to the source of this issue. Inlined options work!

{
  test: glob2re('.less'),
  use: ({ issuer, resource }) => {
    if (!issuer) {
      return inlineOptions(concat(cssExtractLoader, cssLoader, postcssLoader, lessLoader))
    } else if (glob2re('.vue').test(issuer)) {
      return inlineOptions(concat(vueStyleLoader, cssLoader, postcssLoader, lessLoader))
    } else {
      return inlineOptions(concat(styleLoader, cssLoader, postcssLoader, lessLoader))
    }
  }
}
function inlineOptions(loaders) {
  return loaders.map(({ loader, options={} }) => {
    if (!isString(loader)) throw new Error('inlineOptions: loader should be a string!')
    if (!isObjectLike(options)) throw new Error('inlineOptions: options should be an object!')
    return loader + '?' + JSON.stringify(options)
  })
}

@evilebottnawi alright, haven’t yet created the minimum reproducible test repo, but the live work is open source and auto deploys to Netlify… so it should give us something to start with.

The repo is https://github.com/poetapp/explorer-web master deploys to https://explorer-mainnet.poetnetwork.net/ and is currently working fine

I’ve created a PR introducing the use of the function useEntry, which can be seen to fail the build. See the PR here: https://github.com/poetapp/explorer-web/pull/553. I left the detailed log output in the PR description.

Also tried adding an ident property in this PR: https://github.com/poetapp/explorer-web/pull/554.

I also tried moving the ident property around. It always fails.