Plugin

1. 什么是 Plugin

2. 特性

3. 编译生命周期钩子

4. 常见的Plugin

答:

  1. Plugin(Plug-in)是一种计算机应用程序,它和主应用程序互相交互,以提供特定的功能. 是一种遵循一定规范的应用程序接口编写出来的程序,只能运行在程序规定的系统下,因为其需要调用原纯净系统提供的函数库或者数据

webpack中的plugin也是如此,plugin赋予其各种灵活的功能,例如打包优化、资源管理、环境变量注入等,它们会运行在 webpack 的不同阶段(钩子 / 生命周期),贯穿了webpack整个编译周期

目的在于解决loader 无法实现的其他事

2. 特性

其本质是一个具有apply方法javascript对象

apply 方法会被 webpack compiler调用,并且在整个编译生命周期都可以访问 compiler对象

const pluginName = 'ConsoleLogOnBuildWebpackPlugin';

class ConsoleLogOnBuildWebpackPlugin {
  apply(compiler) {
    compiler.hooks.run.tap(pluginName, (compilation) => {
      console.log('webpack 构建过程开始!');
    });
  }
}

module.exports = ConsoleLogOnBuildWebpackPlugin;

3. 关于整个编译生命周期钩子,有如下:

4. 常用Plugin

HtmlWebpackPlugin

在打包结束后,⾃动生成⼀个 html 文件,并把打包生成的js 模块引⼊到该 html 中

<!--./src/html/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body>
    <h1>html-webpack-plugin</h1>
</body>
</html>

在 html 模板中,可以通过 <%=htmlWebpackPlugin.options.XXX%> 的方式获取配置的值

clean-webpack-plugin

删除(清理)构建目录

mini-css-extract-plugin

提取 CSS 到一个单独的文件中

DefinePlugin

允许在编译时创建配置的全局对象,是一个webpack内置的插件,不需要安装

const { DefinePlugun } = require('webpack')

module.exports = {
 ...
    plugins:[
        new DefinePlugin({
            BASE_URL:'"./"'
        })
    ]
}

这时候编译template模块的时候,就能通过下述形式获取全局对象

<link rel="icon" href="<%= BASE_URL%>favicon.ico>"

copy-webpack-plugin

复制文件或目录到执行区域,如vue的打包过程中,如果我们将一些文件放到public的目录下,那么这个目录会被复制到dist文件夹中

new CopyWebpackPlugin({
    patterns:[
        {
            from:"public",
            globOptions:{
                ignore:[
                    '**/index.html'
                ]
            }
        }
    ]
})

复制的规则在patterns属性中设置:

补充

补充:Plugin 与 Loader 的本质区别:

  • loader:文件级"翻译官",A 文件 → B 文件,链式调用从右到左。
  • plugin:构建流程级"拦截器",通过 apply(compiler) 挂到 webpack 生命周期钩子上,可以新增资源、修改产物、删除模块、注入全局变量等。 编写插件模板:
class MyPlugin {
  apply(compiler) {
    compiler.hooks.emit.tapAsync('MyPlugin', (compilation, cb) => {
      for (const file of Object.keys(compilation.assets)) {
        // 读取、修改、新增 compilation.assets[file]
      }
      cb();
    });
  }
}

webpack 5 推荐用 compilation.hooks.processAssets 替代 emit 来处理产物。

来源整理自:我的有道云笔记