152 - 《劫持 node 模块系统》

发布于 2022年7月17日

通常有两种需求,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);
 };
};

这个方案有个明显的缺点

内容预览已结束

此内容需要会员权限。请先登录以查看完整内容。