NormalModule 钩子
NormalModule 表示 Rspack 从模块图中解析出、并通过对其源码运行 loader 来构建的模块。它提供了用于介入单个模块构建过程的钩子。
你可以通过如下方式获取这些钩子:
beforeLoaders
SyncHook<[LoaderItem[], NormalModule]>
在模块的 loader 运行之前调用,传入 Rspack 从 module.rules 解析出的 loader 列表以及它们所属的模块。回调中可以新增、删除、重新排序或者修改其中的条目,随后 Rspack 会使用修改后的列表来构建该模块。
每个条目的结构如下:
loader:loader 的绝对路径,不含 options 查询串。options:配置该 loader 时传入的 options 对象;若通过查询串配置则为原始查询串;没有 options 时为undefined。ident:options注册时使用的 key;options 来自内联查询串时为null。type:loader 自身的模块类型('module'、'commonjs'或undefined),由其文件扩展名以及最近的package.json中的type字段推导得出。
若要修改某个 loader 的配置,请替换 options,而不要原地修改该对象。与 webpack 一样,同一条 rule 匹配到的所有模块共享同一个 options 对象,原地修改会影响到所有这些模块;此外 Rspack 无法感知共享对象发生了变化,该 loader 会沿用解析时的缓存 key,因而 Rule.use[].cache 可能返回使用旧 options 产出的结果。
下面的例子会为 src/generated 下的所有模块额外运行一个 loader:
loader 的执行顺序是从右到左,因此通过 push 追加的 loader 会最先执行。对于配置中不存在的新增 loader,Rspack 会按照解析 module.rules 中 loader 的方式来解析它,因此 resolveLoader 与内联的 builtin: loader 在这里同样生效。type 总是在该解析过程中推导得出——无论是新增的条目还是被改写的已有条目——因此 tap 写入的值会被忽略。webpack 则会采纳它,并据此决定加载 loader 时使用 import() 还是 require();在 Rspack 中,请通过改变 loader 的文件扩展名或其 package.json 中的 type 字段来改变它的加载方式。
webpack 会向 beforeLoaders 传入第三个参数 loaderContext,Rspack 没有传入。因为模块的 loader context 要等到 loader runner 启动后才会创建,而这发生在该钩子执行之后。

