您的位置:

深入分析webpack插件

一、webpack插件原理

Webpack插件是指可以在Webpack构建流程中,根据指定的生命周期和Webpack内部的事件机制,对Webpack进行扩展和定制的一类模块。

Webpack插件是一个JavaScript对象,它本质上是一个带有一个apply方法的JavaScript类。apply方法接收一个webpack compiler实例,可以通过这个实例去访问Webpack的内部环境,并且可以通过Webpack暴露出来的API实现自定义的逻辑处理。

Webpack的插件机制基于观察者模式实现,插件可以监听Webpack的构建过程中暴露的各个事件,并在事件触发时执行自定义的逻辑。

二、webpack插件库

Webpack插件库是指包含常见的Webpack插件并且支持Webpack 5.x版本的插件集合。Webpack插件库包括webpack、CommonsChunkPlugin、DefinePlugin、MiniCssExtractPlugin等等。

除了Webpack自身提供的插件外,还有很多优秀的第三方插件,例如clean-webpack-plugin、html-webpack-plugin、copy-webpack-plugin等等。这些插件为我们的Webpack构建提供了很多便利。

使用第三方插件需要安装该插件到项目依赖中,然后在Webpack配置文件中引入并进行简单的配置即可。

三、webpack插件钩子

Webpack插件钩子是指Webpack在不同生命周期触发的一系列事件,每个事件可以被插件监听并执行特定功能。

Webpack插件钩子包括compilation(当编译完成并准备生成文件时被调用,这个阶段有chunk钩子和module钩子)、emit(当所有chunk都完成,但在输出到目录之前调用)和done(在输出生成好的文件后调用)。

钩子的名称通常使用webpack.[name],可以通过Tapable.js查看所有的钩子。

四、webpack常用配置

Webpack的配置文件是一个JavaScript文件,负责返回一个Webpack配置对象。该对象包含了Webpack的所有配置项。

module.exports = {
  entry: './src/index.js', // 入口文件
  output: { // 输出
    filename: 'bundle.js'
  },
  module: { // 模块规则
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [ // 插件
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ]
}

五、webpack插件生命周期

Webpack插件的生命周期包括以下四个阶段:

1. 编译阶段(compilation):针对所有要编译的模块进行的操作,在这个阶段可以通过compilation钩子进行一些额外的处理。

2. 优化阶段(optimization):从compilation钩子开始,Webpack进行各类优化操作,例如Tree-Shaking、Scope Hoisting和代码压缩等等。

3. 代码生成阶段(code-generation):在这个阶段,Webpack开始根据优化后的代码生成最终的静态库。

4. 输出阶段(output):在最后一个插件被执行后,Webpack将生成最终代码并将代码输出到指定的目标位置。

六、webpack插件执行顺序

Webpack插件的执行顺序基于两个因素:插件的引入顺序和插件钩子的执行顺序。

Webpack按照插件的顺序来执行,当遇到一个涉及compilation阶段的钩子时,Webpack会继续调用其他插件直到完成此钩子的所有处理步骤。然后开始执行下一阶段的插件。

七、手写webpack插件

手写Webpack插件需要思考插件的具体功能。

下面以通过before-compile钩子实现一段log输出为例:

class LogPlugin {
  apply(compiler) {
    compiler.hooks.beforeCompile.tap('LogPlugin', () => {
      console.log('Webpack编译开始...')
    })
  }
}

module.exports = LogPlugin

八、webpack插件开发

开发Webpack插件需要遵循以下步骤:

1. 创建插件类,通过apply方法接收webpack compiler实例。

2. 监听Webpack插件钩子以确定适当的事件进行插件的响应操作。

3. 根据处理过程编写插件逻辑。

4. 将插件发布到npm或在项目中引入。

九、webpack插件修改请求依赖

Webpack插件可以通过修改依赖关系来优化构建效果,例如通过CommonsChunkPlugin将多个入口文件的共同依赖提取到一个chunk中,提高公共模块的复用。

下面以CommonsChunkPlugin为例

module.exports = {
  entry: {
    home: './home.js',
    about: './about.js'
  },
  output: {
    filename: '[name].js',
    path: './dist'
  },
  plugins: [
    // 将所有入口文件的共同模块提取到vendor.js中
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor', // 公共模块名称
      minChunks: 2, // 至少被多少个入口文件依赖才进行提取
      chunks: ['home', 'about'] // 那些入口文件进行提取
    })
  ]
}
以上就是对Webpack插件的详细解析,通过深入学习Webpack插件,我们不仅可以更好地理解Webpack的构建原理和流程,而且可以通过插件扩展Webpack的功能,提高我们的开发效率。