update: CommonJS 规范
This commit is contained in:
parent
d6b0277f05
commit
b291152801
@ -237,12 +237,12 @@ Promise对象, 可以**将异步操作以同步的流程表达出来**。使用
|
|||||||
return request2();
|
return request2();
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
// 接口2请求成功后,打印接口1的返回结果
|
// 接口2请求成功后,打印接口2的返回结果
|
||||||
console.log(data);
|
console.log(data);
|
||||||
return request3();
|
return request3();
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
// 接口3请求成功后,打印接口1的返回结果
|
// 接口3请求成功后,打印接口3的返回结果
|
||||||
console.log(data);
|
console.log(data);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,39 +2,43 @@
|
|||||||
|
|
||||||
## Node.js的介绍
|
## Node.js的介绍
|
||||||
|
|
||||||
### 什么是 Node.js(官方解释)
|
### 什么是 Node.js
|
||||||
|
|
||||||
Node.js 是一个基于 **Chrome V8** 引擎的 JavaScript 代码运行环境。
|
Node.js 是一个基于 **Chrome V8** 引擎的 JavaScript 运行环境。Node.js使用了一个**事件驱动**、**非阻塞式I/O**的模型( Node.js的特性),使其轻量级又高效。Node.js 的包管理工具 npm 是全球最大的开源库生态系统。
|
||||||
|
|
||||||
Node.js使用了一个**事件驱动**、**非阻塞式I/O**的模型( Node.js的特性),使其轻量级又高效。
|
|
||||||
|
|
||||||
Node.js 的包管理器 npm 是全球最大的开源库生态系统。
|
|
||||||
|
|
||||||
![](http://img.smyhvae.com/20180301_1540.png)
|
![](http://img.smyhvae.com/20180301_1540.png)
|
||||||
|
|
||||||
如上图所示:
|
如上图所示:
|
||||||
|
|
||||||
- Node 内部采用 Google Chrome 的 V8 引擎,作为 JavaScript 语言解释器;
|
- Node.js 不是一门语言,也不是 JavaScript 的框架,**Node.js是 JavaScript 语言在服务器端的运行环境(平台)**。
|
||||||
|
|
||||||
- 通过自行开发的 libuv 库,调用操作系统资源。
|
- Node.js 内部采用 Google Chrome 的 V8 引擎,作为 JavaScript 语言解释器;同时结合自行开发的 libuv 库,扩展了 JS 的功能,使得 JS 既可以在前端进行DOM操作(浏览器端),又可以在后端调用操作系统资源(I/O操作、文件读写、数据库操作等),是目前最简单的全栈式语言。
|
||||||
|
|
||||||
|
### Node.js的特点
|
||||||
|
|
||||||
|
- 事件驱动
|
||||||
|
|
||||||
### 什么是 Node.js(非官方解释)
|
- 非阻塞IO模型(异步)
|
||||||
|
|
||||||
**Node.js是 JavaScript 语言在服务器端的运行环境(平台)**。Node.js 不是一门语言,也不是 JavaScript 的框架。
|
- 轻量和高效
|
||||||
|
|
||||||
- 与PHP、JSP、Python、Perl、Ruby的“既是语言,也是平台”不同,Node.js的使用JavaScript进行编程,运行在 Chrome 的 V8 引擎上。
|
|
||||||
|
|
||||||
- 与PHP、JSP等相比(PHP、JSP、.net都需要运行在服务器程序上,Apache、Naginx、Tomcat、IIS。
|
|
||||||
),Node.js跳过了Apache、Naginx、IIS等HTTP服务器,它自己不用建设在任何服务器软件之上。Node.js的许多设计理念与经典架构(LAMP = Linux + Apache + MySQL + PHP)有着很大的不同,可以提供强大的伸缩能力。Node.js没有web容器。
|
|
||||||
|
|
||||||
|
|
||||||
### 运行环境(平台)的含义
|
### 运行环境(平台)的含义
|
||||||
|
|
||||||
- 首先,JavaScript 语言通过 Node 在服务器上运行,在这个意义上,Node 有点像 JavaScript 虚拟机。
|
首先,JavaScript 语言通过 Node 在服务器上运行,在这个意义上,Node 有点像 JavaScript 虚拟机。
|
||||||
|
|
||||||
|
其次,Node 生态系统活跃,提供了大量的开源库,使得 JavaScript 语言能与操作系统进行交互(比如读写文件、新建子进程),在这个层次上,Node 又是属于 JavaScript 的工具库。
|
||||||
|
|
||||||
|
|
||||||
|
**引申**:
|
||||||
|
|
||||||
|
|
||||||
|
与PHP、JSP、Python、Perl、Ruby的“既是语言,也是平台”不同,Node.js的使用JavaScript进行编程,运行在 Chrome 的 V8 引擎上。
|
||||||
|
|
||||||
|
与PHP、JSP等相比(PHP、JSP、.net都需要运行在服务器程序上,Apache、Naginx、Tomcat、IIS。
|
||||||
|
),Node.js跳过了Apache、Naginx、IIS等HTTP服务器,它自己不用建设在任何服务器软件之上。Node.js的许多设计理念与经典架构(LAMP = Linux + Apache + MySQL + PHP)有着很大的不同,可以提供强大的伸缩能力。Node.js没有web容器。
|
||||||
|
|
||||||
- 其次,Node 生态系统活跃,提供了大量的开源库,使得 JavaScript 语言能与操作系统进行交互(比如读写文件、新建子进程),在这个层次上,Node 又是属于 JavaScript 的工具库。
|
|
||||||
|
|
||||||
## Node.js和服务器端开发
|
## Node.js和服务器端开发
|
||||||
|
|
||||||
@ -68,15 +72,15 @@ Node.js 的包管理器 npm 是全球最大的开源库生态系统。
|
|||||||
|
|
||||||
**1、中间层**。
|
**1、中间层**。
|
||||||
|
|
||||||
前端访问中间层,中间层再访问后台的 Java/C++ 服务。这样做的好处是:安全性(不会把主服务器暴露在外面)、提高性能(做缓存等)、降低主服务器的复杂度。
|
前端访问中间层的接口,中间层再访问后台的 Java/C++ 服务。这样做的好处是:安全性(不会把主服务器暴露在外面)、提高性能(做缓存等)、降低主服务器的复杂度。
|
||||||
|
|
||||||
当然,有时候做 Node.js 开发,是因为:后台人力不够,所以把后台开发的一部分工作量,转移给前端同学。
|
当然,有时候做 Node.js 开发,是因为:后台人力不够,所以把后台开发的一部分工作量,转移给前端同学。
|
||||||
|
|
||||||
**2、公司内部工具**。
|
**2、做公司内部工具、项目构建工具**。
|
||||||
|
|
||||||
**3、小型服务**(比如管理系统)。
|
**3、做小型服务、小型网站的后端**(比如管理系统)。
|
||||||
|
|
||||||
需要声明的是:Node.js很难像 Java/C++ 那样,成为后台的主力开发语言。这并非是因为 Node.js的性能问题(实际上,Node.js的性能还不错),主要是因为,Node.js的框架的支持度不够,很难独立成为后台开发语言。
|
需要声明的是:目前来看,Node.js很难像 Java/C++ 那样,成为后台的主力开发语言。这并非是因为 Node.js的性能问题(实际上,Node.js的性能还不错),主要是因为,Node.js的框架的支持度不够,很难独立成为后台开发语言。
|
||||||
|
|
||||||
### Node.js 的组成
|
### Node.js 的组成
|
||||||
|
|
||||||
@ -104,6 +108,8 @@ ECMAScript 是 JS 的语法;DOM 和 BOM 浏览器运行环境为 JS 提供的A
|
|||||||
|
|
||||||
### Node 的历史
|
### Node 的历史
|
||||||
|
|
||||||
|
Node.js 诞生于 2009 年,由 Joyent 的员工 Ryan Dahl 开发而成, 目前官网最新版本已经更新到 13.x.x版本,最新稳定的是10.15.3。
|
||||||
|
|
||||||
- 2008年左右,随着 Ajax 的逐渐普及,Web 开发逐渐走向复杂化,系统化;
|
- 2008年左右,随着 Ajax 的逐渐普及,Web 开发逐渐走向复杂化,系统化;
|
||||||
|
|
||||||
- 2009年2月,Ryan Dahl 想要创建一个轻量级,适应现代 Web 开发的平台;
|
- 2009年2月,Ryan Dahl 想要创建一个轻量级,适应现代 Web 开发的平台;
|
||||||
@ -525,7 +531,7 @@ NPM 默认安装到当前正在使用 Node 版本所在目录下。我们建议
|
|||||||
![](http://img.smyhvae.com/20180302_1210.png)
|
![](http://img.smyhvae.com/20180302_1210.png)
|
||||||
|
|
||||||
|
|
||||||
### NPM的常用命令
|
## NPM的常用命令
|
||||||
|
|
||||||
查看 npm 当前版本:
|
查看 npm 当前版本:
|
||||||
|
|
||||||
@ -545,7 +551,8 @@ npm install npm@latest -g
|
|||||||
```bash
|
```bash
|
||||||
npm init
|
npm init
|
||||||
|
|
||||||
npm init --yes 默认配置
|
# 快速跳过问答式界面,选择默认配置
|
||||||
|
npm init --yes
|
||||||
```
|
```
|
||||||
|
|
||||||
只在当前工程下安装指定的包:
|
只在当前工程下安装指定的包:
|
||||||
@ -554,12 +561,125 @@ npm init --yes 默认配置
|
|||||||
npm install [package]
|
npm install [package]
|
||||||
```
|
```
|
||||||
|
|
||||||
在全局阿浑惊吓安装指定的包:
|
在全局安装指定的包:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm install -g [package]
|
npm install -g [package]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
安装的包只用于开发环境,不用于生产环境:(会出现在 package.json 文件中的 devDependencies 属性中)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install [package] --save-dev
|
||||||
|
|
||||||
|
# 或者
|
||||||
|
npm install [package] -D
|
||||||
|
```
|
||||||
|
|
||||||
|
安装的包需要发布到生产环境:(会出现在 package.json 文件中的 dependencies 属性中)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install [package] --save
|
||||||
|
|
||||||
|
# 或者
|
||||||
|
npm install [package] -S
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
查看当前目录下已安装的node包:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm list
|
||||||
|
```
|
||||||
|
|
||||||
|
查看全局已经安装的node包:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm list -g
|
||||||
|
```
|
||||||
|
|
||||||
|
查看npm帮助命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm --help
|
||||||
|
```
|
||||||
|
|
||||||
|
查看指定命令的帮助:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm [指定命令] --help
|
||||||
|
```
|
||||||
|
|
||||||
|
更新指定的包:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm update [package]
|
||||||
|
```
|
||||||
|
|
||||||
|
卸载指定的包:
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm uninstall [package]
|
||||||
|
```
|
||||||
|
|
||||||
|
查看配置信息:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm config list
|
||||||
|
```
|
||||||
|
|
||||||
|
查看本地安装的指定包的信息,没有则显示empty:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm ls [package]
|
||||||
|
```
|
||||||
|
|
||||||
|
查看全局安装的指定包的信息,没有则显示empty:
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm ls [package] -g
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
查看远程npm上指定包的所有版本信息:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm info [package]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
查看当前包的安装路径:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm root
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
查看全局包的安装路径:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm root -g
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## 配置 npm 镜像源
|
## 配置 npm 镜像源
|
||||||
|
|
||||||
由于 npm 默认的下载地址在国外(npmjs.com),有时候会被墙,导致无法下载或者下载很慢。因此,我们可以尝试切换成,从其他的镜像源下载npm包。
|
由于 npm 默认的下载地址在国外(npmjs.com),有时候会被墙,导致无法下载或者下载很慢。因此,我们可以尝试切换成,从其他的镜像源下载npm包。
|
||||||
@ -568,9 +688,11 @@ npm install -g [package]
|
|||||||
|
|
||||||
- 方式1:临时切换镜像源。
|
- 方式1:临时切换镜像源。
|
||||||
|
|
||||||
- 方式2:通过 NRM 切换镜像源(最为推荐的方式)。
|
- 方式2:切换镜像源
|
||||||
|
|
||||||
- 方式3:cnpm。
|
- 方式3:通过 NRM 切换镜像源(最为推荐的方式)。
|
||||||
|
|
||||||
|
- 方式4:cnpm。
|
||||||
|
|
||||||
下面来分别讲一下。
|
下面来分别讲一下。
|
||||||
|
|
||||||
@ -586,8 +708,15 @@ npm install [package] --registry [https://xxx]
|
|||||||
npm install express --registry https://registry.npm.taobao.org
|
npm install express --registry https://registry.npm.taobao.org
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 方式2:切换镜像源
|
||||||
|
|
||||||
### 方式2:通过 NRM 切换镜像源(推荐)
|
```bash
|
||||||
|
npm config set registry https://registry.npm.taobao.org
|
||||||
|
```
|
||||||
|
|
||||||
|
执行上述命令后,以后下载所有 npm 包的时候,都会改为使用淘宝的镜像源。
|
||||||
|
|
||||||
|
### 方式3:通过 NRM 切换镜像源(推荐)
|
||||||
|
|
||||||
|
|
||||||
**NRM**:Node Registry Manager。作用是:**切换和管理npm包的镜像源**。
|
**NRM**:Node Registry Manager。作用是:**切换和管理npm包的镜像源**。
|
||||||
@ -624,7 +753,7 @@ nrm use taobao
|
|||||||
推荐的国内加速镜像淘宝:<https://npm.taobao.org/>
|
推荐的国内加速镜像淘宝:<https://npm.taobao.org/>
|
||||||
|
|
||||||
|
|
||||||
## 方式3:安装cnpm
|
## 方式4:安装cnpm
|
||||||
|
|
||||||
- 项目地址:<https://npm.taobao.org/>
|
- 项目地址:<https://npm.taobao.org/>
|
||||||
|
|
||||||
|
@ -139,48 +139,195 @@ PS:面试时,经常会问AMD 和 CMD 的区别。
|
|||||||
|
|
||||||
- 在浏览器端: 模块需要提前编译打包处理。首先,既然同步的,很容易引起阻塞;其次,浏览器不认识`require`语法,因此,需要提前编译打包。
|
- 在浏览器端: 模块需要提前编译打包处理。首先,既然同步的,很容易引起阻塞;其次,浏览器不认识`require`语法,因此,需要提前编译打包。
|
||||||
|
|
||||||
|
### 模块的暴露和引入
|
||||||
|
|
||||||
### 暴露模块的方式
|
Node.js 中只有模块作用域,两个模块之间的变量、方法,默认是互不冲突,互不影响,这样就导致一个问题:模块 A 要怎样使用模块B中的变量&方法呢?这就需要通过 `exports` 关键字来实现。
|
||||||
|
|
||||||
**方式一**:
|
Node.js中,每个模块都有一个 exports 接口对象,我们可以把公共的变量、方法挂载到这个接口对象中,其他的模块才可以使用。
|
||||||
|
|
||||||
```javascript
|
接下来详细讲一讲模块的暴露、模块的引入。
|
||||||
module.exports = value
|
|
||||||
|
|
||||||
|
### 暴露模块的方式一: exports
|
||||||
|
|
||||||
|
`exports`对象用来导出当前模块的公共方法或属性。别的模块通过 require 函数调用当前模块时,得到的就是当前模块的 exports 对象。
|
||||||
|
|
||||||
|
**语法格式**:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// 相当于是:给 exports 对象添加属性
|
||||||
|
exports.xxx = value
|
||||||
```
|
```
|
||||||
|
|
||||||
这个 value 可以是任意的数据类型。
|
这个 value 可以是任意的数据类型。
|
||||||
|
|
||||||
**方式二**:
|
**注意**:暴露的关键词是`exports`,不是`export`。其实,这里的 exports 类似于 ES6 中的 export 的用法,都是用来导出一个指定名字的对象。
|
||||||
|
|
||||||
```javascript
|
|
||||||
exports.xxx = value
|
|
||||||
|
**代码举例**:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const name = 'qianguyihao';
|
||||||
|
exports.name = name;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
**问题**: 暴露的模块到底是谁?
|
|
||||||
|
### 暴露模块的方式二: module.exports
|
||||||
|
|
||||||
|
`module.exports`用来导出一个默认对象,没有指定对象名。
|
||||||
|
|
||||||
|
语法格式:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 方式一:导出整个 exports 对象
|
||||||
|
module.exports = value;
|
||||||
|
|
||||||
|
// 方式二:给 exports 对象添加属性
|
||||||
|
module.exports.xxx = value;
|
||||||
|
```
|
||||||
|
|
||||||
|
这个 value 可以是任意的数据类型。
|
||||||
|
|
||||||
|
代码举例:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// 方式1
|
||||||
|
module.exports = {
|
||||||
|
name: '我是 module1',
|
||||||
|
foo(){
|
||||||
|
console.log(this.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 我们不能再继续写 module.exports = value2。因为重新赋值,会把 exports 对象 之前的赋值覆盖掉。
|
||||||
|
|
||||||
|
// 方式2
|
||||||
|
const age = 28;
|
||||||
|
module.exports.age = age;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`module.exports` 还可以修改模块的原始导出对象。比如当前模块原本导出的是一个对象,我们可以通过 module.exports 修改为导出一个函数。如下:
|
||||||
|
|
||||||
|
```js
|
||||||
|
module.exports = function () {
|
||||||
|
console.log('hello world')
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### exports 和 module.exports 的区别
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
最重要的区别:
|
||||||
|
|
||||||
|
- 使用exports时,只能单个设置属性 `exports.a = a;`
|
||||||
|
|
||||||
|
- 使用module.exports时,既单个设置属性 `module.exports.a`,也可以整个赋值 `module.exports = obj`。
|
||||||
|
|
||||||
|
其他要点:
|
||||||
|
|
||||||
|
- Node中每个模块的最后,都会执行 `return: module.exports`。
|
||||||
|
|
||||||
|
- Node中每个模块都会把 `module.exports`指向的对象赋值给一个变量 `exports`,也就是说 `exports = module.exports`。
|
||||||
|
|
||||||
|
- `module.exports = XXX`,表示当前模块导出一个单一成员,结果就是XXX。
|
||||||
|
|
||||||
|
- 如果需要导出多个成员,则必须使用 `exports.add = XXX; exports.foo = XXX`。或者使用 `module.exports.add = XXX; module.export.foo = XXX`。
|
||||||
|
|
||||||
|
### 问题: 暴露的模块到底是谁?
|
||||||
|
|
||||||
**答案**:暴露的本质是`exports`对象。【重要】
|
**答案**:暴露的本质是`exports`对象。【重要】
|
||||||
|
|
||||||
比如,方式二可以理解成是,**给 exports 对象添加属性**。
|
比如,方式一的 `exports.a = a` 可以理解成是,**给 exports 对象添加属性**。方式二的 `module.exports = a`可以理解成是给整个 exports 对象赋值。方式二的 `module.exports.c = c`可以理解成是给 exports 对象添加属性。
|
||||||
|
|
||||||
PS:暴露的关键词是`exports`,不是`export`。
|
Node.js 中每个模块都有一个 module 对象,module 对象中的有一个 exports 属性称之为**接口对象**。我们需要把模块之间公共的方法或属性挂载在这个接口对象中,方便其他的模块使用。
|
||||||
|
|
||||||
|
|
||||||
|
### 引入模块的方式:require
|
||||||
|
|
||||||
|
require函数用来在一个模块中引入另外一个模块。传入模块名,返回模块导出对象。
|
||||||
|
|
||||||
### 引入模块的方式
|
**语法格式**:
|
||||||
|
|
||||||
```
|
```js
|
||||||
require(xxx)
|
const module1 = require('模块名');
|
||||||
```
|
```
|
||||||
|
|
||||||
解释:
|
解释:
|
||||||
|
|
||||||
- 内置模块:xxx 为模块名(包名)
|
- 内置模块:require的是**包名**。
|
||||||
|
|
||||||
- 下载的第三方模块:xxx为模块名(包名)。
|
- 下载的第三方模块:require的是**包名**。
|
||||||
|
|
||||||
- 自定义模块:xxx为模块文件路径。
|
- 自定义模块:require的是**文件路径**。文件路径既可以用绝对路径,也可以用相对路径。后缀名`.js`可以省略。
|
||||||
|
|
||||||
|
|
||||||
|
**代码举例**:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const module1 = require('./main.js');
|
||||||
|
|
||||||
|
const module2 = require('./main');
|
||||||
|
|
||||||
|
const module3 = require('Demo/src/main.js');
|
||||||
|
```
|
||||||
|
|
||||||
|
**require()函数的两个作用**:
|
||||||
|
|
||||||
|
- 执行导入的模块中的代码。
|
||||||
|
|
||||||
|
- 返回导入模块中的接口对象。
|
||||||
|
|
||||||
|
|
||||||
|
### 主模块
|
||||||
|
|
||||||
|
主模块是整个程序执行的入口,可以调度其他模块。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 运行main.js启动程序。此时,main.js就是主模块
|
||||||
|
$ node main.js
|
||||||
|
```
|
||||||
|
|
||||||
|
### 模块的初始化
|
||||||
|
|
||||||
|
一个模块中的 JS 代码仅在模块**第一次被使用时**执行一次,并且在使用的过程中进行初始化,然后会被缓存起来,便于后续继续使用。
|
||||||
|
|
||||||
|
代码举例:
|
||||||
|
|
||||||
|
(1)calModule.js:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var a = 1;
|
||||||
|
|
||||||
|
function add () {
|
||||||
|
return ++a;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.add = add;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
(2)main.js:(在 main.js 中引入 hello.js 模块)
|
||||||
|
|
||||||
|
```js
|
||||||
|
var addModule1 = require('./calModule')
|
||||||
|
var addModule2 = require('./calModule')
|
||||||
|
|
||||||
|
console.log(addModule1.add());
|
||||||
|
console.log(addModule2.add());
|
||||||
|
```
|
||||||
|
|
||||||
|
在命令行执行 `node main.js` 运行程序,打印结果:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
2
|
||||||
|
3
|
||||||
|
```
|
||||||
|
|
||||||
|
从打印结果中可以看出,`calModule.js`这个模块虽然被引用了两次,但只初始化了一次。
|
||||||
|
|
||||||
|
|
||||||
## CommonJS 在服务器端的实现举例
|
## CommonJS 在服务器端的实现举例
|
||||||
|
171
11-Node.js和模块化/03-Node.js内置模块:fs文件模块.md
Normal file
171
11-Node.js和模块化/03-Node.js内置模块:fs文件模块.md
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
|
||||||
|
## CommonJS 规范
|
||||||
|
|
||||||
|
CommonJS 规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口对象。加载某个模块,其实是加载该模块的 module.exports 对象。
|
||||||
|
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var x = 5;
|
||||||
|
var addX = function (value) {
|
||||||
|
return value + x;
|
||||||
|
};
|
||||||
|
module.exports.x = x;
|
||||||
|
module.exports.addX = addX;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Node.js 的API文档
|
||||||
|
|
||||||
|
Node.js 的API文档: <https://nodejs.org/docs/latest-v8.x/api/index.html>
|
||||||
|
|
||||||
|
查阅文档时的常见规律:
|
||||||
|
|
||||||
|
- 红色:表示已废弃。
|
||||||
|
|
||||||
|
- 绿色:表示100%安全使用。
|
||||||
|
|
||||||
|
- 黄颜色:表示当前版本可用,其他版本不确定。
|
||||||
|
|
||||||
|
|
||||||
|
## Node.js 中模块的分类
|
||||||
|
|
||||||
|
|
||||||
|
Node.js 应用由模块组成,采用 CommonJS 模块规范。Node.js中的模块分为三种:
|
||||||
|
|
||||||
|
- 内置模块
|
||||||
|
|
||||||
|
- 第三方模块
|
||||||
|
|
||||||
|
- 自定义模块
|
||||||
|
|
||||||
|
下面简单介绍一下。
|
||||||
|
|
||||||
|
### 1、内置模块
|
||||||
|
|
||||||
|
```js
|
||||||
|
const process = require('process');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
console.log(process.version);
|
||||||
|
console.log(path.resolve('../'));
|
||||||
|
```
|
||||||
|
|
||||||
|
require方法用于加载模块。
|
||||||
|
|
||||||
|
### 2、require 加载第三方包的机制
|
||||||
|
|
||||||
|
```js
|
||||||
|
const express = require('express');
|
||||||
|
```
|
||||||
|
|
||||||
|
require 加载第三方包的机制:
|
||||||
|
|
||||||
|
(1)第三方包安装好后,这个包一般会存放在当前项目的 node_modules 文件夹中。我们找到这个包的 package.json 文件,并且找到里面的main属性对应的入口模块,这个入口模块就是这个包的入口文件。
|
||||||
|
|
||||||
|
(2)如果第三方包中没有找到package.json文件,或者package.json文件中没有main属性,则默认加载第三方包中的index.js文件。
|
||||||
|
|
||||||
|
(3)如果在 node_modules 文件夹中没有找到这个包,或者以上所有情况都没有找到,则会向上一级父级目录下查找node_modules文件夹,查找规则如上一致。
|
||||||
|
|
||||||
|
(4)如果一直找到该模块的磁盘根路径都没有找到,则会报错:can not find module xxx。
|
||||||
|
|
||||||
|
**3、自定义模块(module)**:
|
||||||
|
|
||||||
|
每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
|
||||||
|
|
||||||
|
举例:
|
||||||
|
|
||||||
|
```
|
||||||
|
var example = require('./example.js');
|
||||||
|
console.log(example.x); // 5
|
||||||
|
console.log(example.addX(1)); // 6
|
||||||
|
```
|
||||||
|
|
||||||
|
今天这篇文章,重点讲一下内置模块中的 **fs 文件处理模块**。
|
||||||
|
|
||||||
|
## 文件读取
|
||||||
|
|
||||||
|
fs 的英文全称是 File System。fs 模块提供了很多api方法,我们首先应该学习的方法是**文件读取**。
|
||||||
|
|
||||||
|
Node中文件读取的方式主要有以下几种。
|
||||||
|
|
||||||
|
|
||||||
|
### 异步读取文件 fs.readFile()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
语法格式:
|
||||||
|
|
||||||
|
```js
|
||||||
|
fs.readFile(file[, options], callback(error, data))
|
||||||
|
```
|
||||||
|
|
||||||
|
代码举例:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
fs.readFile('c:\\demo\1.txt', 'utf8', (err, data) => {
|
||||||
|
if (err) throw err;
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 同步读取文件 fs.readFileSync()
|
||||||
|
|
||||||
|
语法格式:
|
||||||
|
|
||||||
|
```js
|
||||||
|
fs.readFileSync(file[, options])
|
||||||
|
```
|
||||||
|
|
||||||
|
代码举例:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
try {
|
||||||
|
const data = fs.readFileSync('c:\\demo\1.txt', 'utf8');
|
||||||
|
console.log(data);
|
||||||
|
} catch(e) {
|
||||||
|
// 文件不存在,或者权限错误
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Node.js 中的异步操作
|
||||||
|
|
||||||
|
fs模块对文件的几乎所有操作都有同步和异步两种形式。例如:readFile() 和 readFileSync()。
|
||||||
|
|
||||||
|
|
||||||
|
区别:
|
||||||
|
|
||||||
|
- 同步调用会阻塞代码的执行,异步则不会。
|
||||||
|
|
||||||
|
- 异步调用会将 读取任务 下达到任务队列,直到任务执行完成才会回调。
|
||||||
|
|
||||||
|
- 异常处理方面,同步必须使用 try catch 方式,异步可以通过回调函数的第一个参数。【重要】
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
console.time('async');
|
||||||
|
fs.readFile(path.join('C:\\Users\\qianguyihao\\Downloads', 'H.mp4'), (error, data) => {
|
||||||
|
if (error) throw error;
|
||||||
|
// console.log(data);
|
||||||
|
});
|
||||||
|
console.timeEnd('async');
|
||||||
|
|
||||||
|
|
||||||
|
console.time('sync');
|
||||||
|
try {
|
||||||
|
var data = fs.readFileSync(path.join('C:\\Users\\qianguyihao\\Downloads', 'H.mp4'));
|
||||||
|
// console.log(data);
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
console.timeEnd('sync');
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## JS相关
|
||||||
|
|
||||||
|
- JS装饰器
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 性能相关
|
## 性能相关
|
||||||
|
|
||||||
- 防抖和节流
|
- 防抖和节流
|
||||||
|
Loading…
Reference in New Issue
Block a user