Node-模块化
模块化
概念:
模块化 是指 解决一个复杂问题时,自顶向下逐层把把系统划分成若干个模块的过程。对于整个系统来说模块是可以组合分解和更换的单元,遵守固定的规则把一个大文件拆分成独立并互相依赖的多个小模块
好处:
提高代码复用性
提高代码维护性
可实现按需加载
模块化规范
模块化规范就是对代码进行模块化的拆分与组合时,需要遵守的那些规则
例如:
使用什么样的语法来引用模块
在模块中使用什么样的语法格式向外暴露成员
好处:
都遵守模块化规范写代码,降低沟通成本,极大的方便了各个模块之间的相互调用,利人利己
Node.js 中模块化
分类:
Node.js 中将根据来源不同将模块分为三大类
内置模块
(是由Node.js 官方提供的,例如fs,path,http等)
自定义模块
(用户创建的js文件都是自定义)
第三方模块
(第三方开发的模块,使用要提前下载)
模块的加载
require() 方法,可以加载模块使用
// 1、内置的fs模块
const fs = require('fs')
// 自定义
const custom = require('./custom.js')
// 第三方模块
const moment = require('moment')
⚠️ 注意:在require()方法加载其他模块时,会执行被加载模块中的代码,在加载用户自定义模块时可以省略.js 后缀名
模块的作用域
在自定义模块中定义的变量方法等成员、只能在当前模块内被访问,模块级的访问限制叫做模块的作用域,防止全局变量的污染问题
共享模块作用域中的成员
module对象
每个.js自定义模块中都有一个module对象,里面存储了和当前模块有关的信息
console.log(module)
//输出:
Module {
id: '.',
path: 'D:\\XXXX\\demo\\js\\node',
exports: {},
filename: 'D:\\XXXX\node\\module对象.js',
loaded: false,
children: [],
paths: [
'D:\\xxx\\demo\\js\\node\\node_modules',
'D:\\xxx\\demo\\js\\node_modules',
]
}
module.exports 对象
在自定义模块中,可使用module.exports对象将模块内的成员共享出去,供外界使用;外界使用require()方法导入自定义模块的时,就是得到了module.exports所指向的对象
const m = require('./001.js')
console.log(m)//输出 {}
// test.js
// 在一个自定义模块中 默认 module.exports = {}
//向module.exports 对象上挂载属性和 方法
const age = 20
module.exports.username = 'xiaoming'
module.exports.printHello = function () {
console.log('printHello : Hello!')
}
module.exports.age = age
-------------------------------------------------------
// requireTest.js
const test = require('./test')
console.log(test)// 输出 { username: 'xiaoming', printHello: [Function (anonymous)], age: 20 }
⚠️注意 require()方法导入模块时,导入的结果永远以module.exports指向的对象为准
就是
module.exports = {
name:‘xx’,
sHi() {
}
}
指向了一个新的对象,以新的对象为准
exports 对象
⚠️ 为了简化向外共享成员的代码,Node 提供了exports对象。默认情况,exports和module.exports 指向同一个对象。最终共享的结果,还是以module.exports指向的对象为准
module.exports === exports
true
Node.js中的模块化规范
Nodejs遵循了CommonJS
模块化规范,规定了模块的特性和各个模块之间如何相互依赖
CommonJS规定:
- 每个模块内部,module变量代表当前模块
- module变量是一个对象,它的exports属性是对外的接口
- 加载某个模块,其实 就是加载该模块的module.exports属性。require() 方法用于加载该模块
npm与包
包
Node.js中的第三方模块又叫做包,由第三方个人或团队开发的免费使用
**使用包的原因:**Node.js 内置模块仅仅提供了一些底层的api ,在导致基于内置模块进行项目开发的时候效率低,包是基于内置模块封装出来的,提供了更高级的、更方便的api,提高开发效率
下载包:地址 http://www.npmjs.com/ 他是全球最大的包共享平台,可以从网站上搜索任何你需要的包,下载地址:http://registry.npmjs.org/ <服务器地址>
包管理工具:Node Package Manager (npm 包管理工具),这个包随着Node.js 安装一起被安装到用户电脑上,npm -v
查看版本
//使用 格式化时间的包
// 导入moment 包
const moment = require('moment')
//使用moment().format() ,格式化时间
const dt = moment().format('YYYY-MM-DD HH:mm:ss')
console.log(dt)
安装包:npm install xxx@
2.22.1 / npm i xxx
<简写> @2.22.1–》指定版本,默认最新的包
⚠️注意:初次装包多了哪些文件:
node_modules
文件夹和package_lock.json
的配置文件node_modules 存放已安装到项目中的包。require() 导入第三方包时,就是从这个目录中查找并加载包
ackage-lock.json 用来记录node_modules 目录下每一个包的下载信息,包的名字、版本号、下载地址等
不要手动修改node_modules中或者package-lock.json 文件中的任何代码,npm包管理工具会自动维护他们
npm包的语义化版本:三位数字 ,点分十进制, 例如:2.22.4 第一位:大版本 第二位:功能版本 第三位:Bug修复版本 ,只要前面版本号增长了,后面的版本号归零
包管理配置文件
- 相关概念
package.json 记录与项目有关的一些配置信息
项目的名称、版本号、描述、用到哪些包,开发期间或者部署时
npm init -y
快速创建package.json 文件
dependencies
节点 执行 npm install
会创建node_modules 文件夹以及 依赖的节点dependencies
执行 npm install
命令时npm包管理工具会先读取package.json 中的dependencies 节点;读取到的所有依赖包名称和版本号 npm 管理工具会把这些包一次性下载到项目中
npm uninstall xxx
删除指定包;会删除 node_modules 下的包和 package.json 中的依赖
devDependencies 节点 只在项目开发中用到 例如npm i -D webpack
-
npm下包慢
默认国外的服务器下载:https://registry.npmjs.org/
换镜像:
# 查看当前下的镜像源 npm config get registry # 将镜像源换位淘宝的 npm config set registry=https://registry.npm.taobao.org/ # 检查是否切换成功 npm config get registry
使用 安装
nrm
小工具快速查看和切换下包的镜像源npm i nrm -g # 查看镜像源 nrm ls # 将镜像源切换为taobao nrm use taobao
-
包的分类
-
项目包:node_modules 中的包
开发依赖包(dependencies节点中的包 开发期间会用到) npm i xxx -D
核心依赖包(devDependencies节点中的包 开发期间和项目上线都会用到) npm i xxx
-
全局包: -g 参数 安装为全局包
被安装到C:\Users\用户目录\AppData\Roaming\npm\node_modules下
npm i xxx -g
npm unstall xxx -g
-
-
规范的包结构
需要符合以下三点要求
1》包以单独的目录而存在
2》包的顶级目录下要包含package.json文件
3》package.json中必须包含name,version,main这三个属性分别代表包的名字、版本号、包的入口
-
开发属于自己的包
1> 新建 my-tools 文件夹 作为包的根目录
2> 在my-tools 文件夹中 新建三个文件
package.json 包管理配置工具
index.js 入口文件
README.md 说明文档
3>初始化 package.json
{ "name": "my-tools", "version": "1.0.0", "main": "index.js", "description": "描述信息", "keywords": ["关键字1", "关键字2"], "license": "ISC" }
4>在index.js中写实现对应的方法,也可以模块化导入
function xxxxx(param) { ... } modules.exports = { xxxxx }
在 require(‘./my-tools’)时 默认会找 package.json文件中的mian 属性对应的 index.js 入口文件
5> 发布包
注册npm账号;终端执行npm login 依次输入用户名密码等信息 (注意把包的下载地址换位npm官方 的 服务器 );将终端切换到 包的根目录 运行npm publish
命令 即可发布
删除已发布的包 npm unpublish xxx -force
即可删除(72小时以内发布的)
模块的加载机制
模块在第一次加载会后被缓存 多次调用require 不会导致模块的代码被多次执行 各种模块都会优先从缓存中拿取提高模块加载效率
内置的模块加载的优先级最高
自定义模块加载 必须以./或…/开头的路径标识符 若没有指定 node 会当作内置模块或者第三方模块加载
若省略了文件的扩展名则node.js会以 按照明确的文件名 –> .js --> .json -->.node -->加载失败
第三方模块加载 从/node_modules 文件夹中加载第三方模块 一直从 当前目录的node_modules 到根目录 寻找 node_modules下的包
目录作为模块 三种加载方式:a. 在被加载的目录下找package.json文件 寻找main属性 作为require() 的入口;b. 目录里没有package.json文件 或者main入口 不存在无法解析 则会试图加载目录下的index.js文件 c. 报错 没有找到模块