前言
如今的前端项目,不管是开发还是上线,都避免不了在打包时判断一下打包环境,来针对开发或者生产做不同的打包配置,那么不修改 process.env.NODE_ENV 或设置 webpack --env,还能做判断吗?
实践
在阅读 only-allow 源码 时,我发现作者是通过whichPMRuns获取包管理器的
其内部逻辑为:
function whichPMRuns() {
if (!process.env.npm_config_user_agent) {
return undefined
}
return pmFromUserAgent(process.env.npm_config_user_agent)
}
function pmFromUserAgent (userAgent) {
const pmSpec = userAgent.split(' ')[0]
const separatorPos = pmSpec.lastIndexOf('/')
const name = pmSpec.substring(0, separatorPos)
return {
name: name === 'npminstall' ? 'cnpm' : name,
version: pmSpec.substring(separatorPos + 1)
}
}
在我的项目里面打印一下 process.env,发现一些 npm 相关变量:
{
"npm_config_email": "xxx",
"npm_package_scripts_dev": "webpack serve --env development",
"npm_config___xnpm_ximalaya_com__always_auth": "",
"npm_package_sideEffects": "false",
"npm_config_registry": "https://registry.npmmirror.com/",
"npm_config_home": "https://npmmirror.com",
"npm_package_description": "",
"npm_package_license": "ISC",
"npm_config_set": "registry",
"npm_execpath": "/Users/xmly/.local/share/fnm/node-versions/v20.16.0/installation/lib/node_modules/pnpm/bin/pnpm.cjs",
"npm_config_frozen_lockfile": "",
"npm_config_http___xnpm_ximalaya_com": "",
"npm_package_name": "web",
"npm_package_scripts_build": "webpack --env production",
"npm_config_config": "set",
"npm_lifecycle_script": "webpack --env production",
"npm_lifecycle_event": "build",
"npm_config_user_agent": "pnpm/9.12.2 npm/? node/v20.16.0 darwin arm64",
}
其中:
- npm_config_user_agent: 包含了包管理器信息
- npm_lifecycle_event: 指调用的 scripts
- npm_lifecycle_script: 调用的 scripts 对应的脚本
于是,我完全可以通过 npm_lifecycle_event 或 npm_package_scripts_build 判断是开发环境还是生产环境
例如,在 webpack.config.js 中:
/**
* @returns {import("webpack").Configuration}
*/
export default () => {
const isDev = /dev|start/i.test(process.env.npm_lifecycle_event);
process.env.NODE_ENV = isDev ? 'development' : 'production';
const mode = isDev ? 'development' : 'production';
const stats = isDev ? 'errors-warnings' : 'normal';
const devtool = isDev ? 'inline-source-map' : false;
return {
mode,
devtool,
stats,
...
};
};
只要判断是否调用了 start 或 dev 命令,就可以判断是否为开发环境
同理,也可以通过 npm_lifecycle_script 来判断,如果脚本中包含 devServer,就是开发环境
不过有些依赖包是通过 process.env.NODE_ENV 来判断环境的,还是需要显性地更改一下