《Webpack入门系列》DefinePlugin插件用法理解
作者:水涛
座右铭:天行健,君子以自强不息
自白:我写博文上来蹭蹭就是干,我突然觉得我需要幽默一点了,好了,下面我们说正经的
一、官方定义:
defineplugin
defineplugin
允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和生产模式的构建允许不同的行为非常有用。如果在开发构建中,而不在发布构建中执行日志记录,则可以使用全局常量来决定是否记录日志。这就是 defineplugin
的用处,设置它,就可以忘记开发环境和生产环境构建的规则。
new webpack.defineplugin({ // definitions... });
用法
每个传进 defineplugin
的键值都是一个标志符或者多个用 .
连接起来的标志符。
- 如果这个值是一个字符串,它会被当作一个代码片段来使用。
- 如果这个值不是字符串,它会被转化为字符串(包括函数)。
- 如果这个值是一个对象,它所有的 key 会被同样的方式定义。
- 如果在一个 key 前面加了
typeof
,它会被定义为 typeof 调用。
这些值会被内联进那些允许传一个代码压缩参数的代码中,从而减少冗余的条件判断。
new webpack.defineplugin({ production: json.stringify(true), version: json.stringify('5fa3b9'), browser_supports_html5: true, two: '1+1', 'typeof window': json.stringify('object'), 'process.env.node_env': json.stringify(process.env.node_env) });
console.log('running app version ' + version); if(!browser_supports_html5) require('html5shiv');
when defining values for
process
prefer'process.env.node_env': json.stringify('production')
overprocess: { env: { node_env: json.stringify('production') } }
. using the latter will overwrite theprocess
object which can break compatibility with some modules that expect other values on the process object to be defined.
注意,因为这个插件直接执行文本替换,给定的值必须包含字符串本身内的实际引号。通常,有两种方式来达到这个效果,使用
'"production"'
, 或者使用json.stringify('production')
。
二、个人分析
1、官网中说的“可以使用这个插件定义一些编译时的全局常量”
编译时这几个字很重要,webpack会根据配置文件将将入口文件解析、打包、转译为浏览器可识别的js文件最后输出到出口,而他转译的过程其实就是webpack编译过程,也就是官网说的编译时。
2、官网中说的“插件会直接替换文本”
> 在编译过程中(转译为浏览器可识别的js文件时),会将源文件中所有用到defineplugin中定义的常量的地方直接替换为对应的值文本,注意,是文本无论语义上是对象还是字符串还是函数,都直接作为文本替换过去。
示例1:
假设在配置文件中定义编译时全局常量 process.env.firstname
new webpack.defineplugin({ 'process.env.firstname': json.stringify("shuitao") });
源文件index.js内容如下
console.log(process.env.firstname)
最终转译后的js文件
console.log('shuitao')
可以看到,在编译生成新js文件时,将process.env.firstname
常量直接替换成了他对应的值文
示例2:
假设在配置文件中定义编译时全局常量 process.env.info
new webpack.defineplugin({ 'process.env.info': json.stringify({ name:'shuitao', age:23 }) });
源文件index.js内容如下
console.log(process.env.info)
最终转译后的js文件
console.log({ name:'shuitao', age:23 })
可以看到,在编译生成新js文件时,将process.env.info
常量直接替换成了他对应的值文本
示例3:
假设在配置文件中定义编译时全局常量 process.env.info
new webpack.defineplugin({ 'process.env.info': json.stringify({ name:'shuitao', age:23 }) });
源文件index.js内容如下
console.log(process.env); console.log(process.env.info);
最终转译后的js文件
console.log(process.env); console.log({ name:'shuitao', age:23 });
可以看到,在编译生成新js文件时,将process.env.info
常量直接替换成了他对应的值文本,而process.env
没有被替换,因为没有在defineplugin中定义process.env
运行最终转译后的js文件时,process.env
指向的是node中的process
,在process.env
中找不到info
属性,足以证明在defineplugin定义的process.env.info
和node
的process
没有任何关系,他只是一个在插件中定义的编译时的常量,编译后就已经被替换了,因此 理解清楚概念,他只是个编译时的常量,转译后就会被替换,只是恰好常量的名字是process.env.info