阅读 124

初识Webpack(三)

这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战

插件plugin

插件webpack 除了loader以外的另一个核心功能。而通过对Webpack源码的观察,我们发现Webpack自身也是构建于各类插件之上。

插件目的在于解决上一篇文章所介绍的loader 无法实现的事。通过上篇文章的介绍,我们知道了loader的主要作用是对各类的文件的解析、预处理。但如果仅有这些对于我们的日常开发是远远不够的,这也是插件所补充的部分。

如何使用插件

我们日常开发中如果需要使用Webpack插件,就需要在webpack.config.js中进行配置,比如:

const HtmlWebpackPlugin = require('html-webpack-plugin'); 
const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    filename: 'my-first-webpack.bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        use: 'babel-loader',
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({ template: './src/index.html' }),
  ],
};
复制代码

上面的例子中首先通过require加载通过npm安装的插件,接着在module.exports中的plugins中传入我们所需要的插件的实例,这里通过new来创建一个插件的实例并进行加载。这里的例子是一个解析html的插件,插件需要传入一个参数是需要处理的html的相对路径,然后插件内部对该html进行解析,构建。该插件将为你生成一个 HTML5 文件, 在 body 中使用 script 标签引入你所有 webpack 生成的 bundle。HtmlWebpackPlugin简化了 HTML 文件的创建,以便为你的 webpack 包提供服务。这对于那些文件名中包含哈希值,并且哈希值会随着每次编译而改变的 webpack 包特别有用。

一个插件是如何开发的

plugins是可以用自身原型方法apply来实例化的对象。apply只在安装插件被Webpack compiler执行一次。apply方法传入一个webpck compiler的引用,来访问编译器回调。一个简单的插件代码结构是这样:

class Plugin {
  constructor(options) {}
  apply(compiler) {
    //...
  }
}

module.exports = Plugin
复制代码

这里以HtmlWebpackPlugin的代码为例:

apply(compiler){
    compiler.hooks.make.tapAsync(
         //...
    )
}
复制代码

这里的compiller.hooks.make()函数,这是一个异步并发 AsyncParallelBailHook 钩子,也就是在编译完成之前执行的钩子函数,compiler里有很多钩子函数是在webpackcompile编译过程的不同阶段进行操作的钩子,这样也就扩展了我们的webpack的功能。

插件的执行过程

首先介绍一下CompilerCompiler 模块是 webpack 的核心引擎,它通过 CLI 或 Node API 传递的所有选项,创建出一个 compilation 实例。它扩展(extend)自 Tapable 类,以便于我们注册和调用插件。大多数面向用户的插件首先在 Compiler 上注册。

监听

Compiler 支持可以监控文件系统的监听(watching)机制,并且在文件修改时重新编译。当处于监听模式(watch mode)时,compiler 会触发诸如 watchRunwatchClose 和 invalid 等额外的事件。通常用于开发环境中使用,也常常会在 webpack-dev-server 这些工具的底层之下调用,由此开发人员无须每次都使用手动方式重新编译。还可以通过 CLI 进入监听模式。

执行过程
  1. Webpack开始读取插件配置的过程中会先执行 new xxxPlugin(options) 初始化一个 xxxxPlugin插件来获得其实例。
  2. 在初始化 compiler 对象后调用 xxxxPlugin.apply(compiler) 给插件实例传入 compiler 对象。
  3. 插件实例在获取到 compiler 对象后,就可以通过compiler.plugin(事件名称, 回调函数) 监听到 Webpack广播出来的事件。然后根据不同的事件,进行不同的操作。并且可以通过 compiler 对象去操作 Webpack

几个强烈推荐学习的插件源码

文章分类
前端
文章标签