1. 程式人生 > >webpack4.x中關於css-loader的幾個坑

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

本文主要記錄筆者在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分離。