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

7
我有以下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');
}

我认为这是因为CSS加载器定义了root。我收到一个构建错误: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,但不确定那是否是我需要的。
有什么想法吗?谢谢!
更新
我应该注意到,在Safari中它可以正常工作,但在Chrome中却不能。所以它似乎是一个针对Chrome的特定bug,但在Safari中进行所有开发并不现实。
我还遇到了vue-style-loader,它是style-loader的分支,声称可以解决这个问题,但它解决的方法是依赖于一个过时的hacky转义/取消转义方法。
2个回答

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结构,您可能还需要调整url-loader名称参数:

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

我不知道是否有更好的方法来解决这个问题,但这是目前我能想到的最佳方案。欢迎任何反馈或替代方案。

谢谢!

2016年6月30日更新

有一些拉取请求可以解决此问题,但维护者更喜欢在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的resolve root,将以下代码添加到你的webpack.config.js文件中:

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

它也应该适用于@import,例如@import“〜otherfile.scss”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接