mode 和 plugin

前边我们介绍 mode 时提过,mode 不同值会影响 webpack 构建配置,其中有一个就是会启用 DefinePlugin 来设置process.env.NODE_ENV 的值,方便代码中判断构建环境。

除此之外,development和 production两个不同的 mode 之间还有其他 plugin 使用上的区别,这里详细介绍一下:

development

development 下会启用 NamedChunksPlugin 和 NamedModulesPlugin,这两个 plugin 官方文档并没有详细的介绍,主要作用是在 Hot Module Replacement(热模块替换,后续简称 HMR)开启时,模块变化时的提示内容显示 chunk 或者 module 名称,而不是 ID。

production

production 下会启动多个 plugins,分别是:

  • FlagDependencyUsagePlugin 在构建时给使用的依赖添加标识,用于减少构建生成的代码量。
  • FlagIncludedChunksPlugin 在构建时给 chunk 中所包含的所有 chunk 添加 id,用于减少不必要的 chunk。
  • ModuleConcatenationPlugin 构建时添加作用域提升的处理,用于减少构建生成的代码量,详细参考:module-concatenation-plugin
  • NoEmitOnErrorsPlugin 编译时出错的代码不生成,避免构建出来的代码异常。
  • OccurrenceOrderPlugin 按使用的次数来对模块进行排序,可以进一步减少构建代码量。
  • SideEffectsFlagPlugin 在构建时给带有 Side Effects 的代码模块添加标识,用于优化代码量时使用。
  • TerserPlugin 压缩 JS 代码,参考:Terser

production mode 下启用的大量 plugin都是为了优化生成代码而使用的,和配置的 optimization 的内容息息相关,详细可以查阅:optimization

下面介绍下其中用到的一些plugin的使用,帮我们理解plugin。

DefinePlugin

DefinePlugin 是 webpack 内置的插件,可以使用webpack.DefinePlugin 直接获取。

在不同的 mode 中,会使用 DefinePlugin 来设置运行时的 process.env.NODE_ENV 常量。DefinePlugin 用于创建一些在编译时可以配置值,在运行时可以使用的常量,如下例子:

  1. module.exports = {
  2. // ...
  3. plugins: [
  4. new webpack.DefinePlugin({
  5. PRODUCTION: JSON.stringify(true), // const PRODUCTION = true
  6. VERSION: JSON.stringify('5fa3b9'), // const VERSION = '5fa3b9'
  7. BROWSER_SUPPORTS_HTML5: true, // const BROWSER_SUPPORTS_HTML5 = 'true'
  8. TWO: '1+1', // const TWO = 1 + 1,
  9. CONSTANTS: {
  10. APP_VERSION: JSON.stringify('1.1.2') // const CONSTANTS = { APP_VERSION: '1.1.2' }
  11. }
  12. }),
  13. ],
  14. }

有了上面的配置,就可以在应用代码文件中,访问配置好的常量了,如:

  1. console.log("Running App version " + VERSION);
  2.  
  3. if(!BROWSER_SUPPORTS_HTML5) require("html5shiv");

对上面配置简单解释下:

  • 如果配置的值是字符串,那么整个字符串会被当成代码片段来执行,其结果作为最终变量的值,如上面的"1+1",最后的结果是2
  • 如果配置的值不是字符串,也不是一个对象字面量,那么该值会被转为一个字符串,如true,最后的结果是'true'
  • 如果配置的是一个对象字面量,那么该对象的所有 key 会以同样的方式去定义

这样我们就可以理解为什么要使用 JSON.stringify()了,因为 JSON.stringify(true)的结果是 'true'JSON.stringify("5fa3b9") 的结果是 "5fa3b9"

社区中关于 DefinePlugin 使用得最多的方式是定义环境常量,例如 PRODUCTION = true或者 __DEV__ = true

建议使用 process.env.NODE_ENV: ...的方式来定义 process.env.NODE_ENV,而不是使用 process: { env: { NODE_ENV: ... } } 的方式,因为这样会覆盖掉process这个对象,可能会对其他代码造成影响。

TerserPlugin

webpack mode 为 production 时会启用 TerserPlugin 来压缩 JS 代码,我们看一下如何使用的:

  1. module.exports = {
  2. // ...
  3. // TerserPlugin 的使用比较特别,需要配置在 optimization 字段中,属于构建代码优化的一部分
  4. optimization: {
  5. minimize: true, // 启用代码压缩
  6. minimizer: [new TerserPlugin({
  7. test: /\.js(\?.*)?$/i, // 只处理 .js 文件
  8. cache: true, // 启用缓存,可以加速压缩处理
  9. })], // 配置代码压缩工具
  10. },
  11. }

关于 TerserPlugin 的更多配置参考官方文档:terser-webpack-plugin

在以前的版本 webpack 是使用 UglifyWebpackPlugin来压缩 JS 代码,后边更换为 TerserPlugin了,可以更好地处理新的 JS 代码语法。

IgnorePlugin

IgnorePlugin和 DefinePlugin一样,也是一个webpack内置的插件,可以直接使用 webpack.IgnorePlugin来获取。

这个插件用于忽略某些特定的模块,让webpack不把这些指定的模块打包进去。例如我们使用 moment.js,直接引用后,里边有大量的 i18n 的代码,导致最后打包出来的文件比较大,而实际场景并不需要这些 i18n 的代码,这时我们可以使用 IgnorePlugin 来忽略掉这些代码文件,配置如下:

  1. module.exports = {
  2. // ...
  3. plugins: [
  4. new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  5. ]
  6. }

IgnorePlugin 配置的参数有两个,第一个是匹配引入模块路径的正则表达式,第二个是匹配模块的对应上下文,即所在目录名。

webpack-bundle-analyzer

这个 plugin 可以用于分析 webpack 构建打包的内容,用于查看各个模块的依赖关系和各个模块的代码内容多少,便于开发者做性能优化。

webpack-bundle-analyzer是第三方的包,使用前需要安装,配置上很简单,仅仅引入 plugin 即可,在构建时可以在浏览器中查看分析结果:

  1. const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
  2.  
  3. module.exports = {
  4. // ...
  5. plugins: [
  6. new BundleAnalyzerPlugin(),
  7. ],
  8. }

使用这个可以配合 IgnorePlugin 来过滤掉部分大而无用的第三方模块。

webpack笔记-生产环境与开发环境常用plugin介绍(五)的更多相关文章

  1. 【webpack学习笔记】a06-生产环境和开发环境配置

    生产环境和开发环境的配置目标不一样,生产环境主要是让文件压缩得更小,更优化资源,改善加载时间. 而开发环境,主要是要开发更方便,更节省时间,比如调试比如自动刷新. 所以可以分开配置不同的开发环境,然后 ...

  2. (17/24) webpack实战技巧:生产环境和开发环境并行设置,实现来回切换

    1. 概述 生产环境和开发环境所需依赖是不同: --开发依赖:就是开发中用到而发布时用不到的.在package.json里面对应的就是devDependencies下面相关配置. --生产依赖: 就是 ...

  3. Maven Filter与Profile隔离生产环境与开发环境

    Maven Filter与Profile隔离生产环境与开发环境 在不同的开发阶段,我们一般用到不同的环境,开发阶段使用开发环境的一套东西,测试环境使用测试环境的东西,可能有多个测试环境,生产环境使用的 ...

  4. (24/24) webpack小案例--自己动手用webpack构建一个React的开发环境

    通过前面的学习,对webpack有了更深的认识,故此节我们就利用前面相关知识自己动手用webpack构建一个React的开发环境,就算是一个小案例吧. 注:此处使用的开发工具是Webstorm. 1. ...

  5. vue cli3中配置生产环境、开发环境、测试环境

    首先在packjson中配置 "scripts": { "serve": "vue-cli-service serve", //调用开发ap ...

  6. 通过Maven配置测试环境和开发环境连接不同的数据库

    通过Maven配置测试环境和开发环境连接不同的数据库   作者及来源: 通灵宝玉 - 博客园    收藏到→_→: 此文来自: 马开东博客 网址:http://www.makaidong.com   ...

  7. Android 程序分析环境搭建-开发环境搭建

    1.1  JDK 安装 JDK 的配置,初学java 开发,那是必须会的. 下载,遇到的问题就是要注册oracle 的账号,还有你要下载特定版本,比如jdk 1.7,jdk 1.6,很难找到在哪里.解 ...

  8. 【webpack学习笔记】a04-建立开发环境

    开发环境就是在开发过程中为了方便配置的环境,生产环境就是开发完成即将上线的情况. 好了,说了句废话,切入正题. 在开发时,打包后的文件压缩成一团,报错调试的时候傻眼了有木有?每次做出修改需要到浏览器查 ...

  9. 基于webpack和vue.js搭建开发环境

    前言 在对着产品高举中指怒发心中之愤后,真正能够解决问题的是自身上的改变,有句话说的好:你虽然改变不了全世界,但是你有机会改变你自己.秉承着“不听老人言,吃亏在眼前”的优良作风,我还是决定玩火自焚. ...

  10. spring boot区分生产环境和开发环境

    回顾一下spring boot使用基础,做个笔记. 通过配置文件,设置项目的开发环境和生成环境. 项目目录结构: application-dev.yml是开发环境配置文件,application-pr ...

随机推荐

  1. SafeLine Web 安全网关保护你的网站不受黑客攻击

    SafeLine 简介 今天,推荐给大家的是一款在社区广受好评的网站防护工具 -- SafeLine Web 安全网关. 简单来说这是一个自带安全 buf 的 Nginx,它基于业界领先的语义分析检测 ...

  2. 深入解读RabbitMQ工作原理

    RabbitMQ简介 在介绍RabbitMQ之前首先要介绍一下MQ,MQ是什么?MQ全称是Message Queue,可以理解为消息队列的意思. RabbitMQ是一个实现了AMQP(Advanced ...

  3. ABC361-C题解

    背景 昨天打比赛的时候查了中考分,心快停跳了. 题意 从 \(n\) 个数字中删除 \(k\) 个数字,问剩下的数字中极差的最小值. 分析 首先把这 \(n\) 个数字排序,然后问题就可以转化为求这 ...

  4. JavaScript小面试~数组相关的方法和运用(学习笔记)

    1,稀疏数组 稀疏数组是指数组中的某个下标未给出值或某个下标的值被删除.例如: let arrayOne=['xiaozi',,12,,true,23] let arrayTwo=[1,2,3,3,4 ...

  5. Kafka kafka在windows下的安装与配置

    kafka在windows下的安装与配置   By: 授客 QQ:1033553122     1.测试环境.............................................. ...

  6. Docker安装及操作

    目录 docker 安装: 官方文档方法 CentOS Ubuntu docker-compose 单独安装 centos7 ubuntu22.04 docker 容器操作: docker启动与停止 ...

  7. 备份服务器eBackup

    目录 软件包方式安装eBackup备份软件   1.前景提要   2.创建虚拟机   3.安装备份软件.   4.安装 eBackup 补丁   5.配置 eBackup 服务器   6.访问web界 ...

  8. 前端RSA密钥生成和加解密——window.crypto使用相关

    转自简书,原文地址,本文介绍window.crypto关于RSA方面的API. crypto API支持常用的rsa.aes加解密,这边介绍rsa的应用. 浏览器兼容性 window.crypto需要 ...

  9. 个人常用的 matplotlib 绘图模板

    import numpy as np import matplotlib import matplotlib.pyplot as plt matplotlib.rcParams['mathtext.f ...

  10. linux终端如何加上时间,添加时间戳到终端提示?

    方法: 在 .bashrc 文件中加入: export PROMPT_COMMAND="echo -n \[\$(date +%H:%M:%S)\\] " 这样便可以在每次输入命令 ...