本文主要记录笔者在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-loader可以管理项目中的css,但css中的url(引用的各种类型的图片)需要url-loader(file-loader)协助处理,而mini-css-extract-plugin可以执行css和js分离。