1.不使用mock的那部分假数据,总不能放在代码里发布生产环境吧?
2.debug工具代码,如移动端比较流行的vconsole插件,我们不希望测试前引入这份代码,发布生产的时候手动关闭这部分代码吧,我们需要一个开关的功能去自动化引入和移除。
…
遇到以上这些情况,正是需要条件编译这个功能。
if (false) {
do somthing...
}
如上面场景2,需要一个开关自动切换debug工具代码注入和移除。可以在工程上注入环境变量来作为开关,如下配置:
"scripts": {
"dev": "node build/dev-server.js",
"build": "node build/build.js",
"build:test": "cross-env BUILD_ENV=test node build/build.js",
},
在UglifyJsPlugin加上dead_code属性
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_debugger: true,
dead_code: true,
},
comments: false,
beautify: false,
sourceMap: false
}),
在DefinePlugin注入js可使用的node变量
new webpack.DefinePlugin({
DEBUG: JSON.stringify(process.env.BUILD_ENV=='test'),
}),
怎么在前端js代码中使用这个开关?
if (DEBUG) {
const vConsole = require('vconsole')
new vConsole();
}
我们做个实验,证明以上做法能做到条件编译。
//测试环境,需要debug工具
npm run build:test
总所周知,node_modules中引入的包,webpack默认都会打到一个vendor.js的文件里,我们搜索一下vconsole插件是否注入,如下。
//生产环境,不需要debug工具
npm run build
我们继续看下输出的公共包
确实没被引入,至此证明可以做到条件编译。
总结:
步骤一:根据发布环境(test?production?)在node中通过DefinePlugin定义一个可以在前端js中引用的变量(DEBUG,随便命名),作为开关。(引入条件关键词)
步骤二:通过if语句使用这个开关做一些事情。(条件编译)
步骤三:使用UglifyJsPlugin的compress.dead_code=true,在打包扫描代码初阶段(未进入依赖包构建阶段)去除死代码。 (执行代码块的注入或移除)
简单粗暴,步骤一:
//wepack中设置loader
{
test: /\.jsx?$/,
use: [
{
loader: 'js-conditional-compile-loader',
options: {
isDebug: process.env.BUILD_ENV=='test'
}
}
]
},
步骤二:
//注释般写入代码
/*IFDEBUG
let vConsole = require('vconsole')
new vConsole()
FIDEBUG*/