认识DLL库

DLL是什么呢?

  • DLL全称是动态链接库,是为软件在Windows中实现共享函数库的一种实现方式
  • 那么webpack中也有内置DLL功能,它指的是我们可以将可以共享的,并且不经常改变的代码,抽取成一个共享的库
  • 这个库在之后编译的过程中,会被引入到其他项目的代码中
  • 通俗点讲就是一个缓存,以空间换时间,先把常用的打包好,你项目中用到了就不用重新打包,而是引用就可以了

DLL库的使用分为两步:

  • 第一步:打包一个DLL库
  • 第二部:项目中引入DLL库

注意:在升级到webpack4以后,React和Vue脚手架都移除了DLL库,这是因为webpack4本身的打包性能足够高,DLL文件不能带来明显的打包速度提升,提升的几秒钟对于整个项目的打包时间来说可以忽略不计,不过autodll-webpack-plugin的README.md中推荐了hard-source-webpack-plugin,配置更简单,打包速度提升也很明显,并且会集成在webpack5中

打包一个DLL库

首先,我们需要在一个单独的文件中,将我们想要通过DLL打包的文件进行打包,比如我们想要将react和react-dom通过DLL打包,这个时候我们新建个文件夹,npm 安装 react 和 react-dom

  1. // 新文件夹只安装 react 和 react-dom 即可
  2. "dependencies": {
  3. "react": "^17.0.2",
  4. "react-dom": "^17.0.2"
  5. }

然后配置一个webpack.dll.js文件,文件内和webpack配置差不多

  1. const path = require('path');
  2. const TerserPlugin = require('terser-webpack-plugin');
  3. const webpack = require('webpack');
  4. module.exports = {
  5. entry: {
  6. react: ['react', 'react-dom'],
  7. },
  8. output: {
  9. path: path.resolve(__dirname, './dll'),
  10. filename: 'dll_[name].js',
  11. library: 'dll_[name]',
  12. },
  13. optimization: {
  14. minimizer: [
  15. new TerserPlugin({
  16. extractComments: false,
  17. }),
  18. ],
  19. },
  20. plugins: [
  21. new webpack.DllPlugin({
  22. name: 'dll_[name]',
  23. path: path.resolve(__dirname, './dll/[name].manifest.json'),
  24. }),
  25. ],
  26. };

入口文件是react和react-dom,通过plugins插件webpack.DllPlugin进行打包配置,这个插件是webpack自带的

我们将打包好后导出的dll文件夹放入其他需要使用Dll打包后文件的项目中

Terser介绍和安装

什么是Terser?

  • Terser是一个JavaScript的解释(Parser)、Mangler(绞肉机)/Compressor(压缩机)的工具集
    Mangler(绞肉机)作用:比如项目中一个函数的名称是addPersonToSomeone,通过Mangler可以将其在编译时改成a,这样就能使打包出来的文件更小,也能起到一个丑化或者说是混淆的作用,别人无法通过函数名推测函数的作用。
    Compressor(压缩机)作用:项目中存在的一些“不可达”的代码,比如
    我们知道,这里的打印语句是无法执行的,可以看作是dead code,Compressor的作用就是在打包的过程中剔除这些代码,使得打包后的文件更小。

    1. if(false){
    2. console.log('a')
    3. }
  • 早期我们使用 uglify-js 来压缩、丑化我们的 JS 代码,但是目前该库已经不再维护,并且不能处理ES6+的语法

  • Terser 是从 uglify-es fork 过来的,并且保留它原来的大部分 API 以及适配 uglify-es 和 uglify-js@3 等

也就是说,Terser可以帮助我们压缩、丑化我们的代码,让我们的bundle变得更小

因为Terser是一个独立的工具,所以可以单独安装:

# 全局安装
npm install terser -g
# 局部安装
npm install terser

命令行使用Terser

我们可以在命令行使用Terser

terser [input files] [options]

# 举例说明
terser js/file1.js -o foo.min.js -c -m

https://github.com/terser/terser

可以通过上面的链接访问github查看具体配置

Terser在webpack中配置

真实开发中,我们不需要手动通过terser来处理我们的代码,我们可以直接通过webpack来处理:

  • 在webpack中有一个minimizer属性,在production模式下,默认就是使用TerserPlugin来处理我们的代码的
  • 如果我们对默认的配置不满意,也可以自己创建TerserPlugin的实例,来覆盖相关的配置
    optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true,
        extractComments: false,
        terserOptions: {
          mangle: true,
          keep_classnames: true,
          keep_fnames: true,
        },
      }),
    ],
    },
    
    如上就是我们对webpack的Terser做自定义配置,不过一般情况下,当webpack模式为production时,默认的Terser就足以应对日常的开发需求

    CSS的压缩

除了对于js代码的压缩,我们还可以对css进行压缩:

  • CSS压缩通常是去除无用的空格等,因为很难去修改选择器、属性的名称、值等
  • CSS的压缩我们可以使用另外一个插件:css-minimizer-webpack-plugin
  • css-minimizer-webpack-plugin是使用cssnano工具来优化、压缩css(也可以单独使用)

第一步,安装css-minimizer-webpack-plugin

npm install css-minimizer-webpack-plugin -D

第二部,在optionmization.minimizer中配置

plugins: [
  // 生产环境
  new CleanWebpackPlugin({}),
  new MiniCssExtractPlugin({
    filename: 'css/[name].[contenthash:6].css',
  }),
  new CssMinimizerPlugin(),
],

引入并配置即可实现CSS代码压缩

Scope Hoisting

什么是Scope Hoisting?

  • Scope Hoisting是从webpack3开始增加的一个功能
  • 功能是对作用于进行提升,并且让webpack打包后的代码更小、运行更快

默认情况下webpack打包会有很多的函数作用域,包括一些IIFE

  • 无论是从最开始的代码运行,还是加载一个模块,都需要执行一系列的函数
  • Scope Hoisting 可以将函数合并到一个模块中来运行

使用 Scope Hoisting 非常的简单,webpack已经内置了对应的模块

  • 在 production 模式下,默认这个模块就会启用
  • 在 development 模式下,我们需要自己来打开这个模块