• webpack不同环境下使用CSS分离插件mini-css-extract-plugin


    1.背景描述

    使用mini-css-extract-plugin插件来打包css文件(从css文件中提取css代码到单独的文件中,对css代码进行代码压缩等)。

    本次采用三个配置文件

    • 公共配置文件:webpack.common.js
    • dev开发环境配置文件:webpack.dev.js
    • prod生产环境配置文件:webpack.prod.js

    2.webpack.common.js (公共配置文件)

    • 开发环境和生产环境共用的配置,借助webpack-merge插件,可以merge到开发或生产环境,从而减少重复配置。
    • 引入了Node环境变量process.env.NODE_ENV,可以根据传入的环境参数,动态更改配置,具体请看代码。
    npm i -D mini-css-extract-plugin webpack-merge html-webpack-plugin
    1. const HtmlWebpackPlugin = require("html-webpack-plugin");
    2. const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    3. const devMode = process.env.NODE_ENV != "production"
    4. const path = require('path');
    5. module.exports = {
    6. entry: './src/index.js',
    7. devServer: {
    8. static: '/dist'
    9. },
    10. module: {
    11. rules: [
    12. {
    13. test: /\.(sa|sc|c)ss$/, // 可以打包后缀为sass/scss/css的文件
    14. use: [
    15. {
    16. loader: MiniCssExtractPlugin.loader,
    17. options: {
    18. // 指定一个 publicPath,默认使用 webpackOptions.output中的publicPath
    19. // publicPath的配置,和plugins中设置的filename和chunkFilename的名字有关
    20. // 如果打包后,background属性中的图片显示不出来,请检查publicPath的配置是否有误
    21. // publicPath: './src',
    22. publicPath: devMode ? './src' : './src', // 根据不同环境指定不同的publicPath
    23. },
    24. },
    25. 'css-loader',
    26. // 'sass-loader'
    27. ],
    28. },
    29. ]
    30. },
    31. plugins: [
    32. // 创建了一个全新的html文件,所有的 bundle 都自动添加到其中。
    33. new HtmlWebpackPlugin({
    34. title: 'development'
    35. }),
    36. // css代码分离
    37. new MiniCssExtractPlugin({
    38. // 这里的配置和webpackOptions.output中的配置相似
    39. // 即可以通过在名字前加路径,来决定打包后的文件存在的路径
    40. filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
    41. chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',
    42. })
    43. ],
    44. output: {
    45. filename: '[name].bundle.js',
    46. path: path.resolve(__dirname, 'dist'),
    47. // 每次构建前清理 /dist 文件夹
    48. clean: true,
    49. },
    50. optimization: {
    51. // 进行代码分离
    52. splitChunks: {
    53. chunks: 'all',
    54. },
    55. }
    56. }

    3.webpack.dev.js(dev环境的配置文件)

    • dev环境的配置,记得把mode设置为development模式,否则webpack4以后会默认为production模式。
    npm i -D webpack-merge

    注意引入merge是使用 { merge } 形式:

    1. const { merge } = require("webpack-merge");
    2. const common = require("./webpack.common");
    3. module.exports = merge(common, {
    4. // dev环境的配置,记得把mode设置为development模式,否则webpack会默认为production模式。
    5. mode: "development",
    6. // 可以将编译后的代码映射回原始源代码,便于追踪 error 和 warning(浏览器中打开生成的 index.html 文件,点击按钮后控制台将会报错)
    7. devtool: 'inline-source-map',
    8. });

    4.webpack.prod.js(生产环境的配置文件)

    • 生产环境的配置,默认开启tree-shaking和js代码压缩;
    • 通过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代码块提取到单独的文件中。
    • 注意生产环境必须使用devTool:'source-map',否则报警告页面渲染不出来
    1. const { merge } = require("webpack-merge");
    2. const common = require("./webpack.common");
    3. // 生成环境下对JS进行压缩
    4. const TerserJSPlugin = require('terser-webpack-plugin');
    5. // 生成环境下对CSS进行压缩
    6. const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
    7. module.exports = merge(common, {
    8. // dev环境的配置,记得把mode设置为development模式,否则webpack会默认为production模式。
    9. mode: "production",
    10. devtool: 'source-map',
    11. optimization: {
    12. minimizer: [new TerserJSPlugin({}), new CssMinimizerWebpackPlugin({})],
    13. splitChunks: {
    14. cacheGroups: {
    15. styles: {
    16. name: 'styles',
    17. test: /\.css$/,
    18. chunks: 'all',
    19. enforce: true,
    20. },
    21. }
    22. },
    23. }
    24. });

    和dev环境同样的配置会报以下警告,页面也渲染不出来:

    使用css-minimizer-webpack-plugin和terser-webpack-plugin插件也无法正常启动

    解决:

    是因为使用了devtool:"inline-source-map"选项配置后报警告,改为devtool:"source-map"后启动正常

    5.package.json配置文件

    • sideEffects: 生产环境打包的时候,会默认开启tree-shaking,如果不设置sideEffects,某些通过import方式引入的css文件可能不会被打包,因为tree-shaking会甩掉没有导出任何东西(即文件中没有export关键字)的文件。所以,不希望被tree-shaking的文件,请在sideEffects中配置与之匹配的正则表达式(如下,在package.json中添加)。
    • NODE_ENV: 由于项目中用到了Node的环境变量,所以打包时需通过NODE_ENV传入环境变量。例如:"script":{ "dev": "set NODE_ENV=development && webpack serve --open --config ./webpack.dev.js --mode=development"})。
    1. {
    2. "sideEffects": [
    3. "*.css",
    4. "*.scss",
    5. "*.sass"
    6. ],
    7. "scripts": {
    8. "dev": "set NODE_ENV=development && webpack serve --open --config ./webpack.dev.js --mode=development",
    9. "prod": "set NODE_ENV=production && webpack serve --open --config ./webpack.prod.js --mode=production"
    10. },
    11. }

    6.总结:

    • 不同环境下的打包,如果出现图片显示不了时(特别是css中的图片),请检查publicPath的配置。
    • mode: 'production'会开启tree-shaking和js代码压缩,但配置optimization. minimizer会使默认的压缩功能失效。所以,指定css压缩插件的同时,务必指定js的压缩插件。
    • mini-css-extract-plugin插件,结合optimization.splitChunks.cacheGroups配置,可以把css代码打包到单独的css文件,且可以设置存放路径(通过设置插件的filenamechunkFilename)。
    • 生产环境下不能使用devtool:"inline-source-map",而用devtool:"source-map"

    参考:mini-css-extract-plugin插件快速入门_mn_front的博客-CSDN博客

  • 相关阅读:
    Django测试与持续集成:从入门到精通
    springboot使用redis实现消息队列功能,redis使用list和stream实现消息队列功能,redis实现消息队列的风险点分析
    Hadoop实训有谁会做有尝
    VUE3照本宣科——内置指令与自定义指令及插槽
    LeetCode(1)合并两个有序数组【数组/字符串】【简单】
    vue前端实现多个url下载并合并为zip文件
    lodash已死?Radash库方法介绍及源码解析 —— 异步方法篇
    全局指令选择
    【面试专线】【基础知识】【JAVA】基础(三)(简答版)
    图解|用好MySQL索引,你需要知道的一些事情
  • 原文地址:https://blog.csdn.net/qq_34569497/article/details/133707547