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实战(双色)》作者之一——吴中骅访谈录
随机推荐
- LivePhoto开发,你要知道的知识点
前言 Apple从iPhone6s开始支持Live Photo.Live Photo 会录下拍照前后 1.5 秒所发生的一切,因此用户获得的不仅仅是一张精美照片,还有拍照前后时刻的动作和声音.具体的操 ...
- git 忽略 .idea文件
多人开发时,会出现明明在gitignore中忽略了.idea文件夹,但是提交时仍旧会出现.idea内文件变动的情况 原因.idea已经被git跟踪,之后再加入.gitignore后是没有作用的 解决办 ...
- 解决java compiler level does not match the version of the installed java project facet【转载】
原博文地址http://blog.csdn.net/chszs/article/details/8125828 Java compiler level does not match the versi ...
- Golang 入门系列(七) Redis的使用
安装 1. Redis 的安装很简单,我这里测试直接用的是windows 的版本.如何安装就不细说了.想了解的可以看之前的文章:https://www.cnblogs.com/zhangweizhon ...
- iOS开发基础-UIScrollView实现图片缩放
当用户在 UIScrollView 上使用捏合手势时, UIScrollView 会给 UIScrollViewDelegate 协议发送一条消息,并调用代理的 viewForZoomingInScr ...
- 【原创】分布式之大话CAP
引言 本文翻译自博客 http://ksat.me/a-plain-english-introduction-to-cap-theorem/ 博主觉得这个故事讲的生动活泼,因此翻译来给大家分享,顺便加 ...
- 云计算openstack共享组件(3)——消息队列rabbitmq
队列(MQ)概念: MQ 全称为 Message Queue, 消息队列( MQ ) 是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链 ...
- 如何给框架添加API接口日志
前言 用的公司的框架,是MVC框架,看了下里面的日志基类,是操作日志,对增删改进行记录, 夸张的是一张业务的数据表 需要一张专门的日志表进行记录, 就是说你写个更新,添加的方法都必须写一遍操作日志,代 ...
- 数据库主键到底是用自增长(INT)好还是UUID好
其实针对使用自增长还是UUID,大家讨论最多的就是速度和存储空间,这里我加入了安全性和分布式,具体对比如下: 使用自增长做主键的优点:1.很小的数据存储空间2.性能最好3.容易记忆使用自增长做主键的缺 ...
- Android——图片轮播
Android技术——轮播功能 轮播需要什么? 答:实现图片与广告语展示.循环播发以及手动切换.支持加载本地与网络图片. 性能优化? 答:多张图片与指示器展示.自动与定时.循环播发.滑动流畅并且无卡顿 ...