• webpack笔记-生产环境与开发环境常用plugin介绍(五)


    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 用于创建一些在编译时可以配置值,在运行时可以使用的常量,如下例子:

    module.exports = {
      // ...
      plugins: [
        new webpack.DefinePlugin({
          PRODUCTION: JSON.stringify(true), // const PRODUCTION = true
          VERSION: JSON.stringify('5fa3b9'), // const VERSION = '5fa3b9'
          BROWSER_SUPPORTS_HTML5: true, // const BROWSER_SUPPORTS_HTML5 = 'true'
          TWO: '1+1', // const TWO = 1 + 1,
          CONSTANTS: {
            APP_VERSION: JSON.stringify('1.1.2') // const CONSTANTS = { APP_VERSION: '1.1.2' }
          }
        }),
      ],
    }

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

    console.log("Running App version " + VERSION);
    
    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 代码,我们看一下如何使用的:

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

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

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

    IgnorePlugin

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

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

    module.exports = {
      // ...
      plugins: [
        new webpack.IgnorePlugin(/^./locale$/, /moment$/)
      ]
    }

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

    webpack-bundle-analyzer

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

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

    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    
    module.exports = {
      // ...
      plugins: [
        new BundleAnalyzerPlugin(),
      ],
    }

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

  • 相关阅读:
    OC学习13——Foundation框架中的集合
    OC学习12——字符串、日期、日历
    OC学习11——循环引用与@class
    OC学习10——内存管理
    OC学习9——反射机制
    OC学习8——异常处理
    OC学习7——类别、扩展和协议
    OC学习6——面相对象的三大特性
    OC学习5——类和对象
    Unity3D应用防外挂与防破解
  • 原文地址:https://www.cnblogs.com/moqiutao/p/13199863.html
Copyright © 2020-2023  润新知