1// 如果缓存过这个模块就直接从缓存中读取,如果没有缓存就从fs读取文件,并且判断如果是cjs但是type为module就报错,并且从父模块读取详细的行号进行报错,如果没问题就调用 compile
2Module._extensions['.js'] = function(module, filename) {
3 // If already analyzed the source, then it will be cached.
4 // 首先尝试从 cjsParseCache 中获取已经解析过的模块源代码,如果已经缓存,则直接使用缓存中的源代码
5 const cached = cjsParseCache.get(module);
6 let content;
7 if (cached?.source) {
8 content = cached.source; // 有缓存就直接用
9 cached.source = undefined;
10 } else {
11 content = fs.readFileSync(filename, 'utf8'); // 否则从fs读取源代码
12 }
13 // 是不是.js结尾的文件
14 if (StringPrototypeEndsWith(filename, '.js')) {
15 // 读取package.json文件
16 const pkg = packageJsonReader.readPackageScope(filename) || { __proto__: null };
17 // Function require shouldn't be used in ES modules.
18 // 如果package.json文件中有type字段,并且type字段的值为module,并且你使用了require则抛出一个错误,提示不能在ES模块中使用require函数
19 if (pkg.data?.type === 'module') {
20 const parent = moduleParentCache.get(module);
21 const parentPath = parent?.filename;
22 const packageJsonPath = path.resolve(pkg.path, 'package.json');
23 const usesEsm = hasEsmSyntax(content);
24 const err = new ERR_REQUIRE_ESM(filename, usesEsm, parentPath,
25 packageJsonPath);
26 // Attempt to reconstruct the parent require frame.
27 // 如果抛出了错误,它还会尝试重构父模块的 require 调用堆栈,以提供更详细的错误信息。它会读取父模块的源代码,并根据错误的行号和列号,在源代码中找到相应位置的代码行,并将其作为错误信息的一部分展示出来。
28 if (Module._cache[parentPath]) {
29 let parentSource;
30 try {
31 parentSource = fs.readFileSync(parentPath, 'utf8');
32 } catch {
33 // Continue regardless of error.
34 }
35 if (parentSource) {
36 const errLine = StringPrototypeSplit(
37 StringPrototypeSlice(err.stack, StringPrototypeIndexOf(
38 err.stack, ' at ')), '\n', 1)[0];
39 const { 1: line, 2: col } =
40 RegExpPrototypeExec(/(\d+):(\d+)\)/, errLine) || [];
41 if (line && col) {
42 const srcLine = StringPrototypeSplit(parentSource, '\n')[line - 1];
43 const frame = `${parentPath}:${line}\n${srcLine}\n${
44 StringPrototypeRepeat(' ', col - 1)}^\n`;
45 setArrowMessage(err, frame);
46 }
47 }
48 }
49 throw err;
50 }
51 }
52 module._compile(content, filename);
53};