概述

一、Node 应用由模块组成,采用 CommonJS 模块规范。
三、在服务器端,模块的加载是运行时同步加载的;在浏览器端,模块需要提前编译打包处理。

特点

一、所有代码都运行在模块作用域,不会污染全局作用域。
二、模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
三、模块加载的顺序,按照其在代码中出现的顺序。

基本语法

一、module.exports = value 或exports.xxx = value用来暴露模块,require()用来引入模块

module.exports / exports.xxx

一、暴露模块:module.exports = value或exports.xxx = value

| 【示例】通过module.exports输出变量x和函数addX``` // example.js var x = 5; var addX = function (value) { return value + x; }; module.exports.x = x; module.exports.addX = addX;

  1. |
  2. | --- |
  3. 二、CommonJS暴露的模块到底是什么? <br />CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。
  4. <a name="N8C8C"></a>
  5. ## require
  6. 一、引入模块:require(xxx)<br />1、如果是第三方模块,xxx为模块名;<br />2、如果是自定义模块,xxx为模块文件路径<br />1require命令用于加载模块文件。require命令的基本功能是,读入并执行一个JavaScript文件,然后返回该模块的exports对象。如果没有发现指定模块,会报错。
  7. | 【示例】

var example = require(‘./example.js’);//如果参数字符串以“./”开头,则表示加载的是一个位于相对路径 console.log(example.x); // 5 console.log(example.addX(1)); // 6

 |
| --- |


<a name="AGAb3"></a>
### require查找模块的顺序
一、require查找模块的顺序,即node.js查找模块的顺序<br />见nodejs模块查找策略:[nodejs模块查找策略](https://www.yuque.com/webfront/dsg2th/zzgluu?view=doc_embed)

| 【示例】在文件/home/somebody/workspace/somemodule.js中第一行引用了一个模块:require(‘othermodule‘),请问require查找模块的顺序是: <br />A. /home/somebody/workspace/node_modules/othermodule/index.js <br />B. /home/somebody/workspace/node_modules/othermodule. Js <br />C. CORE MODULES named othermodule <br />D. /home/somebody/node_modules/othermodule/index.js <br />A. C D A B<br />B. C B D A<br />C. C B A D<br />D. C D B A<br />**答案**:C |
| --- |

<a name="UPqgN"></a>
# 模块的加载机制
一、CommonJS模块的加载机制是,输入的是被输出的值的拷贝。<br />1、这点与ES6模块化有重大差异<br />二、CommonJS一旦输出一个值,模块内部的变化就影响不到这个值

| 【示例】下面的代码输出内部变量counter和改写这个变量的内部方法incCounter。

// lib.js var counter = 3; function incCounter() { counter++; } module.exports = { counter: counter, incCounter: incCounter, };

<br />

// main.js var counter = require(‘./lib’).counter; var incCounter = require(‘./lib’).incCounter; console.log(counter); // 3 incCounter(); console.log(counter); // 3 ``` 上面代码说明,counter输出以后,lib.js模块内部的变化就影响不到counter了。这是因为counter是一个原始类型的值,会被缓存。除非写成一个函数,才能得到内部变动后的值。 | | —- |