使用 css-loader 解析 Webpack url() 路径
Posted
技术标签:
【中文标题】使用 css-loader 解析 Webpack url() 路径【英文标题】:Webpack url() path resolution with css-loader 【发布时间】:2020-04-09 21:39:15 【问题描述】:出于显而易见的原因,我正在开发一个网站并使用 webpack。我遇到的问题是通过我的 SCSS 文件导入到我的项目中的图像的路径分辨率。问题是 css-loader 没有解析正确的路径。似乎正在发生的事情如下:
如果我允许css-loader
处理 url() 导入(保留 url 选项为 true),它会重写相对于ExtractCSSChunksPlugin()
中指定的输出目录的文件路径,例如:
url('../img/an-image.jpg')
应该改写为url('http://localhost:3000/assets/img/an-image.jpg')
,然而实际输出的是url('http://localhost:3000/assets/css/assets/img/an-image.jpg')
。
如果我将其更改为 false,则会解析正确的路径,但 file-loader
无法找到图像然后发出它们。
我知道当 css-loader 处理 url 解析时正在输出图像,因为我可以在编译包时看到发出的消息——它没有失败。
如果我在 JS 入口点手动添加对它们的导入调用,在 entry:
字段中设置,然后在 SCSS 中调用绝对路径,我也可以让图像显示。但这是不可取的,因为随着项目的增长,它变得乏味。
我曾尝试使用resolve-url-loader
并更改多个设置,但我似乎无法让它工作。
我也尝试过使用 webpack 提供的 resolve: alias: Images: path.resolve(__dirname, 'src/assets/img/'
选项,然后在我的 SCSS 中调用 url('~Images/an-image.jpg')
,但它只是重现了相同的结果。
所以,总的来说,我的问题是我需要能够在我的 SCSS 中使用相对路径,然后让我的一个加载器将它们重写为正确的路径。
我当前的 webpack 配置(使用文件加载器输出文件,但在 url 的开头添加 assets/css/
)如下:
"use strict";
const webpack = require('webpack');
const merge = require('webpack-merge');
const common = require('./webpack.common');
const ExtractCSSChunksPlugin = require('extract-css-chunks-webpack-plugin');
module.exports = merge(common,
mode: 'development',
devtool: 'inline-source-map',
entry: [
'webpack-hot-middleware/client',
],
module:
rules: [
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use:
loader: 'babel-loader',
options:
presets: ['@babel/preset-env'],
,
test: /\.scss$/,
use: [
loader: ExtractCSSChunksPlugin.loader,
options:
hot: true,
,
loader: 'css-loader',
options:
sourceMap: true,
,
loader: 'sass-loader',
options:
sourceMap: true,
]
,
test: /\.html$/,
use:['html-loader']
,
test:/\.(svg|jpg|png|gif)$/,
use: [
loader:'file-loader',
options:
publicPath: 'assets/img',
outputPath: 'assets/img',
name: '[name].[ext]',
esModule: false
],
,
]
,
plugins: [
new webpack.HotModuleReplacementPlugin(),
new ExtractCSSChunksPlugin(
filename: 'assets/css/[name].css',
chunkFilename: 'assets/css/[id].css',
),
]
);
提前谢谢你。
【问题讨论】:
【参考方案1】:好的,看来我已经通过解决文件加载器配置字段中设置的publicPath
解决了这个问题:publicPath: path.resolve(__dirname, '/assets/img')
。
我现在的配置是:
"use strict";
const webpack = require('webpack');
const merge = require('webpack-merge');
const common = require('./webpack.common');
const path = require('path');
const ExtractCSSChunksPlugin = require('extract-css-chunks-webpack-plugin');
module.exports = merge(common,
mode: 'development',
devtool: 'inline-source-map',
entry: [
'webpack-hot-middleware/client',
],
module:
rules: [
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use:
loader: 'babel-loader',
options:
presets: ['@babel/preset-env'],
,
test: /\.scss$/,
use: [
loader: ExtractCSSChunksPlugin.loader,
options:
hot: true,
,
loader: 'css-loader',
options:
sourceMap: true,
,
loader: 'sass-loader',
options:
sourceMap: true,
]
,
test: /\.html$/,
use:['html-loader']
,
test:/\.(svg|jpg|png|gif)$/,
use: [
loader:'file-loader',
options:
publicPath: path.resolve(__dirname, '/assets/img'),
outputPath: 'assets/img',
name: '[name].[ext]',
esModule: false
],
,
]
,
plugins: [
new webpack.HotModuleReplacementPlugin(),
new ExtractCSSChunksPlugin(
filename: 'assets/css/[name].css',
chunkFilename: 'assets/css/[id].css',
),
]
);
【讨论】:
【参考方案2】:我认为在 webpack 配置中添加 url 加载器会有所帮助。
test: /\.(jpg|png)$/,
use:
loader: "url-loader",
options:
limit: 25000,
,
,
,
【讨论】:
谢谢老兄,这是file-loader
配置。我不想使用 url 加载器,因为它只是对所有内容进行 base64 编码,除非您设置了非常高的限制。以上是关于使用 css-loader 解析 Webpack url() 路径的主要内容,如果未能解决你的问题,请参考以下文章
Webpack style-loader / css-loader: url() 路径解析不起作用