【工程化】Webpack 插件龙虎榜

152 阅读3分钟

优化

JS 压缩大师

TerserWebpackPlugin | webpack

terse 就是简洁的意思,顾名思义,Terser 的作用就是将代码变得更加简洁,从而使得代码更适合放在浏览器(互联网)中展示(另外一个打包库,browserify 名字就来源于此)。

Terser 用于压缩代码体积,通常用于生产(也只有生产有这个需求)。

测试下来,mode 为 production 的时候,使用 Terser 时打包产物体积为 352 字节,不使用时体积为 423 字节。

虽然看起来产物的字符都一样,但 Terser 能够对一些不可见的空白字符、换行符、评论、组织分隔符进行删减。从而减小产物体积。

const TerserPlugin = require("terser-webpack-plugin");

module.exports = {
  entry: "./index.js",
  mode: "production",
  output: {
    filename: "output.js",
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          mangle: {
            // Find work around for Safari 10+
            safari10: true,
          },
        },
        // Use multi-process parallel running to improve the build speed
        parallel: true,

      }),
    ],
  },
};

CSS 压缩大师

CssMinimizerWebpackPlugin | webpack

CSS 文件保存了各种样式,而 CssMinimizer 这个插件的作用就是能够将 CSS 按内容进行合并同类项,把产物体积缩到最小。

module.exports = {
  /* ... */
  optimization: {
    minimize: true,
      minimizer: [
      new CssMinimizerPlugin(),
    ]
  }
  /* ... */
}

副作用插件

这里包含一些能助你如虎添翼的插件,方便开发、生产的流程。

创建 HTML 不再麻烦

HtmlWebpackPlugin | webpack

网页通常都使用 HTML 作为骨架,但是现今各种前端框架盛行,我们可以方便地编写模板代码,最后才将这些结构体转为真正的 DOM 注入到这个 HTML 文件中。

实际上我们直接使用到 HTML 的场景已经大幅减少,而为了提供网页入口,我们每次都需要在 dist/中手动新建一个 index.html 文件,很繁琐。

而 HtmlWebpackPlugin 能够每次打包都在输出目录 dist/ 创建一个 HTML 文件,并且会包含一个引入输出打包产物的 <script>标签,打包产物的 hash 也会自动更新。

module.exports = {
  /* ... */
  plugins: [new HtmlWebpackPlugin()],
  /* ... */
}

使用环境变量不再麻烦

DefinePlugin | webpack

只需要在 webpack.config.js中提前定义好一些变量,即可以在应用中所有 JS 文件中使用这些全局变量。

其实就是在编译时进行字符串的替换。

module.exports = {
  /* ... */
  plugins: [new webpack.DefinePlugin({
    NODE_ENV: process.env.NODE_ENV || 'development',
    PUBLIC_URL: 'path/to/public/dir' 	
  )],
  /* ... */
}

为每一个 JS 文件生成一个 CSS

MiniCssExtractPlugin | webpack

在写 React 应用的时候,通常都会将组件放在同一个文件夹内管理。但是打包后,所有组件的样式文件都放到同一个地方,可能会造成重名困扰。

而使用了 MiniCssExtractPlugin 插件能够很好地解决这个问题,将样式保持出现在它应该出现的组件内。

此外还支持异步加载(渲染了才加载)、没有重复的编译(性能)、更容易使用(组件开发)。

module.exports = {
  /* ... */
  plugins: [new MiniCssExtractPlugin()],
  module: {
    rules: [
      {
        test: /.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
  /* ... */
}

注意:MiniCssExtractPlugin 需要同时在 plugin 和 loader 中出现

模块

紧急尝鲜

babel-loader | webpack

通常一些比较新的 JS 语法(如 ES2015 的 结构赋值、模板字符串、spread 语法)未必支持在浏览器中运行,需要进行 polyfill (垫片)转换。而 babel 就是 polyfill 的专业团队,他们家出品了一个 babel-loader 专门用来方便我们这些想要尝新的弄潮儿。

原理就是先解析代码,转成 AST, 然后生成 ES5 的代码。

module.exports = {
  /* ... */
  rules: [
    {
      test:  /.(js|jsx|ts|tsx)$/,
      exclude: /node_modules/,
      include: 'path/to/src/file',
      loader: 'babel-loader',
    }
  ]
};

还想尝尝 React

babel-preset-react-app

又想用新语法,又想玩 React,不用对打包工具操心,还不赶紧用 CRA 快速上手。

如果你不想使用 CRA,但是又想获得同样的体验,可以使用 babel-preset-react-app 这个预设。CRA 的专业团队的出品,必属精品。

你只要在 babel-loader 的基础上可选配置上如下设置,即可解锁和使用 CRA 一样的体验。

{
  test:  /.(js|jsx|ts|tsx)$/,
  exclude: /node_modules/,
  include: 'path/to/src/file',
  loader: 'babel-loader',
  options: {
    presets: [
      // Preset includes JSX, TypeScript, and some ESnext features
      require.resolve('babel-preset-react-app'),
    ]
  }
}

分析

比分看板

GitHub - FormidableLabs/webpack-dashboard: A CLI dashboard for webpack dev server

webpack 构建默认的打印输出的 log 有点丑,想要酷炫的终端数据看板,可以如下安装 webpack 看板:

yarn add -D webpack-dashboard

用的时候就像正常插件一样:

module.exports = {
  /* ... */
  plugins: [new webpackDashboard()],
  /* ... */
}

有图有真相

GitHub - webpack-contrib/webpack-bundle-analyzer: Webpack plugin and CLI utility that represents bundle content as convenient interactive zoomable treemap

当我们想要分析打包产物中各个库所占体积的大小,可以使用 Webpack-bundle-analyzer 进行分析,会很直观地看到各个模块在打包产物中的所占体积。

用法也很简单:

module.exports = {
  /* ... */
  plugins: [new BundleAnalyzerPlugin()]
  /* ... */
}

参考资料

  1. The best and proven React Webpack plugins for 2021
  2. Top Webpack plugins for faster development