• webpack定制化 环境配置[开发环境、生产环境、前后端半分离环境]


    前提:
    webpack5及其对应配套内容
    node16.13.2

    webpack定制化 基础配置[基础、配置、初运行]
    webpack定制化 高级配置[热更新、热打包、别名、调试]
    webpack定制化 加载与插件[css加载器、html插件、image打包配置、babel代码兼容、vue加载器及配置]
    webpack定制化 优化提速[多进程、压缩、多js打包、多css打包、gzip]

    下文环境,已经配置好了的,一定先阅读README.md
    下载:阿里云盘百度网盘

    一.开发环境

    解释:这里通过4个文件,配置3个环境。原因是3个环境都有共同内容(直接把这个单独写一个文件,其它三个引用),这样写一个三个都能应用,方便管理,但需要安装一个包引入

    • 开发环境:使用热加载需要代码压缩、gzip等优化的配置,大大降低最终项目打包体积,但是速度慢;
    • 生产环境去除代码压缩、gzip、体积分析等优化的配置,大大提高构建速度生产环境只打包用到的代码,没用到的代码不打包
    • 前后端半分离环境:当内容更新后,打包到文件里面,便于后端引入模板

    安装:npm i webpack-merge -D #本文版本为5.8.0

    配置启动命令:
    pageage.json

      "scripts": {
        "serve": "webpack serve  --config webpack.development.js --env ISHOT=true",
        "watch": "webpack --watch --config webpack.half-combination.js --env ISHOT=false",
        "build": "webpack --config webpack.production.js --env ISHOT=false"
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1. 共用内容

    命名:webpack.config.js

    特殊:本文与其它人写的不同在于,引入了环境变量env.ISHOT,处理env需要下面这种函数式写法;里面有三处运用了三目运算符,来避免热更新BUG

    // 注意点,使用webpack-dev-server时,切记一切都要是默认路径,本配置由于不使用其的时候需要其它路径
    // 故使用env.ISHOT(来自pageage.json里面serve启动项)来分辨
    const path = require('path')// 路径配置
    const HtmlWebpackPlugin = require('html-webpack-plugin')// html打包
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')// css单独打包到某个位置
    const { VueLoaderPlugin } = require('vue-loader')// vue加载器
    
    module.exports = (env) => {
      return {
        // 入口
        entry: {
          main: './src/app/main.js',
          app: './src/app2/main.js'
        },
        // 输出
        output: {
          path: env.ISHOT === 'true' ? path.resolve(__dirname, './dist') : path.resolve(__dirname, './dist/static/js'),
          filename: 'ch-[name].[contenthash].js',
          // 每次打包前自动清除旧的dist
          clean: true,
        },
        plugins: [
          new VueLoaderPlugin(),
          // 多页面配置多个该插件,把html与生成的css和js链接导入
          new HtmlWebpackPlugin({
            template: './public/templates/index.html',
            filename: path.resolve(__dirname, './dist/templates/index.html'),
            // js文件插入 body里
            inject: 'body',
            chunks: ['main']// 对应多入口的main对象
          }),
          new HtmlWebpackPlugin({
            template: './public/templates/login.html',
            filename: path.resolve(__dirname, './dist/templates/login.html'),
            // js文件插入 body里
            inject: 'body',
            chunks: ['app']// 对应多入口的app对象
          }),
          // css插件,多个入口导入css只需像下面一样有动态参数即可
          new MiniCssExtractPlugin({
            filename: '../css/[name].css',// 以webpacke配置的js路径为当前路径
            ignoreOrder: true, // 忽视掉打包过程中出现的冲突警告
          }),
          
        ],
        module: {
          rules: [
            {
              test: /\.css$/,
              include: [path.resolve(__dirname, './public'),path.resolve(__dirname, './src')],
              use: env.ISHOT === 'true' ? [ 'style-loader','css-loader'] : [MiniCssExtractPlugin.loader, 'css-loader']
            },
            {
              test: /\.vue$/,
              exclude: /node_modules/,
              include: path.resolve(__dirname, './src'),
              use: 'vue-loader',
            },
            {
              test: /\.(png|jpe?g|gif|svg|webp)$/,
              include: path.resolve(__dirname, './public'),
              type: 'asset',
              generator: {
                // 打包到 指定目录 文件下 env.ISHOT来自pageage.json里面serve启动项
                filename: env.ISHOT === 'true' ? 'img/[contenthash][ext][query]' : '../img/[contenthash][ext][query]',//name表示文件名字为原名(可以用[contenthash]);ext表示. ;query表示请求资源的后缀(如png) // 以webpacke配置的js路径为当前路径
              },
            }
          ]
        },
        resolve: {
          // extensions:['.vue','.js','.json'],//引入这些文件 可以不带后缀 按顺序解析
          // 路径别名
          alias: {
            '@': path.resolve('./public'),
          },
        },
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    2. serve

    命名:webpack.development.js

    解释:需要箭头函数传递envwebpack.config.js文件里面去,因为在命令里面这最先被调用;由于上面的配置所以这里的base是函数

    注意:热加载环境不能使用mini-css-extract-plugin插件,再次提醒,上面配置文件已经用三目运算符解决

    // 本配置启动热更新,启动代码格式检查,map文件源码与位置双定位
    const { merge } = require('webpack-merge')// 合并配置文件用的
    const base = require('./webpack.config.js')// 大家共用的配置文件
    const ESLintPlugin = require('eslint-webpack-plugin')// 检测语法格式适配到webpack的插件
    const webpack = require('webpack')
    module.exports = (env) => merge(base(env), {
      mode: 'development',
      module: { rules: [] },
      plugins: [
        // 热替换插件
        new webpack.HotModuleReplacementPlugin(),
    ],
      devtool: 'eval-cheap-module-source-map',
      devServer: {
        host: '127.0.0.1',  // 配置启动ip地址
        port: 5002,  // 配置端口
        open: true,
        hot: true
        // static:'./dist',// 默认打开的是public文件夹,此处可自定
      },
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3. build

    命名:webpack.production.js

    解释:需要箭头函数传递envwebpack.config.js文件里面去,因为在命令里面这最先被调用;由于上面的配置所以这里的base是函数

    // 本配置启动js、css压缩、gzip压缩,以及多入口多文件的分离,相同的引入node_moudules单独的分离
    const path = require('path')// 路径设置
    const { merge } = require('webpack-merge')// 合并配置文件用的
    const base = require('./webpack.config.js')// 大家共用的配置文件
    const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')// 压缩css
    const TerserPlugin = require('terser-webpack-plugin')// 压缩js
    const CompressionPlugin = require('compression-webpack-plugin')// 压缩为gzip
    module.exports = (env) => merge(base(env), {
      mode: 'production',
      devtool: 'nosources-source-map',
      module: {
        rules: [
          {
            test: /\.js$/,
            include: path.resolve(__dirname, './src'),
            use: ['thread-loader', 'babel-loader'],
          },
        ]
      },
      plugins: [
        // gzip压缩
        new CompressionPlugin({
          algorithm: 'gzip',
          exclude: /\.(map|html)$/,
          threshold: 10240,// 大于10kb进行压缩
        })
      ],
      optimization: {
        minimizer: [
          new CssMinimizerPlugin(), // 去重压缩css
          new TerserPlugin({ // 压缩JS代码
            terserOptions: {
              compress: {
                drop_console: true, // 去除console
              },
            },
          }), 
        ],
        // 代码多入口导入相同的分离
        splitChunks: {
          chunks: 'all', // 可选值:all,async 和 initial。all功能最强大,所以咱们就使用all
          minSize: 20000, // 引入的模块大于20kb才做代码分割,官方默认20000,这里不用修改了
          // maxSize: 60000, // 若引入的模块大于60kb,则告诉webpack尝试再进行拆分
          cacheGroups: {
            vendors: {
              test: /[\\/]node_modules[\\/]/, // 使用正则匹配node_modules中引入的模块
              priority: -10, // 优先级值越大优先级越高,默认-10,不用修改
              name:'common',
            },
          },
        },
      },
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    4. watch

    命名:webpack.half-combination.js

    解释:需要箭头函数传递envwebpack.config.js文件里面去,因为在命令里面这最先被调用;由于上面的配置所以这里的base是函数

    // 本配置启动文件一保存,就以开发状态打包(不压缩速度快)更新内容(与热更新不同,此直接写入到文件)
    //,启动代码格式检测以及代码多入口导入,相同的引入node_moudules单独的分离
    const { merge } = require('webpack-merge')// 合并配置文件用的
    const base = require('./webpack.config.js')// 大家共用的配置文件
    const ESLintPlugin = require('eslint-webpack-plugin')// 检测语法格式适配到webpack的插件
    module.exports = (env) => merge(base(env), {
        mode: 'development',
        module: { rules: [] },
        plugins: [
            new ESLintPlugin({
                // 运行的时候自动帮你修复错误
                fix: true,
            })
        ],
        optimization: {
            // 代码多入口导入,相同的分离
            splitChunks: {
                chunks: 'all', // 可选值:all,async 和 initial。all功能最强大,所以咱们就使用all
                minSize: 20000, // 引入的模块大于20kb才做代码分割,官方默认20000,这里不用修改了
                // maxSize: 60000, // 若引入的模块大于60kb,则告诉webpack尝试再进行拆分
                cacheGroups: {
                    vendors: {
                        test: /[\\/]node_modules[\\/]/, // 使用正则匹配node_modules中引入的模块
                        priority: -10, // 优先级值越大优先级越高,默认-10,不用修改
                        name: 'common',
                    },
                },
            },
        },
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    结语:请把本系列都看完再投入开发环境,优化配置很重要

  • 相关阅读:
    Flow 3D学习记录
    解决谷歌Redux DevTools调试React+Typescript项目数据对不上/连接不上问题
    中石油大学22春季《大学英语(四)#》第三阶段在线作业
    互联网Java工程师面试题·Elasticsearch 篇·第二弹
    leaflet 示例教程100+ 目录
    Spring Boot与Shiro实现权限管理01
    ps提示由于找不到MSVCP140.dll是怎么回事?MSVCP140.dll修复方法
    MongoDB常用的比较符号和一些功能符号
    elasticsearch Docker启动Device or resource busy异常
    matlab 神经网络 ANN 分类
  • 原文地址:https://blog.csdn.net/weixin_46765649/article/details/126627271