> 文章列表 > webpack plugin源码解析(五) ignorePlugin

webpack plugin源码解析(五) ignorePlugin

webpack plugin源码解析(五) ignorePlugin

文章目录

  • 作用
  • 涉及 webpack API
    • normalModuleFactory 普通模块工厂解析
    • require.context 上下文目录匹配
    • contextModuleFactory 上下文引入模块解析
  • 实现
    • constructor
    • apply
    • checkIgnore

作用

  • 忽略某些模块打包,被忽略的模块不能被其他模块引用,否则仍然会被打包进最终的结果中。
new webpack.IgnorePlugin({resourceRegExp: /o1/,  // 要忽略模块的 request 请求正则contextRegExp: /src/, // 要忽略模块所在的上下文目录的正则
}),

涉及 webpack API

  • normalModuleFactory 普通模块工厂解析

    • 通过 import、require 引入的模块
compiler.hooks.normalModuleFactory.tap("IgnorePlugin", nmf => {nmf.hooks.beforeResolve.tap("IgnorePlugin", (resolveData)=>{this.checkIgnore(resolveData,'normal')});
});
  • require.context 上下文目录匹配

    • 自动搜索指定目录下的所有符合条件的模块,并将它们打包到最终的打包结果中
    • require.context 接受三个参数:一个要搜索的目录,一个表示是否搜索子目录的布尔值,以及一个用于匹配模块文件名的正则表达式
const context = require.context('./src', true, /\\.js$/);context.keys().forEach((key) => {const module = context(key);
})
  • contextModuleFactory 上下文引入模块解析

    • 通过 require.context 引入的模块
compiler.hooks.contextModuleFactory.tap("IgnorePlugin", cmf => {cmf.hooks.beforeResolve.tap("IgnorePlugin", (resolveData)=>{this.checkIgnore(resolveData,'context')});
});

实现

constructor

class IgnorePlugin {constructor(options) {validate(options);this.options = options;this.checkIgnore = this.checkIgnore.bind(this);}
}

apply

apply(compiler) {// 普通模块工厂compiler.hooks.normalModuleFactory.tap("IgnorePlugin", nmf => {// 在模块解析前触发,return false 忽略模块,return undefined 处理模块nmf.hooks.beforeResolve.tap("IgnorePlugin", (resolveData)=>{this.checkIgnore(resolveData,'normal')});});// 上下文模块工厂compiler.hooks.contextModuleFactory.tap("IgnorePlugin", cmf => {// 在模块解析前触发,return false 忽略模块,return undefined 处理模块cmf.hooks.beforeResolve.tap("IgnorePlugin", (resolveData)=>{this.checkIgnore(resolveData,'context')});});
}

checkIgnore

  • 根据正则匹配要忽略的模块
checkIgnore(resolveData,type) {console.log(type)if ("checkResource" in this.options &&this.options.checkResource &&// resolveData.request:"./src/index.js"// resolveData.context:"/xxx/Desktop/webpack/wb"this.options.checkResource(resolveData.request, resolveData.context)) {return false;}if ("resourceRegExp" in this.options &&this.options.resourceRegExp &&this.options.resourceRegExp.test(resolveData.request) ) {if ("contextRegExp" in this.options && this.options.contextRegExp) {// if "contextRegExp" is given,// both the "resourceRegExp" and "contextRegExp" have to match.if (this.options.contextRegExp.test(resolveData.context)) {return false;}} else {return false;}}
}