webpack4.x中關於css-loader的幾個坑
阿新 • • 發佈:2018-12-21
本文主要記錄筆者在webpack4.x專案下使用css-loader管理css踩到的坑(下面用一個逐步修改的示例來說明)。
專案的初始訴求是使用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)}
此時編譯失敗,會提示檔案型別無法識別,需要其他的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引入的(同時這樣處理會有效能問題),且沒有和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分離。