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演示模式 需要建立和运 ...
随机推荐
- eMMC基础技术9:分区管理
[转]http://www.wowotech.net/basic_tech/emmc_partitions.html 0.前言 eMMC 标准中,将内部的 Flash Memory 划分为 4 类区域 ...
- UniGUI 如何进行 UniDBGrid 的单元 Cell 的计算 ?
来源:http://forums.unigui.com/index.php?/topic/10508-update-dataset-events-in-unidbgrid/?hl=unidbgrid ...
- mac安装adb
安装 brew cask install android-platform-tools 测试 adb devices
- liunx本地网卡流量监控
作者:邓聪聪 公司网络异常,由于可监控设备有限,无法快速读取网络异常的设备,所以找到了这个办法,部署在服务端用以解决网络突发异常流量故障的查找! 环境:CentOS release 6.8 Linux ...
- ADO读写DateTime方式
// 读取日期 var = m_pResultSet->GetCollect(_variant_t("Birth_Time")); DATE dt = var.date; C ...
- configparser模块--配置文件
该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值). 创建文件 import configparser config = ...
- SharePoint 2010 安装错误:请重新启动计算机,然后运行安装程序以继续
一.环境:Windows Server 2008 R2 with sp1,SharePoint 2010 二.问题描述: 正常的安装SharePoint 2010 ,安装完必备组件,并提示所有必备组件 ...
- hdu 4825 && acdream 1063 01字典树异或问题
题意: 给一个集合,多次询问,每次给一个k,问你集合和k异或结果最大的哪个 题解: 经典的01字典树问题,学习一哈. 把一个数字看成32位的01串,然后查找异或的时候不断的沿着^为1的路向下走即可 # ...
- Hash之哈希表的详解
Hash算法 Hash算法的原理; 决绝冲突的办法是: 线性探查法; 双散列函数法; 拉链法处理碰撞; 哈希原理及实现; 哈希表-Hash table, 也叫散列表;
- php password_hash
2018-1-6 17:22:13 星期六 php 自带的密码生成方法, 如果生成密码最好使用这个, 这个是"单程"的, 没有解密函数 $a = '123456'; $b = pa ...