webpack+vite前端构建工具 -11实战中的配置技巧

11 实战中的配置技巧

11.1 环境区分

11.1.1 为什么要区分环境

  • 生产模式
    • 需要:代码压缩,tree-shaking
    • 不需要:详细的source-map,开启开发模式
  • 开发模式
    • 需要:详细的source-map,开启开发模式
    • 不需要:代码压缩,代码混淆等

11.1.2 环境区分要点

  • 区分要点
    • 根据不同环境进行打包,一般在process.env设置
    • 有时需要在js代码中获取环境,可以借助插件完成

11.1.3 不同环境不同配置文件webpack.xxxconfig.js

  • 生产模式和开发模式相同的webpack配置放到webpack.baseconfig.js里
  • 开发模式的webpack配置放到webpack.devconfig.js
  • 生产模式的webpack配置放到webpack.proconfig.js
配置文件
javascript 复制代码
// webpack.baseconfig.js
const htmlwebpack = require('html-webpack-plugin');
module.exports = {
    entry: {  // 多入口写法:入口名称+入口文件
        app: ["./app.js"]
    },
    output: {
        path: __dirname + '/dist', // 绝对路径,__dirname是node的全局变量,表示当前目录的绝对路径
        filename: "[name].[chunkhash:4].bundle.js", //将name加到filename里,打包结果文件是app.bundle.js和app2.bundle.js,hash是对文件是否有改变的标志,:4表示截取前4位
        publicPath: "www.xx.com"
    },
    // loader
    module: {
        rules: [
            {
                // 每个对象是一个loader
                test: /\.js$/,
                use: {
                    loader: 'babel-loader'
                }
            }
        ]
    },
    plugins: [
        new htmlwebpack({
            template: './index.html',// 写法1,指定html模板
            filename: "index.html"
        })
    ],

    resolve: {
    },
    optimization: {
    }
}
javascript 复制代码
// webpack.devconfig.js
const base = require("./webpack.baseconfig.js");
const merge = require("webpack-merge").merge;
module.exports = merge(base, {
    mode: "development",
    devServer: {
        port: 2000,
        hot: true,//热更新
    }
});
javascript 复制代码
// webpack.proconfig.js
const base = require("./webpack.baseconfig.js");
const merge = require("webpack-merge").merge;
module.exports = merge(base, {
    mode: "production"
});
打包命令

打包命令

json 复制代码
{
  "name": "webpackDemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config ./webpack.proconfig.js",
    "dev": "webpack-dev-server --config ./webpack.devconfig.js"
  }
}
打包结果

打生产包

命令:npm run build

结果

本地项目启动

命令:npm run dev

前端项目按照不同的环境划分不同的配置,按照不同的脚本进行打包。

理解平时npm run build,npm run dev的本质。

11.1.4 环境判断 cross-env

通过node脚本指令指定环境变量。

1 安装cross-env

安装cross-env的包,命令npm install cross-env --save-dev

2 node脚本指令

脚本指令cross-env NODE_ENV=development

json 复制代码
// package.json
{
  "name": "webpackDemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "cross-env NODE_ENV=production webpack --config ./webpack.proconfig.js",
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./webpack.devconfig.js" 
  },
}

配置文件里打印下NODE_ENV的值process.env.NODE_ENV

javascript 复制代码
// webpack.baseconfig.js
const htmlwebpack = require('html-webpack-plugin');
console.log(process.env.NODE_ENV)
module.exports = {
...
}
3 打包

npm run build

4 应用

根据NODE_ENV的值判断当前环境,使用相应的loader.

javascript 复制代码
// webpack.baseconfig.js
const htmlwebpack = require('html-webpack-plugin');
console.log(process.env.NODE_ENV)
module.exports = {
    entry: {  // 多入口写法:入口名称+入口文件
        app: ["./app.js"]
    },
    output: {
        path: __dirname + '/dist', // 绝对路径,__dirname是node的全局变量,表示当前目录的绝对路径
        filename: "[name].[chunkhash:4].bundle.js", //将name加到filename里,打包结果文件是app.bundle.js和app2.bundle.js,hash是对文件是否有改变的标志,:4表示截取前4位
        publicPath: "www.xx.com"
    },
    // loader
    module: {
        rules: [
            {
                // 每个对象是一个loader
                test: /\.css$/,
                use: [
                    process.env.NODE_ENV === 'production' ? minicss.loader : 'style-loader', 'css-loader'
                ]
            }
        ]
    },
}

此外,对于不好处理的配置,可以用变量存储根据环境变化的配置,然后配置到module.exports的对象中。此处不赘述。------编程式配置

11.1.5 webpack指令

通过webpack本身指令做环境判断的方案。

11.1.5.1 webpack --help

webpack --help

只要在命令行运行的工具,都有--help查看帮助的指令

执行结果如下。

如--config后可以跟一个config文件,还有--env<value...>

11.1.5.2 webpack --env
1 指定env
javascript 复制代码
// package.json
{
  "name": "webpackDemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack --config ./webpack.proconfig.js --env production",
   }
}
2 config文件接收env

env作为方法入参传给config文件。

因此exports出去的是一个方法,入参为env,这个方法return一个merge方法。

javascript 复制代码
// webpack.proconfig.js
const base = require("./webpack.baseconfig.js");
const merge = require("webpack-merge").merge;
// module.exports = merge(base, {
//     mode: "production"
// });
module.exports = function (env) {
    return merge(base(env), {
        mode: "production"
    })
}

实际用到env的是baseconfig,因此还需要作为入参传给base方法,即baseconfig export出来的也需要是一个方法。

当然baseconfig也是return一个对象。

javascript 复制代码
const htmlwebpack = require('html-webpack-plugin');
console.log(process.env.NODE_ENV)
module.exports = function (env) {
    console.log("🚀 ~ env:", env)
    return {
        entry: {
            app: ["./app.js"]
        },
        output: {
            path: __dirname + '/dist',
            filename: "[name].[chunkhash:4].bundle.js",
            publicPath: "www.xx.com"
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    use: {
                        loader: 'babel-loader'
                    }
                },
                {
                    test: /\.css$/,
                    use: [
                        process.env.NODE_ENV === 'production' ? minicss.loader : 'style-loader', 'css-loader'
                    ]
                }
            ]
        },
        plugins: [
            new htmlwebpack({
                template: './index.html',
                filename: "index.html"
            })
        ]
    }
}
// module.exports = {
//     entry: {  // 多入口写法:入口名称+入口文件
//         app: ["./app.js"]
//     },
//     output: {
//         path: __dirname + '/dist', // 绝对路径,__dirname是node的全局变量,表示当前目录的绝对路径
//         filename: "[name].[chunkhash:4].bundle.js", //将name加到filename里,打包结果文件是app.bundle.js和app2.bundle.js,hash是对文件是否有改变的标志,:4表示截取前4位
//         publicPath: "www.xx.com"
//     },
//     // loader
//     module: {
//         rules: [
//             {
//                 // 每个对象是一个loader
//                 test: /\.js$/,
//                 use: {
//                     loader: 'babel-loader'
//                 }
//             },
//             {
//                 // 每个对象是一个loader
//                 test: /\.css$/,
//                 use: [
//                     process.env.NODE_ENV === 'production' ? minicss.loader : 'style-loader', 'css-loader'
//                 ]
//             }
//         ]
//     },
//     plugins: [
//         new htmlwebpack({
//             template: './index.html',// 写法1,指定html模板
//             filename: "index.html"
//         })
//     ]
// }
3 打包

npm run build

复制代码
"build": "webpack --config ./webpack.proconfig.js --env production",这里env也可以指定为其他内容
4 总结

webpack --env配置并不方便,需要修改config.js的export的方法。

11.1.6 webpack的DefinePlugin插件

给业务代码提供环境变量。

11.2 优化相关

11.2.1 优化webpack打包速度

  • 打包分析
    • 官方方案,--json输出打包结果分析json ------ 不推荐
    • webpack-bundle-analyzer
1 获取json的方式
1 配置命令

在package.json的scripts里配置指令--json>stats.json

json 复制代码
    "getjson": "cross-env NODE_ENV=production webpack --config ./webpack.proconfig.js --json>stats.json"
2 运行指令

npm run getjson

执行结果,生成一个stats.json文件。

3 json分析

如果https://webpack.js.org/analyse/网站可以加载,上传2生成的json文件,即可出现分析结果。

webpack官方文档: https://webpack.js.org/

json分析:https://webpack.js.org/analyse/

anyway,我们来看后面的方案。

2 webpack-bundle-analyzer
1 安装webpack-bundle-analyzer

npm install webpack-bundle-analyzer --save-dev

2 引入并注册插件
javascript 复制代码
const webpackbundleanalyzer = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = {
    plugins: [
        new webpackbundleanalyzer()
    ]
}
3 打包

npm run build

打包完成后自动打开一个网站。

通过下图可以看出打包出一个app.js,包括lodash.js文件。

4 结果分析

可以了解项目的引用关系,以及文件的大小。在大型项目里可以发现较大的模块,以优化打包的体积。

  • start:原始大小
  • Parsed:压缩大小
  • Gzipped:压缩大小

3 提升打包速度

如何提升打包速度。

1 dll优化
  • 提前打包不变的包(例如第三方库)
  • 通知到正式打包
  • dll处理过的不再处理

需要手动在index.html引入提前打的不变的包

p10 33:00

4 减小包体积
  • 压缩程度
    • webpack能做到的极致压缩,不只是代码上的物理压缩(压缩为一行代码),而是直接输出最终执行的代码。
    • webpack还可以混淆代码,如语义化的变量用a b c代替,避免上线后代码被窃取。
  • 打包
    • 引入某个有100个方法的库,只用到f1方法,应该只将f1方法打包进来------最节省代码体积的做法。

引入了lodash,vue,axios这些包,一般不会用到这些包里的所有方法,只会用到一部分

那么可以将用到的方法进行打包,用不到的方法不会打包进来。

  • 打包局限性
    • 在类上定义的方法,会全部被打包。
  • 如何不会全部被打包
    • 单独定义方法然后export 单个方法(js文件里每个方法单独export)
    • 然后用到f1方法就只引入f1方法
相关推荐
passerby60619 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了9 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅9 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅10 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment10 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅10 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊10 小时前
jwt介绍
前端
爱敲代码的小鱼10 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
Cobyte10 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc