Webpack-5 - Webpack 尝试解析 scss(或 css)中图像的根相对路径并失败

dov*_*isz 8 webpack webpack-5

升级到 Webpack-5 后出现此错误:

Error: Can't resolve '/path/to/image.jpg' in '/app/path/to/module/module'

问题在于用于 css 背景的图像,其中文件未存储在存储库中,并且在构建时不可用。(为什么会这样,以后再说了。)

问题:

在我的 scss 文件中:

background-image: url(/path/to/image.jpg);
Run Code Online (Sandbox Code Playgroud)

在 Webpack-4 中,它保持原样,并且可以正常工作。

Webpack-5 尝试处理图像,但失败并出现上述错误。

这不起作用:

在路径中添加引号...

background-image: url("/path/to/image.jpg");
Run Code Online (Sandbox Code Playgroud)

我尝试过 Webpacks 魔法评论......

/* webpackIgnore: true */
background-image: url(/path/to/image.jpg)

Run Code Online (Sandbox Code Playgroud)

...但它不起作用(也许他们被剥夺得太早了? - 这似乎是这种情况,我的create-react-app 示例中的开发构建证明了这一点)

webpack.IgnorePlugin

我还尝试了这里的一些边缘情况技巧。但我认为这来得太晚了,因为 Webpack 已经假设该文件存在。

这有效,但是...

有效的方法是包含资产的绝对路径:

background-image: url(https://www.example.com/path/to/image.jpg);
Run Code Online (Sandbox Code Playgroud)

但这也带来了一系列问题。

更新:

我在此存储库中重现了该问题:

Webpack 魔术注释适用于开发构建,但不适用于生产构建。

~/webpack-test$ npm run build

> webpack-test@0.1.0 build
> node scripts/build.js

Creating an optimized production build...
Failed to compile.

Module not found: Error: Can't resolve '/mypics/pom.jpg' in '/home/nodejs/webpack-test/src'
Run Code Online (Sandbox Code Playgroud)

dov*_*isz 6

事实证明,css-loader 在下面有专门用于此的配置选项options.url

感谢Webpack 团队的Alexander Akait在这里回答我的问题。

它可以选择传递一个包含filter()谓词函数的对象,该谓词函数应确定是否应处理路径:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: "css-loader",
        options: {
          url: {
            filter: (url, _resourcePath) => {
              // Disable processing for root-relative urls under /images
              return !/^\/images\//.test(url)

              // This would disable processing for all root-relative urls:
              // return !/^\//.test(url);
            },
          },
        },
      },
    ],
  },
};
Run Code Online (Sandbox Code Playgroud)

这是我在问题中提到的存储库中用于解决此问题的提交:https://github.com/dovidweisz/webpack-test/commit/a9e4cfc4ae0a5a8475ddd2cc114a8650846db421

您还可以通过简单地传递到来禁用所有url 处理:falseoptions.url

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: "css-loader",
        options: {
          url: false,
        },
      },
    ],
  },
};
Run Code Online (Sandbox Code Playgroud)