使用mini-css-extract-plugin插件来打包css文件(从css文件中提取css代码到单独的文件中,对css代码进行代码压缩等)。
本次采用三个配置文件:
webpack-merge
插件,可以merge到开发或生产环境,从而减少重复配置。process.env.NODE_ENV
,可以根据传入的环境参数,动态更改配置,具体请看代码。npm i -D mini-css-extract-plugin webpack-merge html-webpack-plugin
- const HtmlWebpackPlugin = require("html-webpack-plugin");
- const MiniCssExtractPlugin = require("mini-css-extract-plugin");
- const devMode = process.env.NODE_ENV != "production"
- const path = require('path');
-
- module.exports = {
- entry: './src/index.js',
- devServer: {
- static: '/dist'
- },
- module: {
- rules: [
- {
- test: /\.(sa|sc|c)ss$/, // 可以打包后缀为sass/scss/css的文件
- use: [
- {
- loader: MiniCssExtractPlugin.loader,
- options: {
- // 指定一个 publicPath,默认使用 webpackOptions.output中的publicPath
- // publicPath的配置,和plugins中设置的filename和chunkFilename的名字有关
- // 如果打包后,background属性中的图片显示不出来,请检查publicPath的配置是否有误
- // publicPath: './src',
- publicPath: devMode ? './src' : './src', // 根据不同环境指定不同的publicPath
- },
- },
- 'css-loader',
- // 'sass-loader'
- ],
- },
- ]
- },
- plugins: [
- // 创建了一个全新的html文件,所有的 bundle 都自动添加到其中。
- new HtmlWebpackPlugin({
- title: 'development'
- }),
- // css代码分离
- new MiniCssExtractPlugin({
- // 这里的配置和webpackOptions.output中的配置相似
- // 即可以通过在名字前加路径,来决定打包后的文件存在的路径
- filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
- chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',
- })
- ],
- output: {
- filename: '[name].bundle.js',
- path: path.resolve(__dirname, 'dist'),
- // 每次构建前清理 /dist 文件夹
- clean: true,
- },
- optimization: {
- // 进行代码分离
- splitChunks: {
- chunks: 'all',
- },
- }
- }
mode
设置为development
模式,否则webpack4以后会默认为production
模式。npm i -D webpack-merge
注意引入merge是使用 { merge } 形式:
- const { merge } = require("webpack-merge");
- const common = require("./webpack.common");
-
- module.exports = merge(common, {
- // dev环境的配置,记得把mode设置为development模式,否则webpack会默认为production模式。
- mode: "development",
- // 可以将编译后的代码映射回原始源代码,便于追踪 error 和 warning(浏览器中打开生成的 index.html 文件,点击按钮后控制台将会报错)
- devtool: 'inline-source-map',
- });
optimize-css-assets-webpack-plugin
插件可以对css进行压缩,与此同时,必须指定js压缩插件(例子中使用terser-webpack-plugin
插件),否则webpack不再对js文件进行压缩;(webpack5中不再支持optimize-css-assets-webpack-plugin
插件而是使用css-minimizer-webpack-plugin)optimization.splitChunks.cacheGroups
,可以将css代码块提取到单独的文件中。- const { merge } = require("webpack-merge");
- const common = require("./webpack.common");
- // 生成环境下对JS进行压缩
- const TerserJSPlugin = require('terser-webpack-plugin');
- // 生成环境下对CSS进行压缩
- const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
-
- module.exports = merge(common, {
- // dev环境的配置,记得把mode设置为development模式,否则webpack会默认为production模式。
- mode: "production",
- devtool: 'source-map',
- optimization: {
- minimizer: [new TerserJSPlugin({}), new CssMinimizerWebpackPlugin({})],
- splitChunks: {
- cacheGroups: {
- styles: {
- name: 'styles',
- test: /\.css$/,
- chunks: 'all',
- enforce: true,
- },
- }
- },
- }
- });
和dev环境同样的配置会报以下警告,页面也渲染不出来:
使用css-minimizer-webpack-plugin和terser-webpack-plugin
插件也无法正常启动
解决:
是因为使用了devtool:"inline-source-map"选项配置后报警告,改为devtool:"source-map"后启动正常
sideEffects
,某些通过import
方式引入的css文件可能不会被打包,因为tree-shaking会甩掉没有导出任何东西(即文件中没有export关键字)的文件。所以,不希望被tree-shaking的文件,请在sideEffects
中配置与之匹配的正则表达式(如下,在package.json中添加)。NODE_ENV
传入环境变量。例如:"script":{ "dev": "set NODE_ENV=development && webpack serve --open --config ./webpack.dev.js --mode=development"})。- {
- "sideEffects": [
- "*.css",
- "*.scss",
- "*.sass"
- ],
- "scripts": {
- "dev": "set NODE_ENV=development && webpack serve --open --config ./webpack.dev.js --mode=development",
- "prod": "set NODE_ENV=production && webpack serve --open --config ./webpack.prod.js --mode=production"
- },
- }
publicPath
的配置。mode: 'production'
会开启tree-shaking和js代码压缩,但配置optimization. minimizer
会使默认的压缩功能失效。所以,指定css压缩插件的同时,务必指定js的压缩插件。mini-css-extract-plugin
插件,结合optimization.splitChunks.cacheGroups
配置,可以把css代码打包到单独的css文件,且可以设置存放路径(通过设置插件的filename
和chunkFilename
)。