无法使用Webpack解析CSS中背景图像的绝对url()路径

时间:2016-03-04 00:58:29

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

我有以下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的检查器中路径“看起来”正确,但是当您在新选项卡中实际打开链接时,它指向:chrome-devtools://devtools/bundled/"/images/bg.png"显然无法正确解析。

我不确定问题是否与url-loader配置有关,或者究竟发生了什么。

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

有什么想法吗? MTIA!

更新

我应该注意,它在Safari中运行良好,但在Chrome中运行不正常。所以它似乎是特定于Chrome的错误,但是在Safari中进行所有开发是不切实际的。

我也遇到了vue-style-loader,它是一个样式加载器的分支,声称可以修复这个问题,但它修复它的方式是依赖于一个hacky deprecated escape / unescape方法。

2 个答案:

答案 0 :(得分:5)

我可以提出的一个可能的解决方案如下:

使用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-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

希望很快能找到真正的解决办法......

答案 1 :(得分:1)

使用webpack 2:

在.scss文件中,在路径前使用〜。

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

使用webpack中的resolve root,将其添加到webpack.config.js:

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

它也适用于@import,例如@import“~otherfile.scss”