生产环境优化
开发环境注重开发效率,生产环境注重运行效率。
开发环境所使用的soucre map和HMR等webpack特性会 生成 或 向打包文件中添加 一些生产环境用不到的内容。
针对这个问题,webpack4推出了 模式(mode) 。
它提供了不同模式下的预设配置。
其中 production 模式内部开启了很多通用的优化功能。
同时,webpack也建议开发者为不同的工作环境创建不同的配置。
不同环境下的配置
方式1:配置文件根据环境不同,导出不同的配置(中小型项目)
webpack配置文件可以导出一个返回配置对象的函数(env,argv) => { return {...} }
。
函数接收两个参数:
env
接收cli命令中的环境名(--env
)参数
aegv
是cli命令中的所有参数
如此,就可以在函数中根据env
判断,对配置做调整。
也可以通过环境变量来判断。
这种方式只适合中小型项目,因为随着项目变得复杂,不同环境的配置也变得复杂起来,不方便在一个配置文件中去维护。
对于大型项目还是建议使用,一个环境对应一个配置文件的方式去维护。
方式2:一个环境对应一个配置文件(大型项目)
一般项目中会配置3个 环境的配置文件。其中两个用来适配不同的环境(dev/development、prod/production),另一个存放公共的配置(common/base)。
在dev和prod配置文件中,导入公共配置对象common并将其复制到当前导出的对象中,最后用当前环境的配置对象覆盖。
由于Object.assign()
是浅拷贝,使用它来覆盖公共配置是不合适的。
可以使用webpack-merge模块完成合并webpack配置的需求,它内部自动处理合并的逻辑。
由于现在没有默认的配置文件(webpack.config.js),所以需要使用--config
参数指定使用的配置文件。
例如:yarn webpack --config webpack.prod.js
可以将命令配置到package.json的scripts中。
DefinePlugin 插件 注入全局成员
DefinePlugin 插件用于为代码注入全局成员。
webpack 4 的 production 模式下,默认会启用这个插件,并且向代码中注入了一个process.env.NODE_ENV
的全局常量。
很多第三方的模块都是通过这个成员判断当前的运行环境,从而决定是否执行一些操作,例如:打印日志
DefinePlugin 插件接收一个对象,对象中的的key-value都会被注入到代码当中。
例如:
const webpack = require('webpack')
module.exports = {
plugins: [
new webpack.DefinePlugin({
// 全局注入一个API地址
API_BASE_URL: 'https://api.example.com',
// value应是一个符合JS语法的代码片段
// API_BASE_URL: '"https://api.example.com"'
// API_BASE_URL: JSON.stringify('https://api.example.com')
})
]
}
打包时,就会将API_BASE_URL
的值,**直接 **替换代码中的API_BASE_URL
。
开发时:console.log(API_BASE_URL)
打包后:console.log.(https://api.example.com)
由此可知,DefinePlugin定义的成员的值,实际上是一个符合JS语法的代码片段。
它会在打包时直接替换代码中的key。
所以API_BASE_URL
配置的值可以改为'"https://api.example.com"'
小技巧:如果value为一个值,可以通过JSON.stringify()
将其转换成一个表示这个值的代码片段。
DefinePlugin 插件可以用于针对不同的环境注入对应的全局成员。