原生module对象
实例属性
console.log(this)
console.log(module)
Module {
id: '.',
path: '/Users/valar/study/nodejs',
exports: {},
parent: null,
filename: '/Users/valar/study/nodejs/test.js',
loaded: false,
children: [],
paths: [
'/Users/valar/study/nodejs/node_modules',
'/Users/valar/study/node_modules',
'/Users/valar/node_modules',
'/Users/node_modules',
'/node_modules'
]
}
静态属性
console.log(module.__proto__.constructor)
_cache: [Object: null prototype] {
'/Users/valar/study/nodejs/test.js': Module {
id: '.',
path: '/Users/valar/study/nodejs',
exports: {},
parent: null,
filename: '/Users/valar/study/nodejs/test.js',
loaded: false,
children: [],
paths: [Array]
}
},
_pathCache: [Object: null prototype] {
'/Users/valar/study/nodejs/test.js\x00': '/Users/valar/study/nodejs/test.js'
},
_extensions: [Object: null prototype] {
'.js': [Function (anonymous)],
'.json': [Function (anonymous)],
'.node': [Function (anonymous)]
},
globalPaths: [
'/Users/valar/.node_modules',
'/Users/valar/.node_libraries',
'/Users/valar/.nvm/versions/node/v14.17.6/lib/node'
],
_debug: [Function: deprecated],
_findPath: [Function (anonymous)],
_nodeModulePaths: [Function (anonymous)],
_resolveLookupPaths: [Function (anonymous)],
_load: [Function (anonymous)],
_resolveFilename: [Function (anonymous)],
createRequireFromPath: [Function: deprecated],
createRequire: [Function: createRequire],
_initPaths: [Function (anonymous)],
_preloadModules: [Function (anonymous)],
syncBuiltinESMExports: [Function: syncBuiltinESMExports],
Module: [Circular *1],
runMain: [Function: executeUserEntryPoint]
console.log(module.__proto__.constructor.prototype)
{
load: [Function (anonymous)],
require: [Function (anonymous)],
_compile: [Function (anonymous)]
}
const fs = require("fs");
const path = require("path");
const vm = require("vm");
function Module(id) {
this.id = id;
this.exports = {};
}
Module._resolveFilename = function (filename) {
const absPath = path.resolve(filename);
if (fs.existsSync(absPath)) {
return absPath;
} else {
let suffix = Object.keys(Module._extensions);
for (let i = 0; i < suffix.length; i++) {
const newPath = absPath + suffix[i];
if (fs.existsSync(newPath)) {
return newPath;
}
}
}
throw new Error(`${filename} is not exists`);
};
Module._extensions = {
".js"(module) {
let content = fs.readFileSync(module.id, "utf-8");
content = Module.wrapper[0] + content + Module.wrapper[1];
let compiledFn = vm.runInThisContext(content);
const exports = module.exports;
const dirname = path.dirname(module.id);
const filename = module.id;
compiledFn.call(exports, exports, myRequire, module, filename, dirname);
},
".json"(module) {
let content = fs.readFileSync(module.id, "utf-8");
content = JSON.parse(content);
module.exports = content;
},
};
Module.wrapper = [
"(function (exports,require,module,__filename,__dirname) {",
"})",
];
Module._cache = {};
Module.prototype.load = function () {
let extname = path.extname(this.id);
Module._extensions[extname](this);
};
function myRequire(filename) {
let mPath = Module._resolveFilename(filename);
let cacheModule = Module._cache[mPath];
if (cacheModule) {
return cacheModule.exports;
}
let module = new Module(mPath);
Module._cache[mPath] = module;
module.load();
return module.exports;
}
let obj = myRequire("a.json");
let obj2 = myRequire("a.json");
console.log(obj);