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

1
2
3
4
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 自动剪除。

1
2
3
4
5
6
if (isDebug) {
  console.log("debug")
}
if (!isDebug) {
  console.log("production")
}

编译后代码:

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

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

错误用法:

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

Reference

DefinePlugin 文档