CommonJS

CommonJS规范概述

说明

CommonJS对ES规范不曾涉及到的文件(FS),流(Stream),Buffer,Socket等做出了规范,希望JS除了能在浏览器还能再各个系统中运行,Node为其最佳实践由最初命名为ServerJS也可以看出

The project was started by Mozilla engineer Kevin Dangoor in January 2009 and initially named ServerJS.

CommonJS所处位置

在这里插入图片描述

模块化

CommonJS对模块的定义十分简单,主要分为模块引用、模块定义和模块标识3个部分。

引用:
var App = require('express')
定义:
exports.add = function(){}
//OR
module.exports = function(){}
模块定位:

根据.js=>.json=>.node的优先级来查找如果没找到文件而找到一个目录.则会在文件目录下找package.json中的main定义的js为引用模块,如果还是没找到则在当前目录下找index.js如果还是没找到就报错

编译:

模块定义:

function Module(id, parent) {
  this.id = id;
  this.exports = {};
  this.parent = parent;
  if (parent && parent.children) {
    parent.children.push(this);
  }

  this.filename = null;
  this.loaded = false;
  this.children = [];
}
  1. js文件通过fs读取后执行
  2. node这是c++写的文件,通过dlopen()加载最后编译生成的文件
  3. json通过fs读取并用JSON.parse()转换

编译完成后的模块存在一些内置对象如require module exports __filename __dirname是如何做到的喃,其实在编译后形成的js代码如下:

(function (exports, require, module, __filename, __dirname) {
  var math = require('math');
  exports.area = function (radius) {
    return Math.PI * radius * radius;
  };
})
模块读取

根据不同的文件类型有不同的读取方式,以json为例

// Native extension for .json
Module._extensions['.json'] = function(module, filename) {
  var content = NativeModule.require('fs').readFileSync(filename, 'utf8');
  try {
    module.exports = JSON.parse(stripBOM(content));
  } catch (err) {
    err.message = filename + ': ' + err.message;
    throw err;
  }
};

https://blog.csdn.net/dwc_fly/article/details/9902579

模块加载流程

在这里插入图片描述
下面以一段简单的代码来模拟下exports是如何导出的,核心方法是调用了runInThisContext

let Script = require('vm')

var exports = {}
var filename = "test.js"
function requirenew(){
    return exports
}
var source = 
`
    console.log(exports)
    exports.add = function(){console.log('test')}
`
var runInThisContext = Script.runInThisContext;
var wrap = function (script) {
    return wrapper[0] + script + wrapper[1];
};
var wrapper = [
    '(function (exports, module, __filename, __dirname) { ',
    '\n});'
];
source = wrap(source);
var fn = runInThisContext(source, filename, true);
fn(exports, this, filename, filename);
console.log(requirenew())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值