Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CommonJS规范 #4

Open
binperson opened this issue Nov 23, 2017 · 3 comments
Open

CommonJS规范 #4

binperson opened this issue Nov 23, 2017 · 3 comments

Comments

@binperson
Copy link
Owner

参考 CommonJS规范

概述

  • 所有代码都运行在模块作用域,不会污染全局作用域。
  • 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
  • 模块加载的顺序,按照其在代码中出现的顺序。
//example.js
var x = 5;
var addX = function (value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

//加载模块
var example = require('./example.js');
console.log(example.x); // 5
console.log(example.addX(1)); // 6
@binperson
Copy link
Owner Author

module对象

  • module.id 模块的识别符,通常是带有绝对路径的模块文件名。
  • module.filename 模块的文件名,带有绝对路径。
  • module.loaded 返回一个布尔值,表示模块是否已经完成加载。
  • module.parent 返回一个对象,表示调用该模块的模块。
  • module.children 返回一个数组,表示该模块要用到的其他模块。
  • module.exports 表示模块对外输出的值。

module.exports属性

module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports变量。

exports变量

为了方便,Node为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令。

var exports = module.exports;

造成的结果是,在对外输出模块接口时,可以向exports对象添加方法。

exports.area = function (r) {
  return Math.PI * r * r;
};

exports.circumference = function (r) {
  return 2 * Math.PI * r;
};

不能直接将exports变量指向一个值,因为这样等于切断了exports与module.exports的联系。

exports = function(x) {console.log(x)};
module.exports = function (x){ console.log(x);};

如果模块输出的是一个函数,那就不能定义在exports对象上面,而要定义在module.exports变量上面。

// a.js
module.exports = function () {
  console.log("hello world")
}
//b.js
require('./a.js')()

@binperson
Copy link
Owner Author

require命令

  • 基本用法
  • 加载规则
  • 目录的加载规则
  • 模块的缓存
require('./example.js');
require('./example.js').message = "hello";
require('./example.js').message
// "hello"

连续三次使用require命令,加载同一个模块。第二次加载的时候,为输出的对象添加了一个message属性。但是第三次加载的时候,这个message属性依然存在,这就证明require命令并没有重新加载模块文件,而是输出了缓存。

// 删除指定模块的缓存
delete require.cache[moduleName];

// 删除所有模块的缓存
Object.keys(require.cache).forEach(function(key) {
  delete require.cache[key];
})
  • 环境变量NODE_PATH
  • 模块的循环加载
  • require.main

@binperson
Copy link
Owner Author

模块的加载机制

CommonJS模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值

  • require的内部处理流程

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant