webpack学习笔记--区分环境
在开发网页的时候,一般都会有多套运行环境,例如:
- 在开发过程中方便开发调试的环境。
- 发布到线上给用户使用的运行环境。
这两套不同的环境虽然都是由同一套源代码编译而来,但是代码内容却不一样,差异包括:
- 线上代码被通过 4-8 压缩代码 中提到的方法压缩过。
- 开发用的代码包含一些用于提示开发者的提示日志,这些日志普通用户不可能去看它。
- 开发用的代码所连接的后端数据接口地址也可能和线上环境不同,因为要避免开发过程中造成对线上数据的影响。
为了尽可能的复用代码,在构建的过程中需要根据目标代码要运行的环境而输出不同的代码,我们需要一套机制在源码中去区分环境。 幸运的是 Webpack 已经为我们实现了这点。
如何区分环境
具体区分方法很简单,在源码中通过如下方式:
if (process.env.NODE_ENV === 'production') {
console.log('你正在线上环境');
} else {
console.log('你正在使用开发环境');
}
其大概原理是借助于环境变量的值去判断执行哪个分支。
当你的代码中出现了使用 process 模块的语句时,Webpack 就自动打包进 process 模块的代码以支持非 Node.js 的运行环境。 当你的代码中没有使用 process 时就不会打包进 process 模块的代码。这个注入的 process 模块作用是为了模拟 Node.js 中的 process,以支持上面使用的 process.env.NODE_ENV === 'production' 语句。
在构建线上环境代码时,需要给当前运行环境设置环境变量 NODE_ENV = 'production' ,Webpack 相关配置如下:
const DefinePlugin = require('webpack/lib/DefinePlugin');
module.exports = {
plugins: [
new DefinePlugin({
// 定义 NODE_ENV 环境变量为 production
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
],
};
注意在定义环境变量的值时用 JSON.stringify 包裹字符串的原因是环境变量的值需要是一个由双引号包裹的字符串,而 JSON.stringify('production') 的值正好等于 "production" 。
执行构建后,你会在输出的文件中发现如下代码:
if (true) {
console.log('你正在使用线上环境');
} else {
console.log('你正在使用开发环境');
}
定义的环境变量的值被代入到了源码中, process.env.NODE_ENV === 'production' 被直接替换成了 true。 并且由于此时访问 process 的语句被替换了而没有了,Webpack 也不会打包进 process 模块了。
DefinePlugin 定义的环境变量只对 Webpack 需要处理的代码有效,而不会影响 Node.js 运行时的环境变量的值。
通过 Shell 脚本的方式去定义的环境变量,例如 NODE_ENV=production webpack ,Webpack 是不认识的,对 Webpack 需要处理的代码中的环境区分语句是没有作用的。
也就是说只需要通过 DefinePlugin 定义环境变量就能使上面介绍的环境区分语句正常工作,没必要又通过 Shell 脚本的方式去定义一遍。
如果你想让 Webpack 使用通过 Shell 脚本的方式去定义的环境变量,你可以使用 EnvironmentPlugin,代码如下:
new webpack.EnvironmentPlugin(['NODE_ENV'])
以上这句代码实际上等价于:
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
})
结合 UglifyJS
其实以上输出的代码还可以进一步优化,因为 if(true) 语句永远只会执行前一个分支中的代码,也就是说最佳的输出其实应该直接是:
console.log('你正在线上环境');
Webpack 没有实现去除死代码功能,但是 UglifyJS 可以做这个事情,如何使用请阅读 4-8 压缩代码 中的压缩 JavaScript。
第三方库中的环境区分
除了在自己写的源码中可以有环境区分的代码外,很多第三方库也做了环境区分的优化。 以 React 为例,它做了两套环境区分,分别是:
- 开发环境:包含类型检查、HTML 元素检查等等针对开发者的警告日志代码。
- 线上环境:去掉了所有针对开发者的代码,只保留让 React 能正常运行的部分,以优化大小和性能。
例如 React 源码中有大量类似下面这样的代码:
if (process.env.NODE_ENV !== 'production') {
warning(false, '%s(...): Can only update a mounted or mounting component.... ')
}
如果你不定义 NODE_ENV=production 那么这些警告日志就会被包含到输出的代码中,输出的文件将会非常大。
process.env.NODE_ENV !== 'production' 中的 NODE_ENV 和 ' production ' 两个值是社区的约定,通常使用这条判断语句在区分开发环境和线上环境。本实例 提供项目完整代码
webpack学习笔记--区分环境的更多相关文章
- Android Studio 学习笔记(一)环境搭建、文件目录等相关说明
Android Studio 学习笔记(一)环境搭建.文件目录等相关说明 引入 对APP开发而言,Android和iOS是两大主流开发平台,其中区别在于 Android用java语言,用Android ...
- Qt5学习笔记(1)-环境配置(win+64bit+VS2013)
Qt5学习笔记(1)-环境配置 工欲善其事必先-不装-所以装软件 久不露面,赶紧打下酱油. 下载 地址:http://download.qt.io/ 这个小网页就可以下载到跟Qt有关的几乎所有大部分东 ...
- openresty 学习笔记一:环境安装
openresty 学习笔记一:环境安装 openresty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭 ...
- 更博不能忘——webpack学习笔记
webpack是前端构建系统就像grunt和gulp(之前有学习过grunt所以也就大概明白webpack是个什么东西),所以说前端技术大部分还真是相通的,现在觉得当时多看的东西并不白费,虽然长时间不 ...
- 【原】webpack学习笔记
之前在react的项目中有用过webpack,不过没有认真的去研究,这段时间又重新好好的学习一下webpack,发觉 webpack是一个很强大的东西.而且很好用,方便,接下来主要是做一下学习的笔记 ...
- webpack学习笔记—webpack安装、基本配置
文章结构: 什么是webpack? 安装webpack 'webpack基本配置 一.什么是webpack? 在学习react时发现大部分文章都是react和webpack结合使用的,所以在学reac ...
- Python3学习笔记 - 准备环境
前言 最近乘着项目不忙想赶一波时髦学习一下Python3.由于正好学习了Docker,并深深迷上了Docker,所以必须趁热打铁的用它来创建我们的Python3的开发测试环境.Python3的中文教程 ...
- webpack学习笔记一:安装webpack、webpack-dev-server、内存加载js和html文件、loader处理非js文件
一 .webpack学习环境准备: 1:window系统 2:安装node.js 官方网址 下载好后下一步下一步安装即可 安装步骤略过....... 3:nrm的安装 打开cmd命令控制台 输入:n ...
- oracle学习笔记——配置环境
题记:最近再学oracle,于是按照这本经典的书<Oracle Database 9i/10g/11g编程艺术>来学习. 配置环境 如何正确建立SCOTT/TIGER演示模式 需要建立和运 ...
随机推荐
- python3 xml模块
一.简介 xml是实现不通语言或程序之间进行数据交换的协议,可扩展标记语言,标准通用标记语言的子集.是一种用于标记电子文件使其具有结构性的标记语言.xml格式如下,是通过<>节点来区别数据 ...
- python3+selenium入门02-操作火狐浏览器
使用selenium打开浏览器的时候,需要先去selenium官网下载一个对应浏览器的的driver插件.selenium下载.官网在国外可能打不开.或者可以从我网盘下载,但可能不是最新的网盘链接.将 ...
- wtforms-表单生成及验证
介绍 wtforms是一个支持多个web框架的form组件,主要用来做表单的验证以及生成的, 安装 pip install wtforms 使用 自定义一个类,继承wtforms.Form类,定义字段 ...
- jQuery中如何实现多库并存?
多库共存就是“$ ”符号的冲突. 方法一: 利用jQuery的实用函数$.noConflict();这个函数归还$的名称控制权给另一个库,因此可以在页面上使用其他库.这时,我们可以用"jQu ...
- Record && Limit
案例一:Record 预期效果:在 IVR 与用户交互的时候,比如让用户读一段语音,当用户读完之后,按键结束录音. <action application="set" dat ...
- Python2018-列表的相关操作
列表中存放的数据是可以进行修改的,比如"增"."删"."改" .“查” "增"-----append, extend, ...
- django配置发送邮箱
该邮箱配置后台发送邮箱验证使用 settings内配置 # 服务器地址 EMAIL_HOST = 'smtp.163.com' # 端口,邮箱默认动态端口 25 EMAIL_PORT = 25 # 邮 ...
- C# 防止content-type修改后上传恶意文件
以图片为例子.在上传图片的时候,使用Fiddler抓取 通过js判断文件类型是不安全的,所以通过后台来判断,代码如下: ) { HttpPostedFile file0 = Request.Files ...
- python与用户交互、数据类型
一.与用户交互 1.什么是用户交互: 程序等待用户输入一些数据,程序执行完毕反馈信息. 2.如何使用 在python3中使用input,input会将用户输入的如何内容存为字符串:在python中分为 ...
- iPhone内存溢出——黑白苹果
一旦iPhone内存长期占用过大,一关机即再难启动,如果你Home键加power键等都不行,那么可以要刷机了. 方式: 1.电脑下载ITunes,这个过程比较漫长,一系列逐渐大概3G,下载完成打开. ...