【问题标题】:Unable to resolve absolute url() paths for background images in CSS with Webpack无法使用 Webpack 解析 CSS 中背景图像的绝对 url() 路径
【发布时间】:2017-01-17 03:49:55
【问题描述】:

我有以下 Webpack 配置(大致上,它已经为这篇文章进行了简化):

const rootPublic = path.resolve('./public');
const LOCAL_IDENT_NAME = 'localIdentName=[name]_[local]_[hash:base64:5]';
const CSS_LOADER = `css?sourceMap&${LOCAL_IDENT_NAME}&root=${rootPublic}`;
const SASS_LOADER = 'sass?sourceMap&includePaths[]=' + path.resolve(__dirname, './src/styles');

// ... loaders:

loaders: [
  {
    test: /\.(jpe?g|png|gif|svg)$/,
    loader: 'url-loader?limit=10000&name=[path][name].[ext]'
  },
  {
    test: /\.scss$/,
    loader: config.DEVELOPMENT_MODE ? `style!${CSS_LOADER}!autoprefixer!${SASS_LOADER}`
                : ExtractTextPlugin.extract('style', `${CSS_LOADER}!autoprefixer!${SASS_LOADER}`)
  }, // ...
]

现在这对于在 scss 文件中通常引用的图像非常有效:

.some-static-class {
  background: url('/images/bg.png');
}

但是,当使用:local 指令时,它确实不起作用

:local .SomeClass {
  background: url('/images/bg.png');
}

我认为这是因为 root 是为 CSS 加载器定义的。我收到构建错误:Module not found: Error: Cannot resolve 'file' or 'directory' ./../../../../../../../../images/bg.gif

如果我改为从 css-loader 配置中删除 root,那么它构建得很好,但是在 Chrome 的检查器中路径“看起来”是正确的,但是当你实际在新选项卡中打开链接时,它指向:@ 987654329@ 显然无法正确解析。

我不确定问题出在url-loader 配置上,还是到底发生了什么。

我尝试了不同的 webpack 配置来指定 resolve.root、resolve.modulesDirectories 等,但完全不确定它们是否有任何影响,或者我是否完全错误。我也遇到了resolve-url-loader,但不确定这是否是我所需要的。

有什么想法吗? MTIA!

更新

我应该注意,它在 Safari 中可以正常工作,但在 Chrome 中却不行。因此,这似乎是 Chrome 特有的错误,但必须在 Safari 中完成所有开发是不切实际的。

我还遇到了vue-style-loader,它是样式加载器的一个分支,声称可以解决这个问题,但它修复它的方式是依赖于一个不推荐使用的骇人听闻的转义/取消转义方法。

【问题讨论】:

    标签: webpack webpack-dev-server urlloader webpack-style-loader


    【解决方案1】:

    我能想到的一个可能的解决方案如下:

    使用resolve-url-loader(紧跟在sass-loader之后):

    style!${CSS_LOADER}!autoprefixer!resolve-url!${SASS_LOADER}
    

    然后,为静态图片定义一个 resolve.alias:

    resolve: {
      alias: {
        images: path.join(__dirname, 'public/images')
      }
    }
    

    然后在 CSS 中,您可以像这样指向图像:

    :local .SomeClass {
      background: url('images/bg.png');
    }
    

    根据您的 URL 结构,您可能还需要调整 url-loader 名称参数:

    {
      test: /\.(jpe?g|png|gif|svg)$/,
      loader: 'url-loader?limit=10000&name=images/[name].[ext]'
    }
    

    所以我不知道是否有更简洁的方法来解决这个问题,但这是迄今为止我能想到的最好的方法。我欢迎任何反馈或替代方案。

    谢谢!

    2016 年 6 月 30 日更新

    有几个 PR 可以解决这个问题,但维护者更喜欢在 CSS AST 中而不是在 CSS 加载器中的解决方案...

    https://github.com/webpack/style-loader/pull/124 https://github.com/webpack/style-loader/pull/96

    希望真正的修复能很快发生...

    【讨论】:

      【解决方案2】:

      使用 webpack 2:

      在您的 .scss 文件中,在路径前使用 ~。

      .yourClass {
            background: url('~img/wallpaper.png');
      }
      

      利用 webpack 的解析根目录,将其添加到您的 webpack.config.js:

      resolve: {
              modules: [
                  path.resolve(root),
                  'node_modules'
              ]
          },
      

      它也应该适用于@import,例如@import "~otherfile.scss"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-22
        • 2023-04-01
        • 2022-01-03
        • 2018-11-12
        • 2020-05-15
        • 2014-03-31
        • 1970-01-01
        • 2017-12-15
        相关资源
        最近更新 更多