Node.js实战项目学习系列(3) CommonJS 模块化规范
前言
想开始编写Node.js代码,那么我们就必须先熟悉它的模块化规范CommonJS,本文将详细讲解CommonJS规范
本文代码 >>> github 地址
CommonJS
Node 应用由模块组成,采用 CommonJS 模块规范。
每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
【特点】
- 所有代码都运行在模块作用域,不会污染全局作用域。
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 模块加载的顺序,按照其在代码中出现的顺序。
新建文件example.js
// example.js
var x = 5;
var addX = function (value) {
return value + x;
};
上面代码中,变量x和函数addX,是当前文件example.js私有的,其他文件不可见。
如果想在多个文件分享变量,必须定义为global对象的属性。
global.warning = true;
上面代码的warning变量,可以被所有文件读取。当然,这样写法是不推荐的。
module.exports
CommonJS规范规定,每个模块内部,module变量代表当前模块。
这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。
加载某个模块,其实是加载该模块的module.exports属性。
新建文件02_module.js
console.log('module');
const NUM = 100;
function test (){
console.log(NUM);
}
// 输出常量
module.exports.num = NUM;
// 输出函数
module.exports.testFn = test;
exports 与 module.exports
它们之间是一层引用关系,exports 引用了 module.exports对象
06_exports.js
console.log(exports,module.exports); // {} , {}
exports.num = '100';
console.log(exports,module.exports); // { num: '100' } { num: '100' }
看上面的代码的输出可以证明exports 引用了 module.exports。那么之前我们采用module.exports输出的内容,其实可以简写为exports输出
【错误的做法】
exports = {
a:1,
b:2
};
上面代码会切断 exports 对 module.exports的引用关系。导致输出的文件,在其它文件是无法使用的
[注意]建议还是使用module.exports规范些,不会产生额外的错误!
require
require方法用于加载模块。
新建文件 03_require.js
const m1 = require('./02_module');
m1.testFn();
执行命令:
node 03_require.js
运行结果:

【路径】
[1] / 表示绝对路径,./ 表示相对于当前文件的路径,
[2] 不写路径则认为是 build-in模块或者各级 node_modules内的第三方模块
const m1 = require('./02_module.js'); // 这样就会在同级目录中寻找02_module.js文件
const m = require('02_module.js'); // 这样只会去 node_modules去寻找相应的文件
【加载文件】
[1]支持js、json、node 拓展名,不写依次尝试加载
const m1 = require('./02_module'); // 这样会在同级目录中寻找 是否有02_module.js 的文件如果有则加载,如果没有则去寻找是否有02_module.json 或者 02_module.node 文件
【特性】
[1]module 被加载的时候执行,加载后缓存
创建文件 04_catch.js
>>> 当我们连续两次引入同一个文件其实只会执行一次
const m1 = require('./02_module');
const m2 = require('./02_module');
// 同时引入两次 02_module文件
我们执行命令 :node 04_catch.js,输出结果:

[2]一旦出现某个模块被循环加载,就只输出已执行的部分,还未执行的部分不会输出
// 1、创建文件:05_modA.js
module.exports.test = 'A';
const modB = require('./05_modB');
console.log('modA: ', modB.test);
module.exports.test = 'AA';
// 2、创建文件:05_modB.js
module.exports.test = 'B';
const modA = require('./05_modA');
console.log('modB: ', modA.test);
module.exports.test = 'BB';
// 3、创建文件:05_main.js
const modA = require('./05_modA');
const modB = require('./05_modB');
我们可以看到 modA中引入modB,modB中也引入了modA,它们形成了循环引用。那么此时执行 node 05_main.js 会输出什么呢?

其实就是遵循上诉原理:一旦出现某个模块被循环加载,就只输出已执行的部分,还未执行的部分不会输出。大家可以动起手来敲敲代码很好理解的。
[注意]平时写代码的时候切记要避免循环引用
Node.js实战项目学习系列(3) CommonJS 模块化规范的更多相关文章
- Node.js实战项目学习系列(1) 初识Node.js
前言 一直想好好学习node.js都是半途而废的状态,这次沉下心来,想好好的学习下node.js.打算写一个系列的文章大概10几篇文章,会一直以实际案例作为贯穿的学习. 什么是node Node.js ...
- Node.js实战项目学习系列(2) 开发环境和调试工具
前言 上一节让我们对Node.js有一个初步的了解,那么现在可以开始正式学习下Node.js的开发了,但是任何一门语言要设计到开发,就必须先学习开发环境以及调试.本文将主要讲解这些内容. 本文涉及到的 ...
- Node.js实战项目学习系列(4) node 对象(global、process进程、debug调试)
前言 在之前的课程我们学习了Node的模块化规则,接下来我们将学习下 Node的几个新特性:global ,process进程,debug调试 global 跟在浏览器中的window一样都是全局变量 ...
- Node.js实战项目学习系列(5) node基础模块 path
前言 前面已经学习了很多跟Node相关的知识,譬如开发环境.CommonJs,那么从现在开始要正式学习node的基本模块了,开始node编程之旅了. path path 模块提供用于处理文件路径和目录 ...
- iKcamp团队制作|基于Koa2搭建Node.js实战项目教学(含视频)☞ 环境准备
安装搭建项目的开发环境 视频地址:https://www.cctalk.com/v/15114357764004 文章 Koa 起手 - 环境准备 由于 koa2 已经开始使用 async/await ...
- 前端(Node.js)(3)-- Node.js实战项目开发:“技术问答”
1.Web 与 Node.js 相关技术介绍 1.1.Web应用的基本组件 web应用的三大部分 brower(GUI)<==>webserver(business logic.data ...
- 开始连载啦~每周2更共11堂iKcamp课|基于Koa2搭建Node.js实战项目教学(含视频)| 课程大纲介绍
- Node.js 实战 & 最佳 Express 项目架构
Node.js 实战 & 最佳 Express 项目架构 Express Koa refs https://github.com/xgqfrms/learn-node.js-by-practi ...
- 《Node.js实战(双色)》作者之一——吴中骅访谈录
随机推荐
- LeetCode算法题-Shortest Unsorted Continuous Subarray(Java实现)
这是悦乐书的第267次更新,第281篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第134题(顺位题号是581).给定一个整数数组,找到一个连续的子数组,按升序对该子数组 ...
- CentOS7.2重置root密码的处理方法
第一个里程碑 --在启动GRUB菜单中选择编辑选项,按键 "e" 进入编辑; 第二个里程碑 -- 大约在第16行找到 "ro" 将 "ro" ...
- 【笔记】Python集成开发环境——PyCharm 2018.3下载、注册、帮助文档
[博客导航] [Python导航] 前言 使用好的开发环境将有效提高编程效率,在Python使用上我是小白,所以特意请教了从事语言处理的成同学,告知我,推荐使用Pycharm和IntelliJ. 目前 ...
- 【Linux基础】mount报错:mount.nfs: Remote I/O error
问题描述:mount 报错:mount.nfs: Remote I/O error 挂载时需要指明版本,由于NFS服务器有多个版本,V2.V3.V4.而且各版本同时运行,因此挂载时需要说明版本号. 由 ...
- github使用个人总结
1.获取github上面的源码时候,不能获取最新的,因为你的开发工作不一定是最新的要下载历史版本. 2.要使用里面的文件的时候,可以在目录后面url后面添加downloads 这样可以找到封装好的版本 ...
- Netstat 常用命令--备忘录
Netstat 用于显示与IP .TCP .UDP 和ICMP 协议相关的统计数据,一般用于检验本机各端口的网络连接情况. 常用参数 -a (all)显示所有选项,默认不显示LISTEN相关-t (t ...
- CF1012A Photo of The Sky
CF1012A Photo of The Sky 有 \(n\) 个打乱的点的 \(x,\ y\) 轴坐标,现在告诉你这 \(2\times n\) 个值,问最小的矩形面积能覆盖住n个点且矩形长和宽分 ...
- openstack-mitaka部署
详见我在51cto的一篇博客:http://egon09.blog.51cto.com/9161406/1839667
- mysql分割逗号办法
https://blog.csdn.net/xcymorningsun/article/details/73436568
- CF452F Permutations/Luogu2757 等差子序列 树状数组、Hash
传送门--Luogu 传送门--Codeforces 如果存在长度\(>3\)的等差子序列,那么一定存在长度\(=3\)的等差子序列,所以我们只需要找长度为\(3\)的等差子序列.可以枚举等差子 ...