带有 sass-loader 和 resolve-url-loader 的 Webpack 4 - 找不到图像路径

Posted

技术标签:

【中文标题】带有 sass-loader 和 resolve-url-loader 的 Webpack 4 - 找不到图像路径【英文标题】:Webpack 4 with sass-loader & resolve-url-loader - Image paths not being found 【发布时间】:2018-09-22 21:47:23 【问题描述】:

此处的最小可重复设置:https://github.com/jamesopti/webpack_playground/tree/resolve_url_loader_issue

我正在尝试使用 resolve-url-loader 向我的 scss url() 图像路径添加一个哈希名,但我有一段时间让它与 webpack 4 一起工作。 我在/static/img/** 中有一堆图像,这些图像在我的 SCSS 中被引用,例如:

span.arrow 
  background: url(/static/img/audiences.png);

这在我的 css 中以完全相同的方式结束(resolve-url-loader 没有找到它们)

当我通过 webpack 运行以下配置时,我看到解析加载程序正在寻找正确的 url() 及其路径,但调试模式显示 NOT FOUND。

resolve-url-loader: /static/img/audiences.png
  /Users/usr1/webpack_playground/src
  /Users/usr1/webpack_playground/static/img
  NOT FOUND

是否有一些输出配置不正确?我尝试了各种设置组合均无济于事:

  loader: 'resolve-url-loader',
  options: 
    debug: true,
    root: path.join(__dirname, './static/img'),
    includeRoot: true,
    absolute: true,
  ,

我的最终目标是让文件加载器将它们转换为 /dist 散列版本:

span.arrow 
  background: url(/static/img/audiences-dhsye47djs82kdhe6.png);

// Webpack 规则配置

rules: [
      
        test: /\.(png|jpg|gif)$/,
        include: [
          path.resolve(__dirname, './static/img'),
        ],
        use: 
          loader: 'file-loader',
          options: 
            name: '[name]-[hash].[ext]',
          ,
        ,
      ,
      
        test: /\.svg$/,
        use: 
          loader: 'svg-inline-loader',
          options: 
            name: '[name]-[hash].[ext]',
          ,
        ,
      ,
       test: /\/src\/js\/(?:.*)\.css$/, use: [  loader: 'style-loader' ,  loader: 'css-loader'  ] ,
      
        test: [/\.scss$/, /\.sass$/],
        use: [
          MiniCssExtractPlugin.loader,
          
            loader: 'css-loader',
            options: 
              sourceMap: true,
            ,
          ,
          
            loader: 'resolve-url-loader',
            options: 
              debug: true,
              root: './static/img',
              includeRoot: true,
            ,
          ,
          
            loader: 'sass-loader',
            options: 
              outputStyle: 'compressed',
              sourceMap: true,
              includePaths: [
                './src'
              ],
            ,
          ,
        ],
      ,
]

【问题讨论】:

【参考方案1】:

事实证明,我只需要file-loader 来做我想做的事。

当任何 css/sass/style 加载器遇到图像(匹配我指定的文件扩展名)时,它会通过 file-loader 处理,这会将其复制到指定命名格式的输出目录并返回sass 加载器的名称,用作文件名。

rules: [
  
    test: /\.(png|jpg|gif|svg)$/,
    exclude: [
      path.resolve(__dirname, './node_modules'),
    ],
    use: 
      loader: 'file-loader',
      options: 
        name: '[path][name]-[hash].[ext]',
        outputPath: '../',
        publicPath: '/dist',
      ,
    ,
  ,
  
    test: /\.svg$/,
    include: [
      path.resolve(__dirname, './node_modules'),
    ],
    use: 
      loader: 'svg-inline-loader',
      options: 
        name: '[name]-[hash].[ext]',
      ,
    ,
  ,
   test: /\/src\/js\/(?:.*)\.css$/, use: [  loader: 'style-loader' ,  loader: 'css-loader'  ] ,
  
    test: [/\.scss$/, /\.sass$/],
    use: [
      MiniCssExtractPlugin.loader,
      
        loader: 'css-loader',
        options: 
          sourceMap: true,
          root: path.resolve(__dirname),
        ,
      ,
      
        loader: 'postcss-loader',
        options: 
          ident: 'postcss',
          plugins: () => [
            autoprefixer(
              'browsers': ['last 2 versions', 'ie >= 10'],
            ),
          ],
          sourceMap: true,
        ,
      ,
      
        loader: 'sass-loader',
        options: 
          outputStyle: 'compressed',
          sourceMap: true,
          includePaths: [
            './src/scss',
          ],
        ,
      ,
    ],
  ,
  
    test: /\.html$/,
    use: [
      
        loader: 'html-loader',
        options: 
          root: path.resolve(__dirname),
        ,
      ,
    ],
  ,
  
    test: [
      /\/bundles\/(?:.*)\.js$/,
    ],
    use: 
      loader: 'babel-loader',
    ,
  ,
];

【讨论】:

你有这个的github吗?我处理同样的问题,但我无法解决它【参考方案2】:

实际上仍需要 resolve-url-loader 有时... 这取决于您是否希望能够从 sass 编译中导入的文件解析 url() 调用。在这种情况下,如果没有它,网址将被破坏。

但是,如果您不使用多文件 scss 构建(例如,如果每个组件只有 1 个本地 scss 文件而不调用共享库 scss 代码或某种类型的部分) - 那么您不需要解析-url-loader。

当然,您仍然需要 url-loader(使用内联功能包装文件加载器)或文件加载器(用于将资产直接复制到 dist 文件夹)

resolve-url-loader 通过重新处理 sass 发出的源映射中的原始文件来工作 在使用 dart-sass 实现时,sass-loader 确实存在源映射问题。在这种情况下,源映射源会错误地用标准输入代替文件名 请参阅 issue 671 并修复 PR 681 中的问题

截至今天(2019 年 7 月),这仍然是未发布的修复程序,唯一的选择是使用 node-sass 或使用未发布的 sass-loader

【讨论】:

【参考方案3】:

我有同样的问题。我相信 you need url-loader 可以使用 Webpack 4 正确加载图像。这个设置对我有用:

rules: [
    
        test: /\.(png|jpg)$/,
        loader: "url-loader",
    ,         
        test: /\.(scss|css)$/,
        use: [
            "style-loader",
            "css-loader",
            "sass-loader",
        ]
    
]

【讨论】:

你有这个参考吗?我已经尝试使用 webpack 4 的“url-loader”,并且 CSS 中的 URL 没有经过 base64 编码。 我在回答中链接到了url-loader Github。标题limit 下有一个注释,描述了如何获取base64 编码。

以上是关于带有 sass-loader 和 resolve-url-loader 的 Webpack 4 - 找不到图像路径的主要内容,如果未能解决你的问题,请参考以下文章

Webpack 中的相对 CSS url

带有 webpack 和 sass-loader 的 Susy 网格

带有 Webpack、React 和 Babel 的 Sass-loader 无法正常工作

带有 sass-loader、MiniCssExtractPlugin 和 uikit 的 Webpack4

带有 vue-loader 和 sass-loader 的 webpack 无法导入 .scss 文件

带有 sass-loader 的 mini-css-extract-plugin 不输出 CSS 文件