調用的是模塊原型上的方法, 當前文件在解析過程當中已經成了模塊對象json
// 模塊類
function Module() { }
Module.prototype.require = function(id) {
// 返回模塊加載內容
return Module._load(id, this, false)
}
function myRequire(filePath) {
// 其實是 mod.require('./test') , mod是當前文件模塊,
return Module.prototype.require(filePath)
}
let r = myRequire('./test')
複製代碼
// 不一樣擴展名文件處理策略
Module._extensions = {
'.js': function() {},
'.json': function() {}
}
// 簡化版 _resolveFilename 方法(無需細究)
Module._resolveFilename = function(require) {
const filePath = path.resolve(__dirname, require)
const exists = fs.existsSync(filePath)
if (exists) {
return filePath
}
let keys = Object.keys(Module._extensions)
for (let i = 0; i < keys.length; i++) {
const currentPath = filePath + keys[i]
if (fs.existsSync(currentPath)) {
return currentPath
}
}
}
Module._load = function(request, parent, isMain) {
// 解析絕對路徑
const fileName = Module._resolveFilename(request, parent, isMain)
// return module.exports
}
複製代碼
function Module(id = '', parent) {
this.id = id
// 父級路徑
this.path = path.dirname(id)
this.exports = {}
this.parent = parent
this.filename = null
this.loaded = false
this.children = []
}
Module._load = function(request, parent, isMain) {
// 解析絕對路徑
const fileName = Module._resolveFilename(request, parent, isMain)
// 建立新的模塊對象
const module = new Module(fileName, parent)
return module.exports
}
複製代碼
Module.prototype.load = function(fileName) {
}
Module._load = function(request, parent, isMain) {
// 解析絕對路徑
const fileName = Module._resolveFilename(request, parent, isMain)
const module = new Module(fileName, parent)
// 將文件內容載入模塊對象
module.load(fileName)
return module.exports
}
複製代碼
Module.prototype.load = function(fileName) {
// const extension = findLongestRegisteredExtension(filename);
const extension = path.extname(fileName)
}
複製代碼
Module._extensions = {
'.js': function() {
},
'.json': function() {
}
}
Module.prototype.load = function(fileName) {
// const extension = findLongestRegisteredExtension(filename);
const extension = path.extname(fileName)
Module._extensions[extension](this, fileName)
}
複製代碼
Module._extensions = {
'.js': function() {},
'.json': function(module, filename) {
// 讀取文件內容 - 字符串
const content = fs.readFileSync(filename, 'utf8');
// 轉化爲對象賦值到 module.exports 上
module.exports = JSON.parse(content)
}
}
複製代碼
Module.warp = function(script) {
let arr = [
'(function(exports, require, module, __filename, __dirname) {',
script,
'})'
]
return arr.join('')
}
Module._extensions = {
'.js': function(module, filename) {
// 讀取文件內容 - 字符串
const content = fs.readFileSync(filename, 'utf8')
// 調用包裝方法將字符串包裝成函數字符串
const wrapper = Module.warp(content)
const compiledWrapper = vm.runInThisContext(wrapper)
// 準備要傳入的參數
const exports = module.exports
const thisValue = exports
const require = myRequire
const dirname = path.dirname(filename)
// 執行函數返回結果
compiledWrapper.call(thisValue, exports, require, module, filename, dirname)
},
'.json': function(module, filename) { }
}
複製代碼
Module._cache = {}
Module._load = function(request, parent, isMain) {
// 解析絕對路徑
const fileName = Module._resolveFilename(request, parent, isMain)
// 查找是否有模塊緩存
const cachedModule = Module._cache[fileName]
if (cachedModule !== undefined) {
// 返回緩存內容
return cachedModule.exports
}
const module = new Module(fileName, parent)
// 將模塊置入緩存
Module._cache[fileName] = module
module.load(fileName)
return module.exports
}
複製代碼
const path = require('path')
const fs = require('fs')
const vm = require('vm')
function Module(id = '', parent) {
this.id = id
// 父級路徑 ..
this.path = path.dirname(id)
this.exports = {}
this.parent = parent
this.filename = null
this.loaded = false
this.children = []
}
function myRequire(filePath) {
return Module.prototype.require(filePath)
}
Module.warp = function(script) {
let arr = [
'(function(exports, require, module, __filename, __dirname) {',
script,
'})'
]
return arr.join('')
}
Module._extensions = {
'.js': function(module, filename) {
// 讀取文件內容 - 字符串
const content = fs.readFileSync(filename, 'utf8')
// 調用包裝方法將字符串包裝成函數字符串
const wrapper = Module.warp(content)
const compiledWrapper = vm.runInThisContext(wrapper)
// 準備要傳入的參數
const exports = module.exports
const thisValue = exports
const require = myRequire
const dirname = path.dirname(filename)
// 執行函數返回結果
compiledWrapper.call(thisValue, exports, require, module, filename, dirname)
},
'.json': function(module, filename) {
// 讀取文件內容 - 字符串
const content = fs.readFileSync(filename, 'utf8')
// 轉化爲對象賦值到 module.exports 上
module.exports = JSON.parse(content)
}
}
Module._resolveFilename = function(require) {
const filePath = path.resolve(__dirname, require)
const exists = fs.existsSync(filePath)
if (exists) {
return filePath
}
let keys = Object.keys(Module._extensions)
for (let i = 0; i < keys.length; i++) {
const currentPath = filePath + keys[i]
if (fs.existsSync(currentPath)) {
return currentPath
}
}
}
Module.prototype.load = function(fileName) {
// const extension = findLongestRegisteredExtension(filename);
const extension = path.extname(fileName)
Module._extensions[extension](this, fileName)
}
Module._cache = {}
Module._load = function(request, parent, isMain) {
// 解析絕對路徑
const fileName = Module._resolveFilename(request, parent, isMain)
// 查找是否有模塊緩存
const cachedModule = Module._cache[fileName]
if (cachedModule !== undefined) {
// 返回緩存內容
return cachedModule.exports
}
const module = new Module(fileName, parent)
// 將模塊置入緩存
Module._cache[fileName] = module
module.load(fileName)
return module.exports
}
Module.prototype.require = function(id) {
return Module._load(id, this, false)
}
let r = myRequire('./test.js')
myRequire('./test.js')
myRequire('./test.js')
console.log(r)
複製代碼