发布于 2022年7月17日
152 - 《劫持 node 模块系统》
通常有两种需求,1)劫持内容,2)劫持路径。比如 import ‘foo’,劫持内容指修改 foo 模块内容,劫持路径指修改 foo 模块路径。这两类在 umi 框架也都有不少场景。
下午又有个 Umi 场景需要做路径劫持,在这里整理记录下。
1、劫持内容
劫持内容在 umi 的场景比如用户定义的依赖、插件、mock 文件都是 .ts 格式的,而 node 原生并不支持 .ts,所以需要 require ts 文件时动态做编译。实现通常基于封装好的 privates 库就好。
import { addHook } from 'privates';
const revert = addHook(
(code, fileName) => transform(...),
{ ext: ['.ts'], ignoreNodeModules: true, match: (fileName) => {} }
);
revert();
如果去翻翻 privates 的实现,会发现背后是通过修改 require('module')._extensions 实现的。
const mod = require('module');
mod._extensions['.ts'] = function newLoader(mod, filename) {
mod._compile = (code) => {
const newCode = hook(code, filename);
mod._compile(newCode, filename);
};
};
这个方案有个明显的缺点