22_webpack_优化(22_ webpack_ optimization)

Terser是一个JS的解析(Parser)、Mangleer(绞肉机)、Compresor(压缩机)的工具

绞肉机如:一个函数 function functionsWithLongNames(){ } 名称很长,那么打包的文件占用的空间就相对大一些,如果经过工具来对代码进行转化,把函数的名称变成 function a(){} 或者function b(){} 这些较短名称的函数,那么他打包之后的文件占用的体积相对会比较少一些以前称之为这个过程为丑化,现在变成了绞肉机

压缩机知道TreeShaking的都知道有些dead code elimination(死代码删除)如:if(false){console.log(‘123’)}

Terser对JS文件进行解析,对代码进行丑化,压缩的工具集

早期我们是通过uglify-js来压缩、丑化JS代码,但是现在这个库已经不维护了,也不支持ES6以上的语法的

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

因为Terser是一个独立的工具,所以我们可以单独安装、使用  安装:npm i terser (默认安装了cli的工具)

  使用:npx terser [输入文件] -o [输出文件] [options]

Terser在webpack中配置

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

  在webpack中有一个minimizer属性,在production模式下,默认就是使用TerserPlugin来处理我们的代码的

  如果我们对默认的配置不满意,也可以自己来创建TerserPlugin的示例,并且覆盖相关的配置

  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        // 使用多进程并行运行来提高构建速度。默认并发运行次数:。os.cpus().length - 1
        parallel: true,
        // 是否应将注释提取到单独的文件中
        extractComments: false,
        terserOptions: {
          compress: {
            arguments: true,
          },
          mangle: true,
          toplevel: true,
          keep_classnames: true,
          keep_fnames: true,
        },
      }),
    ],
  },

CSS的压缩

CSS压缩通常是去除无用的空格等(因为很难去修改选择器、属性的名称、值等)

css的压缩我们可以使用另外一个插件:css-minimizer-webpack-plugin

安装:

npm i css-minimizer-webpack-plugin -D

npm i postcss -D 不安装postcss会报错

使用:

const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");


plugins:[
    new CleanWebpackPlugin({}),
    new MiniCssExtractPlugin({
      filename: "css/[name].[contenthash:8].css",
    }),
    new CssMinimizerWebpackPlugin(),
  ],

Scope Hoisting

什么是ScopeHoisting(作用域提升)呢?

  scope Hoisting从webpack3开始增加的一个新功能  功能实时对作用域进行提升,并且让webpack打包后的代码更小、运行更快

默认情况下webpack打包会有很多的函数作用域,包括一些(比如最外层的)IIFE

  无论是从最开始的代码运行,还是加载一个模块,都需要执行一系列的函数

  Scope Hoisting可以将函数合并到一个模块中来运行

使用Scope Hoisting非常的简单,默认这个插件就会启用

  在production模式下,默认这个模块就会启用

  在development模式下,我们需要自己来打开该模式

development模式下配置:

const webpack = require("webpack");

  plugins: [
    new webpack.optimize.ModuleConcatenationPlugin(),
  ],

转化前:

转化后:

注意事项:这个插件内部原理其实是依赖于esmodule的静态分析的esmodule对模块进行解析时,会进行静态分析,在静态分析的时候,这个插件可以分析出来哪些代码可以做作用域提升

如果一个模块被多个模块所引入了不可能每个模块都复制一份代码,这个时候不做作用域提升了

推荐在开发过程中,推荐使用esmodule

如果你在项目中使用了第三方模块,那么第三方模块中可能使用esmodule或者commonjs,那么当我们使用import语句导入模块的时候它指向的是main字段指向的入口文件(package.json中的main属性指向的文件)  我们可以进行配置:  resolve.mainFields 4.1.3 优化 resolve.mainFields 配置 – 简书 (jianshu.com)

————————

Terser is a tool for parsing JS, mangler and compressor

Meat grinder: for example, if the name of a function functions withlongnames() {} is very long, the space occupied by the packaged file is relatively large. If the code is transformed by a tool and the name of the function is changed into functions with shorter names such as function a () {} or function B () {}, the volume occupied by the packaged file will be relatively small, which was previously called vilification, Now it’s a meat grinder

All compressors who know treeshaking know some dead code eliminations, such as if (false) {console. Log (‘123 ‘)}

Terser parses the JS file, vilifies the code, and compresses the tool set

In the early days, we compressed and vilified JS code through uglify JS, but now this library is no longer maintained and does not support syntax above ES6

Terser comes from uglify es fork and retains most of its original APIs and adapts to uglify es and uglify- js@3 Etc;

Because terser is an independent tool, we can install and use it separately: NPM I terser (the tool with CLI installed by default)

Using: NPX terser [input file] – o [output file] [options]

Terser在webpack中配置

In real development, we don’t need to process our code manually through terser, but we can process it directly through webpack

There is a minimizer attribute in webpack. In production mode, terserplugin is used to process our code by default

If we are not satisfied with the default configuration, we can also create an example of terserplugin and overwrite the relevant configuration

  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        // 使用多进程并行运行来提高构建速度。默认并发运行次数:。os.cpus().length - 1
        parallel: true,
        // 是否应将注释提取到单独的文件中
        extractComments: false,
        terserOptions: {
          compress: {
            arguments: true,
          },
          mangle: true,
          toplevel: true,
          keep_classnames: true,
          keep_fnames: true,
        },
      }),
    ],
  },

Compression of CSS

CSS compression is usually to remove useless spaces, etc. (because it is difficult to modify selectors, property names, values, etc.)

For CSS compression, we can use another plug-in: CSS minimizer webpack plugin

Installation:

npm i css-minimizer-webpack-plugin -D

NPM I postcss – D if postcss is not installed, an error will be reported

use:

const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");


plugins:[
    new CleanWebpackPlugin({}),
    new MiniCssExtractPlugin({
      filename: "css/[name].[contenthash:8].css",
    }),
    new CssMinimizerWebpackPlugin(),
  ],

Scope Hoisting

What is scopehoisting?

Scope hosting is a new function added from webpack 3, which can improve the scope in real time, and make the code packaged by webpack smaller and run faster

By default, webpack packaging will have many function scopes, including some (such as the outermost) Iife

Whether you run the code from the beginning or load a module, you need to execute a series of functions

Scope hosting can combine functions into one module to run

Using scope hosting is very simple. By default, this plug-in will be enabled

In production mode, this module will be enabled by default

In the development mode, we need to open it ourselves

Configuration in development mode:

const webpack = require("webpack");

  plugins: [
    new webpack.optimize.ModuleConcatenationPlugin(),
  ],

Before conversion:

After conversion:

Note: the internal principle of this plug-in actually depends on the static analysis of esmodule. When esmodule parses the module, it will carry out static analysis. During static analysis, this plug-in can analyze which codes can improve the scope

If a module is introduced by more than one module, it is impossible for each module to copy a copy of the code. At this time, the scope will not be promoted

It is recommended to use esmodule in the development process

If you use a third-party module in the project, esmodule or commonjs may be used in the third-party module. When we use the import statement to import the module, it points to the entry file pointed to by the main field (the file pointed to by the main attribute in package.json). We can configure it: resolve Mainfields 4.1.3 optimize resolve Mainfields configuration – brief book (Jianshu. Com)