模块化

133 阅读4分钟

模块化概念

  • 模块化是指解决一个复杂问题时,自顶向下逐层把系统划分为若干模块的过程,
  • 模块是可组合、分解和更换的单元。
  • 模块化可提高代码的复用性和可维护性,实现按需加载。
  • 模块化规范是对代码进行模块化拆分和组合时需要遵守的规则,如使用何种语法格式引用模块和向外暴露成员。

模块分类

  • 内置模块 (内置模块是有node.js官方提供的例如 fs path http)
  • 自定义模块 (用户创建的每个js文件都是自定义模块)
  • 第三方模块(由第三方开发出来的模块需要先安装)

模块引用

//调用内置模块
const fs = require('fs')

//调用自定义模块 .js可省略  必须以 ./ ../ 不可以 /
const m1 = require('./home/index.js')

//调用第三方模块
const axios = require('axios') 

模块作用域

  • 和函数作用域类似,在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域
  • 防止全局变量污染

模块化成员

  • module 对象
Module {  
  id: '.',
  exports: {},
  parent: null,
  filename: 'F:\\eager\\node\\node-study\\模块化\\module.js',
  loaded: false,
  children: [],
  paths:
   [ 'F:\\eager\\node\\node-study\\模块化\\node_modules',
     'F:\\eager\\node\\node-study\\node_modules',  
     'F:\\eager\\node\\node_modules',
     'F:\\eager\\node_modules',
     'F:\\node_modules' ] }
  • 在自定义模块中 可以使用module.export 对象 将模块内的成员共享出去供外界使用

  • 在外界使用require() 导入一个自定义模块的时候 导入的是module.exports对象

module.js

//为module.exports对象上挂载属性跟方法
module.exports.username = '蔡徐坤'


module.exports.sayHello = function (){
    console.log("你好呀")
}

//私有成员
const age = 20

//对外共享
module.exports.age = age



test.js
const m1 = require('./module')

console.log(m1)



控制台
{ username: '蔡徐坤', sayHello: [Function], age: 20 }
  • ==使用require()方法导入模块导入的结果永远以module.exports指向的对象为准==

  • ==默认情况下exports 和module.exports指向的对象相同==

  • ==为了防止混乱不要在同一个模块中同时使用exports 和module.exports==

模块化规范

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

格式化时间案例

//自定义模块实现
//定义格式化时间的方法
function dataFormat(dtStr){
    //new 一个时间的对象
   const dt = new Date(dtStr) 
   
   const y = dt.getFullYear()
   const m = padZero(dt.getMonth() + 1);
   const d = padZero(dt.getDate());


   const hh = padZero(dt.getHours());
   const mm = padZero(dt.getMinutes());
   const ss = padZero(dt.getSeconds());

  //拼接时间的字符串
  return `${y}-${m}-${d} ${hh}:${mm}:${ss}`

}

//定义补0函数
function padZero(n){
 return  n > 9 ? n: '0' + n
}

//对外暴露
module.exports = {
  dataFormat
};

//引入第三方包 moment实现

//导入自定义时间处理模块
const TIME = require('./格式化时间旧')

//导入第三方时间处理包
const moment = require('moment')

//调用 new data() 获取时间
const data = new Date()
console.log(data)

//调用自定义模块处理时间
const newData = TIME.dataFormat(data);
console.log(newData);

//调用第三方时间处理方法
const MTime = moment(data).format("YYYY-MM-DD HH:mm:ss");

console.log(MTime)

包下载相关

# 查看当前下包镜像源
npm config get registry
# 设置淘宝镜像源
npm config set registry=https://registry.npm.taobao.org/

# 安装nrm 小工具
npm i nrm -g
# 查看可用镜像源
nrm ls
# 将下载镜像 切换为taobao
nrm use taobao

i5ting_toc

// 将md格式文件转换成html格式文件第三方包
// 局部/全局安装
npm i i5ting_toc
npm install -g i5ting_toc
//转换命令
i5ting_toc -f '要转换的文件路径' -o

创建发布自己的npm包

  • 创建包文件夹包含index.js packagejson README.md 三个文件
  • 创建npm账号 在命令行输入 npm login 输入信息登录
  • 进入包文件夹目录运行npm publish 命令发布包 npm unpublish --force
index.js
// 引入src下的模块
const data = require("./src/dataFormat");
const escape = require("./src/htmlEscape");

//对外暴露
module.exports = {
  ...dataFormat,
  ...escape
};


packagejson
{
   "name": "tiur-tools",
   "version": "1.0.0",
   "main": "index.js",
   "description": "提供了格式化时间方法,HTMLEscape的功能",
   "keywords": ["tiur", "dateFormat", "escape"],
   "license": "ISC"
}

README.md
## 安装

npm i tiur-tolls


## 导入
```js
const tiur = require('tiur-tools')

格式化时间

//调用 detaformat对时间进行格式化
const dtStr = tiur.dataFormat(new Date())

console.log(dtStr)

html 字符转换

//调用html
  const str = tiur.htmlEscape('要转义的字段')
  console.log(str)

开源协议

ISC


### 模块加载机制

- 优先从缓存加载 提高效率

- 内置模块加载优先级最高

- 加载自定义模块时,路径要以 ./ 或 ../ 开头,否则会作为内置模块或第三方模块加载。

- 导入自定义模块时,若省略文件扩展名,则 Node.js 会按顺序尝试加载文件:

- 若导入第三方模块, Node.js 会从当前模块的父目录开始,尝试从 /node_modules 文件夹中加载第三方模块。
- 如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录。
- 当把目录作为模块标识符进行加载的时候,有三种加载方式:
- 在被加载的目录下查找 package.json 的文件,并寻找 main 属性,作为 require() 加载的入口
- 如果没有 package.json 文件,或者 main 入口不存在或无法解析,则 Node.js 将
- 试图加载目录下的 index.js 文件。
- 若失败则报错