Loading

commonjs规范 require 函数解析

function require(modulePath) {
    //1.根据传入的模块路径 得到模块完整的绝对路径
    const moduleId = getModuleId(modulePath)
    //2.判断缓存
    if (cache[moduleId]) {
        return cache[moduleId]
    }
    //3.真正运行代码模块的辅助函数
    function _require(exports, require, module, __filename, __dirname) {
        //目标模块的代码在这里执行
    }
    //4.准备并运行辅助函数
    const module = {
        exports:{}
    }
    const exports = module.exports
    //得到模块文件的绝对路径
    const __filename = moduleId
    const __dirname = getDirname(__filename)
    _require.call(exports, exports, require, module, __filename, __dirname)
    //5.缓存module.exports
    cache[moduleId] = module.exports
    //6.返回module.exports
    return module.exports
}

getModuleId、getDirname实现细节不必过多关注

模块内代码会放在_require函数内执行,所以可以在代码内直接打印arguments

console.log(argument)

直接执行node test.js 会有以下输出

arguments [Arguments] {
  '0': {},
  '1': [Function: require] {
    resolve: [Function: resolve] { paths: [Function: paths] },
    main: Module {
      id: '.',
      path: '/Users/whh/Documents/webpack5',
      exports: {},
      filename: '/Users/whh/Documents/webpack5/test.js',
      loaded: false,
      children: [],
      paths: [Array]
    },
    extensions: [Object: null prototype] {
      '.js': [Function (anonymous)],
      '.json': [Function (anonymous)],
      '.node': [Function (anonymous)]
    },
    cache: [Object: null prototype] {
      '/Users/whh/Documents/webpack5/test.js': [Module]
    }
  },
  '2': Module {
    id: '.',
    path: '/Users/whh/Documents/webpack5',
    exports: {},
    filename: '/Users/whh/Documents/webpack5/test.js',
    loaded: false,
    children: [],
    paths: [
      '/Users/whh/Documents/webpack5/node_modules',
      '/Users/whh/Documents/node_modules',
      '/Users/whh/node_modules',
      '/Users/node_modules',
      '/node_modules'
    ]
  },
  '3': '/Users/whh/Documents/webpack5/test.js',
  '4': '/Users/whh/Documents/webpack5'
}

_require函数接受exports, require, module, __filename, __dirname参数

所以在commonJS规范下 模块内可直接使用require, module.exports,exports,filename,dirname

_require辅助函数通过.call执行绑定this指向exports

所以在模块加载执行前 this,exports,module.exports是相等的

console.log(this === exports,this === module.exports)

直接执行node test.js上面的代码会打印 true true

最终返回的是module.exports

所以有一下代码test.js

this.a = 1
exports.b = 2
export = {
	c:3
}
module.exports = {
	d:4
}
exports.e = 5
this.f = 6


/**
解析 初始 this = exports = module.exports
执行后:

this,
{a:1,b:2,f:6}

export,
{c:3,e:5}

module.exports,
{d:4}
*/

最终在别的模块内引入

const test = require(./test.js)
console.log(test)

输出

{d:4}
posted @ 2022-11-19 14:33  资深if-else侠  阅读(578)  评论(0编辑  收藏  举报