Node.js学习第三天

Node.js学习第三天

1.模块化

1.1 模块化的定义

  • 模块化指解决一个复杂问题时,自顶向下逐层把系统划分为若干模块的过程。对应整个系统来说,模块是可组合、分解、更换的单元

1.2 编程领域的模块化

  • 遵守固定的规则,把一个大文件拆分成独立并相互依赖的多个小模块
  • 好处
    • 提高了代码的复用性
    • 提供了代码的可维护性
    • 可以实现按需加载

1.3 模块化的规范

  • 对代码进行模块化的拆分和组合时,需要遵守的那些规则
    • 使用什么样的语法格式来引用模块
    • 在模块中使用什么样的语法格式向外暴露成员

2.Node.js中的模块化

2.1 Node.js中模块的分类

  • 内置模块:Node.js官方提供,如fs,path,http
  • 自定义模块:用户创建的每个.js文件
  • 第三方模块:由第三方开发出来的模块,并非官方提供,也不是用户创建的自定义模块,使用前需要下载

2.2 加载模块

  • 使用require()方法,可以加载需要的内置模块,用户自定义模块,第三方模块
// 加载fs模块
const fs = require('fs')
//加载用户自定义模块
const zdy = require('./zdy.js')
// 加载第三方模块
const moment=require('moment')

示例

  • zdy.js
console.log("自定义模块被加载");
  • test.js
const zdy = require('./02.zdy.js')
console.log(zdy);
  • 运行test.js效果图

注意点

  • 使用require()方法加载其他模块时,会执行被加载模块中的代码

  • 使用require()方法加载自定义模块时,可以省略.js后缀名

const zdy = require('./02.zdy')
console.log(zdy);

2.3 模块作用域

  • 和函数作用域类似,在自定义模块中定义的变量、方法,只能在当前模块内被访问
  • 图解

  • 好处

    • 防止了全局变量污染的问题

示例

  • zdy.js
console.log("自定义模块被加载");
const ename = '张三';
  • test.js
const zdy = require('./02.zdy.js')
console.log(zdy);
  • 效果图

2.4 向外共享模块作用域中的成员

2.4.1 module对象

  • 每个.js自定义模块中都有一个module对象,里面存储了和当前模块有关的信息
示例
console.log(module);
  • 效果图

2.4.2 module.exports对象

  • 在自定义模块中,可以使用module.exports对象,将模块内的成员共享出去,供外界使用
  • 使用require()方法导入自定义模块时,得到的就是module.exports所指向的对象
示例
  • 自定义模块.js
// 在module.exports对象上挂载 username属性
module.exports.username = 'zs';
// 在module.exports对象上挂载sayHello()方法
module.exports.sayHello = function() {
console.log("hello!");
}
const age = 20;
module.exports.age = age;
  • 测试.js
const zdy = require('./06.自定义模块')
console.log(zdy);
  • 效果图

2.4.3 共享成员时的注意点

  • 使用require()方法导入模块时,导入的结果,永远以module.exports指向的对象为准
示例
  • 自定义模块2
// 要共享的成员永远以module.exports指向的对象为准
module.exports.username = 'zd';
module.exports.sayHello = function() {
console.log("hello");
}
// 指向另一个对象
module.exports = {
ename: 'k',
eage: '18',
sayHi() {
console.log("Hi");
}
}
  • 测试
const zdy2 = require('./08.自定义模块2')
console.log(zdy2);
  • 效果图

2.4.4 exports对象

  • exports对象和module.exports指向同一个对象,最终共享的结果,以module.exports指向的对象为准

  • 示例

console.log(exports);
console.log(module.exports);
console.log(exports === module.exports);
  • 效果图

示例
  • 自定义模块3
module.exports.age = '19'
exports.username = 'zs'
exports.age = '18'
exports.sayHello = function() {
console.log("Hello");
}
  • 测试
const zdy3 = require('./11.自定义模块3')
console.log(zdy3);
  • 效果图

2.4.5 exports 和module.exports的使用误区

  • 得到的永远是module.exports指向的对象
  • 为了防止混乱,不要同时使用exports和module.exports

QQ截图20220313165905

QQ截图20220313170037

QQ截图20220313170214

2.4.6 Node.js中的模块化规范

  • 遵循CommonJs模块化规范
  • CommonJs规定
    • 每个模块内部,module变量代表当前模块
    • module变量是一个对象,他的exports属性(即module.exports)是对外的接口
    • 加载某个模块,其实就是加载该模块的module.exports属性,require()方法用于加载模块

3.npm和包

3.1 包

  • Node.js中的第三方模块叫做包
  • 包由第三方个人或团队开发出来的
  • Node.js的包免费开源

3.2 包的作用

  • Node.js的内置模块仅仅提供了一些底层的API,包是基于内置模块封装出来的,提高了开发效率
  • 包与内置模块的关系,类似与jQuery和浏览器内置API之间的关系

3.3 包的下载

3.4 moment包的使用

  • 普通方法格式化日期
  • 自定义日期格式化模块
function dateFormat(dt) {
var y = dt.getFullYear();
var m = padZero(dt.getMonth() + 1);
var d = padZero(dt.getDate());
var h = padZero(dt.getHours());
var mm = padZero(dt.getMinutes());
var s = padZero(dt.getSeconds());
return `${y}-${m}-${d} ${h}:${mm}:${s}`
}
// 补零函数
function padZero(n) {
return n < 10 ? '0' + n : n;
}
module.exports = {
dateFormat
}
  • 测试日期格式化模块
var format = require('./14.自定义日期格式化')
var date = new Date();
var str = format.dateFormat(date);
console.log(str);
  • 效果图

直接使用moment包来格式化日期

  • 下载包(管理员身份运行,先进入项目所在目录,再下载)
npm install moment
  • 使用文档

<Moment.js | Docs (momentjs.com)>

// 导入moment包
const mt = require("moment")
// mt()获取当前时间,format日期格式化
var dt = mt().format("YYYY-MM-DD HH:mm:ss");
console.log(dt);
  • 效果图

3.4 装包后多的文件

  • node_modules文件夹和package-lock.json的配置文件
  • node_modules用来存放已安装到项目中的包,require()导入第三方包时,从这个目录查找并加载包
  • package-lock.json:记录每一个包下的下载信息,例如包名,版本号等

3.5 包的版本号

  • 格式:点分十进制,三位数字,如2.24.0

    • 第一位数字:大版本:底层重新设计
    • 第二位数字:功能版本:功能增添
    • 第三位数字:bug修复版本:修复bug
  • 版本提升规则:只要前面的版本号增长了,后面的版本号归零

3.6 包管理配置文件

  • npm规定:在项目根目录中,必须提供一个叫做package.json的包管理配置文件,记录相关信息
    • 项目的名称,版本号,描述
    • 项目中都用到了哪些包
    • 哪些包只在开发期间会用到
    • 哪些包在开发和部署阶段都需要用到

QQ截图20220314121151

  • package.json配置文件

    • 创建方法
    npm init -y
    • 注意点
      • 只能在英文的目录下成功运行,不能使用中午,不能使用空格
      • 创建成功后,提高npm install 命令安装包时,npm包管理工具会自动的把包的名称和版本号,记录到package.json中
  • dependencies 节点

    • package.json 配置文件中的节点
    • 专门记录安装了哪些包

  • 同时安装多个包,包名之间用空格隔开

npm i jquery art-template
  • 一次性安装所有的依赖包(存在package.json配置文件)
// 执行npm install 或 npm i 命令时,npm包管理工具会读取package.json 中的dependencies 节点
// 读取节点中的包名称和版本号后,就会把这些包一次性全部下载
npm install
  • 卸载包
    • 卸载包之后,package.json的dependencies节点的相关记录也会删除
npm uninstall 包的名称
  • devDependencies节点

    • 节点中的包在项目开发阶段会用到,项目上线后不会用到
  • Dependencies节点

    • 节点中的包在开发和上线后都需要用到
  • 将包记录到devDependencies节点中

    npm i 包名 -D
    // 或者
    npm install 包名 --save-dev

3.7 解决下包慢的问题

  • 切换npm的下包镜像源
# 查看当前的下包镜像源
npm config get registry
# 将下包镜像源切换为淘宝镜像源
npm config set registry=https://registry.npmmirror.com/
# 检查镜像源是否切换成功
npm config get registry

3.8 nrm

  • 一个工具,方便切换下包的镜像源,快速查看和切换下包的镜像源
# 提高 npm包管理器,安装nrm为全局可用的工具
npm i nrm -g
# 查看可用的镜像源
nrm ls
# 将下包的镜像源切换为淘宝
nrm use taobao

3.9 包的分类

  • 全局包

    • 在执行npm install 命令时,如果提供了-g参数,则会把包安装为全局包
    npm i 包名 -g #全局安装指定的包
    npm uninstall 包名 -g #x
    • 注意点
      • 只有工具性质的包,才有全局安装的必要性,因为他们提供了好用的终端命令
      • 判读某个包是否需要全局安装才能使用,可以参考官方文档
  • 项目包

    • 安装到项目的node_modules目录中的包,都是项目包

    • 开发依赖包:(被记录到devDependencies节点中的包,只会在开发期间用到)

    • 核心依赖包:(被记录到Dependencies节点中的包,在开发期间和项目上线之后都会用到)

    • 安装方法

    npm i 包名 -D #开发依赖包(记录到devDepdentencies节点下)
    npm i 包名 # 核心依赖包(记录到Dependencies节点下)

3.10 i5ting_toc

  • 一个把md文档转为html页面的小工具
# 将i5ting_toc 安装为全局包
npm install i5ting_toc -g
#调用i5ting_toc 实现md转html的功能
i5ting_toc -f 要转换的md文件路径 -o

3.11 规范的包结构

  • 包必须以单独的目录存在
  • 包的顶级目录下包含package.json这个包管理配置文件
  • package.json包含name,version,main三个属性,代表包名,包版本,包的入口(js文件所在)

4.开发自己的包

  • 包实现的功能
    • 格式化日期
    • 转义html特殊字符
    • html字符还原
  • 初始化包的基本结构
    • 新建day03-utils文件夹,作为包的根目录
    • 在day03-utils文件夹中新建三个文件
      • index.js
      • package.json(可使用npm init -y) 来自动创建,再修改一下
      • README.md说明文档
  • 包的功能的模块化
    • 根目录下创建src文件夹
    • 将格式化日期的功能拆分到src--->dateDateFormat.js中
    • 处理html的字符串拆分到src->htmlTo
    • index.js导入上述两个功能,在把功能暴露出去
  • package.json
{
"name": "day03-utils",
"version": "1.0.0",
"description": "用于html的转换,时间日期格式化",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": ["lingxin", "html", "Formdate"],
"author": "lingxin",
"license": "ISC"
}
  • index.js
// 这是day03-utils包的入口
// 导入dateFormat和htmlTo包
const date = require('./src/dateFormat');
const htmlTo = require('./src/htmlTo')
module.exports = {
// 使用展开运算符,将对象成员展开
...date,
...htmlTo
}
  • dateFormat.js
// 定义一个格式化日期的函数
function dateFormat(dateStr) {
var date = new Date(dateStr);
var y = date.getFullYear();
var m = padZero(date.getMonth() + 1);
var d = padZero(date.getDate());
var h = padZero(date.getHours());
var mm = padZero(date.getMinutes());
var ss = padZero(date.getSeconds());
return `${y}-${m}-${d}-${h}-${mm}-${ss}`
}
// 补零函数
function padZero(n) {
return n < 10 ? '0' + n : n;
}
module.exports = {
dateFormat
}
  • htmlTo.js
// 将html标签中的<> & 和 " 转换为相应的实体字符
function htmlToEntity(htmlStr) {
return htmlStr.replace(/<|>|"|&/g, function(match) {
switch (match) {
case '<':
return '&lt;'
case '>':
return '&gt;'
case '"':
return '&quot;'
case '&':
return '&amp;'
}
})
}
// 将实体字符还原回来
function htmlTochar(htmlStr) {
return htmlStr.replace(/&lt;|&gt;|&amp;|&quot;/g, function(match) {
switch (match) {
case '&lt;':
return '<'
case '&gt;':
return '>'
case '&amp;':
return '&'
case '&quot;':
return '"'
}
})
}
module.exports = {
htmlToEntity,
htmlTochar
}
  • README.md
## 安装
```shell
npm install day03-utils
```
## 导入
```js
const d3 = require('day03-utils');
```
## 格式化日期函数的使用
```js
var time = d3.dateFormat(new Date());
console.log(time);
// 输出结果 2022-03-14-18-53-18
```
## 转义特殊字符的使用
```js
// 测试字符转义
var str2 = d3.htmlToEntity(str);
console.log(str2);
// 输出结果:&lt;h1 title=&quot;666&quot;&gt;123&amp;nbsp;&lt;h1/&gt;
```
## 还原特殊字符的使用
```js
var str2 = d3.htmlToEntity(str);
// 测试字符还原
var str3 = d3.htmlTochar(str2);
console.log(str3);
// 输出结果:<h1 title="666">123&nbsp;<h1/>
```
## 开源协议
ISC

5.发布包到npm上

  1. 注册npm的账号

  2. 在终端上登录npm账户

    1. 首先将下包的服务器切换成npm的官方服务器
    2. 使用nrm工具换源
    3. 终端登录
    npm login

  3. 发布包到npm

    1. 将终端切换到根目录下
    2. 在npm官网中查看包名是否雷同(雷同不能发布)
    3. 输入发包命令
    npm publish
  4. 删除已发布的包

npm unpublish 包名 --force
  • 注意点

6. 模块加载机制

6.1 模块优先从缓存中加载

  • 模块在第一次被加载时里面的代码会被执行,加载后模块被缓存,多次调用require()方法不会导致模块的代表被多次执行

示例

  • 自定义模块4
console.log("hello");
  • 测试自定义模块4
require('./17.自定义模块4')
require('./17.自定义模块4')
require('./17.自定义模块4')
  • 效果图

6.2 内置模块的加载机制

  • 内置模块是由Node.js官方提供的,内置模块的加载优先级最高
  • 例如,require('fs')始终返回内置的fs模块,即使在node_modules目录下有名字相同的包也叫做fs

6.3 自定义模块的加载机制

  • 使用require()加载自定义模块时,必须指定以./或../开头的路径标识符,在加载自定义模块时,如果没有指定./或../这样的路径标识符,则node会把他当作内置模块或第三方模块进行加载

6.4 第三方模块的加载机制

6.5 目录作为模块

posted @   凌歆  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示