編碼的世界 / 優質文選 / 生涯

webpack4.x中關於css-loader的幾個坑


2022年6月30日
-   

本文主要記錄筆者在webpack4.x項目下使用css-loader管理css踩到的坑(下面用一個逐步修改的示例來說明)。
示例源碼:https://github.com/liqing-taoyanzoukaila/webpack4-css-loader
項目的初始訴求是使用webpack來托管css的合並。
示例代碼結構如下圖:
package.json代碼:
{
"name": "webpack4-css-loader",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"dev": "webpack progress colors config ./webpack.config.js"
},
"author": "liqing",
"license": "ISC",
"dependencies": {
"css-loader": "^1.0.0",
"webpack": "^4.6.0",
"webpack-cli": "^2.1.3"
}
}

webpack.config.js代碼(js目錄下的main.js是入口函數,build是構建目錄,為了清晰描述問題,這裏只用css-loader來處理css):
const path = require("path");
module.exports = {
entry: "./js/main.js",
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/build/",
filename: "[name].js"
},
module: {
rules: [
{
test: /.css$/,
use: [{
loader: 'css-loader'
}]
}
]
},
devtool: 'inline-source-map',
mode: 'development',
plugins: []
};

main.js代碼(聲明所需的css,否則webpack不會處理):
require('./../css/main.css');
require('./../css/font.css');

執行npm run dev後有兩種可能:
css不包含url,編譯成功。
css包含url,即包含如下的樣式:
.container{width: 100%; height: 100%; background: url(../images/loginBG.png)}

此時編譯失敗,會提示文件類型(其實是url內引用的各種圖片文件類型)無法識別,需要其他的loader來處理:
上面的錯誤有兩種方法處理:
1.聲明url不處理(更新後的webpack.config.js):
const path = require("path");
module.exports = {
entry: "./js/main.js",
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/build/",
filename: "[name].js"
},
module: {
rules: [
{
test: /.css$/,
use: [{
loader: 'css-loader',
options: {
url: false
}
}]
}
]
},
devtool: 'inline-source-map',
mode: 'development',
plugins: []
};

2.用url-loader處理css中的url(更新後的webpack.config.js):
const path = require("path");
module.exports = {
entry: "./js/main.js",
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/build/",
filename: "[name].js"
},
module: {
rules: [
{
test: /.css$/,
use: [{
loader: 'css-loader'
}]
},
{
test: /.(gif|png|jpg|woff|svg|ttf|eot)$/ ,
use:[{
loader:'url-loader',
options: {
limit:500,
outputPath: 'images/',
name:'[name].[ext]'
//publicPath:output,
}
}]
}
]
},
devtool: 'inline-source-map',
mode: 'development',
plugins: []
};

更新後的package.json(需要file-loader和url-loader):
{
"name": "webpack4-css-loader",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"dev": "webpack progress colors config ./webpack.config.js"
},
"author": "liqing",
"license": "ISC",
"dependencies": {
"css-loader": "^1.0.0",
"file-loader": "^2.0.0",
"url-loader": "^1.1.2",
"webpack": "^4.6.0",
"webpack-cli": "^2.1.3"
}
}

無論選擇上面的哪種方法,css的打包功能都可以正常執行,但是在編譯的js中可以看到css是通過js引入的(這樣處理可能會帶來性能問題),且css沒有和js分離,那麼進一步的訴求就是把css拆出來。
這個訴求可以利用mini-css-extract-plugin來完成(更新後的webpack.config.js):
const path = require("path");
const miniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: "./js/main.js",
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/build/",
filename: "[name].js"
},
module: {
rules: [
{
test: /.css$/,
use: [
miniCssExtractPlugin.loader,
{loader: 'css-loader'}
]
},
{
test: /.(gif|png|jpg|woff|svg|ttf|eot)$/ ,
use:[{
loader:'url-loader',
options: {
limit:500,
outputPath: 'images/',
name:'[name].[ext]'
//publicPath:output,
}
}]
}
]
},
devtool: 'inline-source-map',
mode: 'development',
plugins: [
new miniCssExtractPlugin({
filename: '[name].css'
})
]
};

編譯後的目錄結構如下(css已經與js分離):
最後總結一下:
css-loader可以管理項目中的css,但css中的url(引用的各種類型的圖片)需要url-loader(file-loader)協助處理,而mini-css-extract-plugin可以執行css和js分離。

熱門文章