Webpack
中文:
MiniCssExtractPlugin | webpack 中文文档
不打印style
页面不会有样式,因为我们在package.json
代码中配置过Tree Shaking
(不使用的代码不会引入,而css
文件没有导出,所以页面不会有效果):
import style from "./index.css";
console.log(style)
body{
background-color: gray;
}
更改排除package.json
文件:
{
"scripts": {
"dev": "webpack serve --open --config ./build/webpack.dev.js",
"build:stage": "webpack --config ./build/webpack.dev.js",
"build:test": "webpack --json > stats.json",
"build": "webpack --config ./build/webpack.prod.js"
},
// 排除 .css 文件
"sidEffects": ["*.css"],
}
以上代码js
文件加载了css
文件,这个时候运行npm run build
后可以看到页面确实被改变了背景色,但是dist
文件夹下面却没有看到css
的文件,这是因为webpack
把css
文件都打包到了js
文件中。
样式抽离
项目开发中,我们希望css
文件能单独存在,我们可以使用Webpack
提供的的插件MiniCssExtractPlugin
。
安装:
$ npm install --save-dev mini-css-extract-plugin
删除对css
文件和scss
文件的loader
:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: {
main: "./src/index.js",
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "../dist"),
},
module: {
rules: [
/*{
test: /\.scss$/,
use: ["style-loader", {
loader: "css-loader",
options: {
importLoaders: 2,
modules: true
}
}, "sass-loader", "postcss-loader"]
},
{
test: /\.css$/,
use: ["style-loader", "css-loader", "postcss-loader"]
}, */
{
test: /\.jpg|.jpeg|.png$/,
use: {
loader: "url-loader",
options: {
limit: 54000,
name: "[name].[ext]",
outputPath: "/images",
}
}
}, {
test: /\.m?js$/,
exclude: /node_modules/, // 排除node_modules下的代码
use: {
loader: "babel-loader"
}
}]
},
optimization: {
// TreeShaking 的配置
usedExports: true,
// SplittingCode 的配置
splitChunks: {
chunks: 'all', // 分割引入代码库的方式,默认为 async 异步,可选 all:同步和异步
},
},
plugins: [
// 自动引入打包好的js文件
new HtmlWebpackPlugin({
template: "./src/index.html"
}),
// 清除dist文件夹
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [
path.resolve(__dirname, '../dist')
],
}),
],
}
对测试环境的配置文件增加对css
文件和scss
文件的loader
:
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.common.js");
const devConfig = {
mode: "development",
devtool: "eval-cheap-module-source-map",
devServer: {
contentBase: "./dist",
open: true,
hot: true,
hotOnly: true
},
module: {
// 新增 .scss 和 .css 的 loader
rules: [{
test: /\.scss$/,
use: ["style-loader", {
loader: "css-loader",
options: {
importLoaders: 2,
modules: true
}
}, "sass-loader", "postcss-loader"]
},{
test: /\.css$/,
use: ["style-loader", "css-loader", "postcss-loader"]
}]
}
}
module.exports = merge(commonConfig, devConfig);
对生产环境的配置文件增加对css
文件和scss
文件的loader
,使用MiniCssExtractPlugin.loader
替换掉style-loader
,对plugins
进行配置:
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.common.js");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const prodConfig = module.exports = {
mode: "production",
devtool: "cheap-module-source-map",
module: {
rules: [{
test: /\.scss$/,
// 删除 style-loader 替换为 MiniCssExtractPlugin.loader
use: [MiniCssExtractPlugin.loader, {
loader: "css-loader",
options: {
importLoaders: 2,
modules: true
}
}, "sass-loader", "postcss-loader"]
}, {
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"]
}]
},
plugins: [new MiniCssExtractPlugin()]
}
module.exports = merge(commonConfig, prodConfig);
更改sideEffects
的配置,忽略scss
文件和css
文件的导出(因为这两个是样式文件,没有导出):
{
"sideEffects": [
"*.scss",
"*.css"
],
// ...
}
这个时候运行npm run build
就能看到css
文件被打包分离出来。
更多配置项:
MiniCssExtractPlugin | webpack 中文文档
更多高级用法:
MiniCssExtractPlugin | webpack 中文文档
代码压缩
MiniCssExtractPlugin
是不支持代码压缩和多css
文件合并的,所以还需要借助另外一个插件css-minimizer-webpack-plugin
。
安装:
$ npm install css-minimizer-webpack-plugin -D
配置optimization.minimizer
:
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.common.js");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const prodConfig = module.exports = {
mode: "production",
devtool: "cheap-module-source-map",
// optimization表示优化
optimization: {
// 压缩css文件代码
minimizer: [new CssMinimizerPlugin()]
},
module: {
rules: [{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader, {
loader: "css-loader",
options: {
importLoaders: 2,
modules: true
}
}, "sass-loader", "postcss-loader"]
}, {
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"]
}]
},
plugins: [
new MiniCssExtractPlugin({
// 直接被引入到 html 的link标签中被命名为 name.hash.js
filename: "[name].[hash].css",
// 间接被引入的css被命名为 name.chunk.hash.js
chunkFilename:"[name].chunk.[hash].css"
})
]
}
module.exports = merge(commonConfig, prodConfig);