webpackDefinePlugin 是经常使用的一个 plugin。它常常用来定义变量以区分环境。它的用法如下:

new webpack.DefinePlugin({
  'process.env': JSON.stringify("production"),
  debug: JSON.stringify(true)
})

一开始我以为它只是把这些变量挂在了全局变量下面,使得代码中能直接用变量,但是经过仔细查看,并不是这样的

工作原理

DefinePlugin 是一个 编译期 的变量替换工具。这意味它在 webpack 编译阶段就已完成了变量的替换工作,不会污染到全局变量。

这意味着,它是简单的变量替换为值,如上面的例子中,debug 变量 会被替换成 false

所以经常可以看到使用 JSON.stringify 将想要替换的内容包裹一层

Usage

利用这个特性和 uglify 可以实现 feature 等特性。例如关闭某个 feature ,就将其设为 false,最后 uglify 时就会将 dead code 自动剪除。

if (isDebug) {
  console.log("debug")
}
if (!isDebug) {
  console.log("production")
}

编译后代码:

console.log("production")    // uglify 自动剪除了 dead code

使用 eslint 时未声明的变量会报错,可在文件开头添加 /* global isDebug */ 设置全局变量的方式绕过

错误用法:

if (window.isDebug) {        // DefinePlugin 并不会替换 `isDebug`
  console.log('debug')
}

Reference

DefinePlugin 文档