【读书笔记】《深入浅出nodejs》第二章 模块机制
1.什么是模块?
指在程序设计中,为完成某一功能所需的一段程序或子程序;或指能由编译程序、装配程序等处理的独立程序单位;或指大型软件系统的一部分。 ----《百度百科》
2.JavaScript缺乏模块机制。
-> 薄弱的JavaScript规范:
(1)没有模块系统;
(2)标准库较少(对于I/O流,文件系统等常见需求没有标准API);
(3)没有标准接口(没有Web服务器或数据库之类的标准统一接口);
(4)缺乏包管理系统(使JavaScript应用中基本没有自动加载和安装依赖的能力);
-> CommonJS规范(大部分为草案):
(1)内容:模块 二进制 Buffer 字符集编码 I/O流 进程环境 文件系统 套接字 单元测试 Web服务器网关接口 包管理 ...
(2)目的:使用CommonJS API写出的应用可以具备跨宿主环境执行的能力。
-> CommonJS模块规范:
(1)【模块引用】:
var math = require('math'); // require()方法 -> 接受模块标识,并引入一个模块的API到当前上下文。
(2)【模块定义】:
require() 方法 -> 导入模块
exports() 方法 -> 导出当前模块的方法或变量(唯一的导出口) ----
|----> JS文件中
module对象 -> 存在于模块中,代表模块自身,拥有exports属性 ----
(3)【模块标识】:
传递给require()方法的参数,
必须符合小驼峰命名的字符串,
或以.、..开头的相对路径或绝对路径,
可以没有.js后缀。
->模块规范的意义:
“使用户可以在完全不必考虑变量污染的前提下,建立上下游的依赖关系。”
3.Node的模块实现
(1)模块引入的步骤:
A.【路径分析】(通过模块标识符):
-> 模块标识符的分类:
-> 核心模块,如http、fs、path等;
-> .或..开始的相对路径文件夹;
-> 以/开始的绝对路径文件模块;
-> 非路径形式的文件模块,如自定义的connect模块。
B.【文件定位】
-> 文件扩展名分析
-> 目录分析和包
C.【编译执行】
在Node中,每个文件模块都是一个对象,其定义如下:
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 = [];
}
(2)模块分类:
A.核心模块 -- Node提供的模块 (仅需路径分析,加载速度快)
B.文件模块 -- 用户编写的模块(三步执行,加载速度较慢)
(3)模块的缓存加载:
无论是核心模块还是文件模块,require()方法对相同模块的二次加载都一律采用缓存优先的方式,这是第一优先级的。
4.Node核心模块
(1)JavaScript编写的核心模块(存放在lib目录下) -> 需转存为C/C++代码
*与文件模块的区别:
A. 获取源码的方式(核心模块是从内存中加载的)
B. 缓存执行结构的位置
(2)C/C++编写的核心模块(存放在src目录下)-> 统称为“內建模块”(buffer、crypto、evals、fs、os等模块)
优势:
A. 性能优于脚本语言
B. 被编译进二进制文件,一旦Node开始执行,他们被直接加载仅内存中,无需在做标识符定位、文件定位、编译等过程,直接就可以执行
內建模块的导出:
内建模块 -> 核心模块 -> 文件模块
5.包与NPM
包与NPM是将模块联系起来的一种机制。
模块 -> 一定程度上解决了变量依赖、依赖关系等代码组织性问题
包 -> 在模块的基础上进一步组织JavaScript代码
(1)包规范 -- 帮助Node解决依赖包安装的问题。
A. 包结构
包实际上是一个存档文件,即一个目录直接打包为.zip或tar.gz格式的文件,安装后解压还原为目录。
完全符合CommonJS规范的包目录应该包含如下这些文件。
package.json :包描述文件 -> name(包名),description(简介),version(版本号),keywords(关键词数组),maintainers(包维护者列表)
bin :用于存放可执行二进制文件目录
lib :用于存放JavaScript代码的目录
doc :用于存放文档目录
test :用于存放单元测试用例的代码
B. 包描述
用于表达非代码相关的信息,它是一个JSON格式的文件 -- package.json 位于包的根目录下,是包的重要组成部分。
NPM的所有行为斗鱼包描述文件的字段息息相关。
(2)NPM -- 包规范的一种实践,帮助完成了第三方模块的发布、安装和依赖等。
借助NPM,Node与第三方模块之间形成了很好的生态系统。
借助NPM,可以帮助用户快速安装和管理依赖包。
(3)安装包,引用包,发布包
安装包:$npm install express -> node_modules > express
引用包:require()
发布包:保存js文件 -> $npm init -> $npm adduser -> npm pulish <folder>
(4)NPM的潜在问题 -> 包质量与安全问题
6.前后端功用模块
前后端JavaScript分别搁置在HTTP的两端,他们扮演的角色并不同。
浏览器端的JavaScript需要经历从同一个服务器端分发到多个客户端执行 -> 瓶颈在于带宽 -> 需要网络加载代码(慢)
服务器端的JavaScript需要经历相同的代码需要多次执行 -> 瓶颈在于CPU和内存资源 -> 直接从磁盘中加载(块)
解决的方式 -> AMD规范 && CMD规范
AMD规范:
AMD规范是CommonJS模块的一个延伸。
define(id?, dependencies?, factory);
id : 模块id(可选)
dependencies : 依赖(可选)
factory : 实际的代码内容
CMD规范:
更接近CommonJS规范的定义。
define(factory)
在依赖部分,支持动态引入:
define(function(require, exports, module) {
// The module code goes here
});
require、exports和module通过形参传递给模块,在需要依赖模块时,随时调用require()引入。
【读书笔记】《深入浅出nodejs》第二章 模块机制的更多相关文章
- Linux 读书笔记 三 (第二章)
一.学习目标 1. 理解二进制在计算机中的重要地位 2. 掌握布尔运算在C语言中的应用 3. 理解有符号整数.无符号整数.浮点数的表示 4. 理解补码的重要性 5. 能避免C语言中溢出,数据类型转 ...
- 《Android开发艺术探索》读书笔记 (2) 第2章 IPC机制
2.1 Android IPC简介 (1)任何一个操作系统都需要有相应的IPC机制,Linux上可以通过命名通道.共享内存.信号量等来进行进程间通信.Android系统不仅可以使用了Binder机制来 ...
- 《深入浅出Node.js》第2章 模块机制
@by Ruth92(转载请注明出处) 第2章 模块机制 JavaScript 先天缺乏的功能:模块. 一.CommonJS 规范: JavaScript 规范的缺陷:1)没有模块系统:2)标准库较少 ...
- 《Linux内核设计与实现》读书笔记——第一、 二章
<Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...
- 《Android开发艺术探索》读书笔记 (3) 第3章 View的事件体系
本节和<Android群英传>中的第五章Scroll分析有关系,建议先阅读该章的总结 第3章 View的事件体系 3.1 View基本知识 (1)view的层次结构:ViewGroup也是 ...
- SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)
SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- 读书笔记: 深入浅出node.js
>> 深入浅出node.js node.js是c++编写的js运行环境 浏览器: 渲染引擎 + js引擎 后端的js运行环境 node.js用google v8引擎,同时提供很多系统级的A ...
- 《linux内核设计与实现》读书笔记第一、二章
第一章 Linux内核简介 1.1 Unix的历史 1971年,Unix被移植到PDP-11型机中. 1973年,Unix操作系统用C语言改写——为Unix系统的广泛移植铺平了道路. 1977年,伯克 ...
随机推荐
- Struts2数据验证与使用Java代码进行数据验证
Struts2数据验证 使用Java代码进行数据验证 重写ActionSupport的validate()方法 对Action类的中所有请求处理方法都会进行验证! 对Action类的数据属性进行检查, ...
- CH5E01 乌龟棋【线性DP】
5E01 乌龟棋 0x5E「动态规划」练习 描述 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物.乌龟棋的棋盘是一行N 个格子,每个格子上一个分数(非负整数).棋盘第1 格是唯一的起点,第N 格是终点 ...
- Centos7.0安装mysql5.6
环境 CentOS 7.0(64-bit system) mysql-5.6.37 一.mysql依赖libaio,所以要先安装libaio # yum search libaio ...
- 【Python算法】递归与递归式
该树结构显示了从1(根节点)到n(n个叶节点)的整个倍增过程.节点下的标签表示从n减半到1的过程. 当我们处理递归的时候,这些级数代表了问题实例的数量以及对一系列递归调用来说处理的相关工作量. 当我们 ...
- initialize myObject by calling a function that returns an object literal
w作用域控制变量的可见范围. JavaScript: The Good Parts Instead of initializing myObject with an object literal, w ...
- JavaScript中的原型与原型链
一直对JavaScript的原型与继承不了解,参考<JavaScript权威指南(第六版)>和<JavaScript高级程序设计(第三版)>对这个点的知识做个整理,方便自己记忆 ...
- 一篇搞定MongoDB
MongoDB最基础的东西,我这边就不多说了,这提供罗兄三篇给大家热身 MongoDB初始 MongoDB逻辑与物理存储结构 MongoDB的基础操作 最后对上述内容和关系型数据做个对比 非关系型数据 ...
- 并发编程 - 进程 - 1.开启子进程的两种方式/2.查看pid/3.Process对象的其他属性或方法/4.守护进程
1.开启子进程的两种方式: # 方式1: from multiprocessing import Process import time def task(name): print('%s is ru ...
- Spring Boot 编写入门程序
1. SpringBoot 入门 快速创建独立运行的Spring项目以及与主流框架集成; 使用嵌入式的Servlet容器,应用无需打成WAR包; starters自动依赖与版本控制; 大量的自动配置, ...
- Linux上安装pip以及setuptools
毕竟丰富的第三方库是python的优势所在,为了更加方便的安装第三方库,使用pip命令,我们需要进行相应的安装. 1.安装pip前需要前置安装setuptools 命令如下: wget --no-ch ...