1 npm
Node.js 中的第三方模块又叫做包。
包是基于内置模块封装出来的,提供了更高级、更方便的 API,极大的提高了开发效率。
包和内置模块之间的关系,类似于 jQuery 和 浏览器内置 API 之间的关系。
npm, Inc. 公司提供了一个包管理工具
Node Package Manager(简称 npm 包管理工具)
1.1 安装第三方包
npm i moment
# 安装指定版本
npm i moment@1.1.1
# 一次性安装所有依赖,它会读取package.json的dependencies节点,然后进行安装
npm i
node_modules 文件夹用来存放所有已安装到项目中的包。require() 导入第三方包时,就是从这个目录中查找并加载包。
package-lock.json 配置文件用来记录 node_modules 目录下的每一个包的下载信息,例如包的名字、版本号、下载地址等。
注意:今后在项目开发中,一定要把 node_modules 文件夹,添加到 .gitignore 忽略文件中。
1.2 包管理配置文件
package.json
- 项目的名称、版本号、描述等
- 项目中都用到了哪些包
- 哪些包只在开发期间会用到
- 那些包在开发和部署时都需要用到
快速创建
npm init -y
执行命令时所处的目录中,快速创建 package.json
- 上述命令只能在英文的目录下成功运行!所以,项目文件夹的名称一定要使用英文命名,不要使用中文,不能出现空格。
- 运行 npm install 命令安装包的时候,npm 包管理工具会自动把包的名称和版本号,记录到 package.json 中。
1.3 dependencies 节点
dependencies 节点,专门用来记录使用 npm install 命令安装了哪些包。
—save 的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖。
npm i module_name -S(--save)
默认就是带-S
1.4 卸载包
npm uninstall 包名
# 卸载全局包
npm uninstall 包名 -g
npm uninstall 命令执行成功后,会把卸载的包,自动从 package.json 的 dependencies 中移除掉。
1.5 devDependencies节点
某些包只在项目开发阶段会用到,在项目上线之后不会用到,则把这些包记录到 devDependencies 节点中。
与之对应的,如果某些包在开发和项目上线之后都需要用到,则建议把这些包记录到 dependencies 节点中。
npm i 包名 -D
npm install 包名 --save-dev
1.6 切换镜像源
# 查看镜像源
npm config get registry
# 切换镜像源
npm config set registry=https://registry.npm.taobao.org
# 通过nrm管理,安装nrm
npm i nrm -g
#查看可用镜像
nrm ls
# 切换
nrm use taobao
1.7 包分类
核心依赖包:在开发期间和项目上线之后都会用到
开发依赖包:只在开发期间会用到
全局包:工具性质的包,类似 nrm,因为它们提供了好用的终端命令。
npm i 包名 # 核心依赖包(会被记录到dependencies中)
npm i 包名 -D # 开发依赖包(会被记录到devDependencies)
npm i 包名 -g # 全局包
项目包又分为两类,分别是:
- 开发依赖包(被记录到 devDependencies 节点中的包,只在开发期间会用到)
- 核心依赖包(被记录到 dependencies 节点中的包,在开发期间和项目上线之后都会用到)
1.8 规范包结构
① 包必须以单独的目录而存在
② 包的顶级目录下要必须包含 package.json 这个包管理配置文件
③ package.json 中必须包含 name,version,main 这三个属性,分别代表包的名字、版本号、包的入口。
2 开发属于自己的包
2.1 创建目录
package.json (包管理配置文件)
index.js (包的入口文件)
README.md (包的说明文档)
2.2 定义package.json
{
"name": "kelliden-tools",
"version": "0.0.1",
"main": "index.js",
"description": "格式化时间,html符号转换",
"keywords": ["html", "data", "format"],
"license": "ISC"
}
license 是遵循开源许可协议
2.3 写功能
dataFormat.js:
// 格式化时间
function dataForma(date) {
const dt = new Date(date);
const y = addZero(dt.getFullYear());
const m = addZero(dt.getMonth() + 1);
const d = addZero(dt.getDay());
const hh = addZero(dt.getHours());
const mm = addZero(dt.getMinutes());
const ss = addZero(dt.getSeconds());
return `${y}年${m}月${d}日 ${hh}时${mm}分${ss}秒`
}
function addZero(n) {
return n > 9 ? n : '0' + n;
}
module.exports = {
dataForma
}
htmlEscape.js:
// 转译html字符
function htmlEscape(htmlStr) {
return htmlStr.replace(/<|>|"|&/g, match => {
switch(match) {
case '<':
return '<';
case '>':
return '>';
case '"':
return '"';
case '&':
return '&';
}
})
}
function unHtmlEscape(htmlStr) {
return htmlStr.replace(/<|>|"|&/g, match => {
switch(match) {
case '<':
return '<';
case '>':
return '>';
case '"':
return '"';
case '&':
return '&';
}
})
}
module.exports = {
htmlEscape,
unHtmlEscape
}
index.js:
const date = require('./src/dataFormat')
const escape = require('./src/htmlEscape')
module.exports = {
...date,
...escape
}
2.4 发布与删除
到包的根目录
nrm use npm # 切换回去
npm login # 登录
npm publish # 发布
npm unpublish kelliden-tools --force # 删除
3 模块加载机制
3.1 优先从缓存中加载
模块在第一次加载后会被缓存。
这也意味着多次调用 require() 不会导致模块的代码被执行多次。
注意:不论是内置模块、用户自定义模块、还是第三方模块,它们都会优先从缓存中加载,从而提高模块的加载效率。
3.2 内置模块加载机制
内置模块是由 Node.js 官方提供的模块,内置模块的加载优先级最高。
例如,require(‘fs’) 始终返回内置的 fs 模块,即使在 node_modules 目录下有名字相同的包也叫做 fs。
3.3 自定义模块的加载机制
使用 require() 加载自定义模块时,必须指定以 ./ 或 ../ 开头的路径标识符。
在加载自定义模块时,如果没有指定 ./ 或 ../ 这样的路径标识符,则 node 会把它当作内置模块或第三方模块进行加载。
同时,在使用 require() 导入自定义模块时,如果省略了文件的扩展名,则 Node.js 会按顺序分别尝试加载以下的文件:
- ① 按照确切的文件名进行加载
- ② 补全 .js 扩展名进行加载
- ③ 补全 .json 扩展名进行加载
- ④ 补全 .node 扩展名进行加载 ⑤ 加载失败,终端报错
3.4 第三方模块的加载机制
如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ‘./’ 或 ‘../’ 开头,则 Node.js 会从当前模块的父 目录开始,尝试从 /node_modules 文件夹中加载第三方模块。
如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录。
3.5 目录作为模块
当把目录作为模块标识符,传递给 require() 进行加载的时候,有三种加载方式:
- ① 在被加载的目录下查找一个叫做 package.json 的文件,并寻找 main 属性,作为 require() 加载的入口
- ② 如果目录里没有 package.json 文件,或者 main 入口不存在或无法解析,则 Node.js 将会试图加载目录下的 index.js 文件。
- ③ 如果以上两步都失败了,则 Node.js 会在终端打印错误消息,报告模块的缺失:Error: Cannot find module ‘xxx
-. 常用npm包
-.1 时间格式化包moment
```javascript const moment = require(‘moment’);
const dt = moment().format(‘YYYY年MM月DD日 HH时mm分ss秒’);
console.log(dt);
![image.png](https://cdn.nlark.com/yuque/0/2021/png/1688721/1624331454623-071b0d76-cacc-41e0-b099-b7f13c41c699.png#align=left&display=inline&height=45&margin=%5Bobject%20Object%5D&name=image.png&originHeight=90&originWidth=1126&size=21918&status=done&style=none&width=563)
<a name="RmizU"></a>
## -.2 自动重启项目 nodemon
```shell
# 安装
sudo npm i -g nodemon
# 使用
nodemon app.js
代码被修改之后,会被 nodemon 监听到,从而实现自动重启项目的效果。