目录
模块化
Node.js中模块的分类
模块作用域
模块的加载机制
npm与包
npm包管理工具的安装与使用
包管理配置文件
包下载速度
包的分类
发布包
模块化
模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程。对整个系统来说,模块是组合、分解和更换的单元。编程领域的模块化:就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块。模块化的好处:提高了代码的复用性、提高了代码的可维护性、可以实现按需加载。
模块化规范:对代码进行模块化的拆分和组合时需要遵循的那些规则。其好处在于大家都遵循同样的模块化规范写代码,降低了沟通的成本,极大的方便了各个模块之间的相互调用
Node.js遵循了CommonJS模块化规范,CommonJS规定了模块的特性和各模块之间如何相互依赖。
CommonJS规定:
1)每个模块内部,module变量代表当前模块。
2)module 变量是一个对象,它的 exports 属性是对外的接口
3)加载某个模块,其实是加载该模块的 module.exports 属性。require()方法用于加载模块
Node.js中模块的分类
Node.js中根据模块的来源的不同,将模块分成了3大类,分别是:
内置模块:内置模块是由Node.js官方提供的,例如:fs、path、http等
自定义模块:用户创建的每个 .js文件,都是自定义模块
第三方模块:由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载。
使用强大的 require() 方法,可以加载需要的内置模块、用户自定义模块、第三方模块进行使用。注意:使用 require() 方法加载其它模块时,会执行被加载模块中的代码。
// 加载内置模块
const fs = require('fs')
// 加载自定义模块 需要模块路径,模块为.js文件时,可省略后缀
const test = require('./test')
// 加载第三方模块
const moment = require('moment')
模块作用域
和函数作用域类似,在自定义模块中定义的变量、方法等成员,只能在当前的模块内被访问,这种模块级别的访问限制,叫做模块作用域。模块作用域的好处:防止了全局变量污染的问题。
module.exports:在每个 .js自定义模块中都有一个module对象,它里面存储了和当前模块有关的信息。在自定义模块中,可以使用 module.exports 对象,将模块内的成员共享出去,供外界使用。外界用 require() 方法导入的自定义模块时,得到的就是 module.exports 所指的对象。
exports:由于 module.exports 单词写起来比较复杂,为了简化向外共享成员的代码,Node提供了 exports 对象。默认情况下,exports和module.exports指向同一个对象。最终共享的结果,还是以 module.exports 指向的对象为准。注意:exports不能以对象的形式来挂载,要用对象的话还是使用 module.exports 即可。
注意:为了防止混乱,建议大家不要在同一个模块中同时使用 exports 和 module.exports 。
模块的加载机制
模块在第一次被加载后会被缓存。这也就意味着多次调用 require() 不会导致模块的代码被多次执行。注意:不管是内置模块、用户自定义模块、还是第三方模块它们都会优先从缓存中加载,从而提高模块的加载效率。
内置模块的加载优先级最高。
自定义模块加载需要 ./或../开头的路径标识符,如果没有会当作内置或第三方模块
第三方模块会一层层的在 /node_modules 文件夹中找到并加载第三方模块
目录作为模块时,会查找当前目录的package.json文件的main属性,没有该文件会查找当前目录下的index.js文件,如果还没有就会报错。
npm与包
Node.js中的第三方模块又叫做包,两者指的是同一个概念,就相当于电脑和计算机一般。不同于Node.js中的内置模块与自定义模块。包是由第三方个人或团队开发出来的,免费供所有人使用。注意:Node.js中的包都是免费且开源的,不需要付费即可免费下载使用。
由于Node.js的内置模块仅提供了一些底层的API,导致在基于内置模块进行项目开发时,效率很低。包是基于内置模块封装出来的,提供了更高级的、更方便的API,极大的提高了开发效率。
全球最大的包共享平台是: https://www.npmjs.com/ ,在这个网站你可以搜到任何你需要的包。
npm包管理工具的安装与使用
Node Package Manager(简称:npm包管理工具)。这个包管理工具随着Node.js的安装包一起被安装到用户的电脑上。可以通过终端执行 npm -v 查看自己的npm包管理工具的版本号:
我们在没使用npm之前,如果想打印当前的事件的话,还需要自己创建自定义模块进行使用:
// 在自定义模块中,module.exports = {}
function gettime(dataStr){
// 引用事件函数
const dt =new Date()
// 定义 年月日 变量
const y = dt.getFullYear()
const m = addZero(dt.getMonth() + 1)
const d = addZero(dt.getDay())
// 定义 时分秒 变量
const h = addZero(dt.getHours())
const t = addZero(dt.getMinutes())
const s = addZero(dt.getSeconds())
// 将得到的时间通过模板字符串return出去
return `${y}-${m}-${d} ${h}:${t}:${s}`
}
// 定义加0函数,小于9的数字前加0
function addZero(n){
return n > 9 ? n : '0' + n
}
// 将模块的函数向外共享出去
module.exports = {
gettime
}
// require导入文件得到的内容就是模块中 通过 module.exports 指向的哪个对象
const result = require('./自定义模块')
const dt = new Date()
// 使用时间的自定义模块
const time = result.gettime(dt)
console.log(time);
经过我们大量的代码才实现了打印当前时间的效果,然而当我们使用包的时候,就需要几行代码就能实现。在项目中安装包的命令是: npm install 包的名称 ,当然这种形式也可以简写成这样的形式进行:npm i 包的名称。所以我们接下来举例安装时间的包,如下:
安装完成之后,我们可以在上文介绍的包共享平台去查阅这个包的使用方法,平常使用自己不知道的包就可以在这个平台去查阅相关使用方法:
// 导入的名称就是包的名称
const moment = require('moment')
const dt = moment().format('YYYY-MM-DD HH:mm:ss')
console.log(dt);
我们在初次安装包后,文件夹会多出node_modules和package.json等文件,里面是记录着你下载包的内容及其版本号等相关信息的,可以点开进去了解,但不能修改其相关信息。
安装指定版本的包: 默认情况下,使用npm install 命令安装包的时候,会自动安装最新版本的包,如果想安装指定版本的包,可以在包名之后,通过 @ 符号指定具体的版本。
包的语义化规范:
包的版本号是以“点分十进制”的形式定义的,总共有三位数字,例如:2.24.3,其含义如下:
第一位数字:代表大版本
第二位数字:代表功能版本
第三位数字:代表Bug修复版本
版本号的提升规则:只要第一位数字的版本号增长,则后面的数字自动清零。
包管理配置文件
npm规定在项目的根目录中,必须提供一个叫做 package.json 的包管理配置文件。用来记录与项目有关的一些配置信息,例如:项目的名称、版本号、描述以及项目中用到哪些包等。在记录项目中用到的哪些包后可以方便的剔除node_modules目录,便于团队之间共享代码。注意:项目开发中一定要将 node_modules 文件夹添加到 .gitignore忽略文件中。
dependencies节点:package.json文件中有这样一个节点,专门用来记录自己使用的npm i 命令安装了哪些包:
我们在拿到别人的项目代码时,是不携带node_modules这个大文件的,那么我们没有项目安装的包如何启动项目呢? 在项目的package.json文件中的dependencies节点下,书写了这个项目安装的所有的包,我们只需执行 npm install 这个命令即可安装项目所需的所有的包。
卸载包:我们可以执行 npm uninstall+包的名称 命令,来卸载指定的包,卸载完成之后,包就会在dependencies节点下移除掉。
devDependencies节点:如果某些包只在项目开发阶段用到,项目上线阶段用不到,则建议把这些包记录到devDependencies节点下,与之对应的某些包在开发和上线都需要用到,则需把这些包记录到dependencies中。安装到这个节点的包,需要安装命令后面加 -D 。
包下载速度
在使用 npm 下载包的时候,默认是从国外的服务器进行下载,此时,网络数据的传输需要经过漫长的海底光缆,因此下包速度很慢。解决方法如下:
# 查看当前的下包镜像源
npm config get registry
# 将下包的镜像源切换为淘宝镜像源
npm config set registry=https://registry.npm.taobao.org/
# 检查镜像源是否下载完成
npm config get registry
为了更方便的切换下包的镜像源,我们可以安装 nrm 这个工具,利用 nrm 提供的终端命令,可以快速查看和切换下包的镜像源。
# 通过 npm 包管理器,将 nrm 安装为全局可用的工具
npm i nrm -g
# 查看所有可用的镜像源
nrm ls
# 将下载的镜像源切换为 taobao 镜像源
nrm use taobao
包的分类
项目包:那些被安装到项目的 node_modules 目录的包都是项目包,项目包又分为两类:开发依赖包(被记录到devDependencies节点中的包,只在开发期间使用);核心依赖包(被记录到dependencies节点中的包,在开发期间和项目上线都会使用)
全局包:在执行 npm install 命令时,如果提供了 -g 参数,则会把包安装为全局包。卸载的话命令和上文一样:npm uninstall 包名 -g。只有工具性质的包,才有全局安装的必要性,因为它们提供了好用的终端命令。判断一个包是否需要全局安装可参考官方提供的文档说明。
发布包
我们可以将自己写的包发布的包共享平台上,供其他人使用,发布流程如下:
注册npm账号:点击 网址 进行注册。
登录npm账号:npm注册完成后,在编译器的终端执行 npm login 命令,依次输入用户名、密码、邮箱后即可登录成功。注意:在执行 npm login 之前,一定先把下包的服务器地址切换为 npm 的官方服务器,否则发包失败!
将包发布到 npm 上:将终端切换到包的根目录之后,运行 npm publish 命令,即可将包发布到npm上,注意:包名不能平台已有包名雷同,建议发包之前去平台搜索自己的包名有没有被占用,发布完成就可以登录平台查看自己的个人中心进行查阅发包情况。
删除包:包路径下终端运行 npm unpublish 包名 --force 命令,即可从 npm 删除已发布的包。注意:npm unpublish 命令只能删除 72 小时内发布的包,npm unpublish删除的包,在24小时之内不能重复发布。