🦄 2024 独立开发者训练营,一起创业!查看介绍 / 立即报名(剩余10个优惠名额) →

Node.js 服务端应用开发 #6:管理应用的包(Package)

JavaScript 社区里面提供了很多现成的包,包里面都提供了一些功能或者工具,我们可以直接把它们用在自己的项目里,这样很多功能我们就不用自个儿去开发了。管理项目里使用的包会用到一个包管理工具叫 npm。后面我们会在项目里用到一些包,所以下面可以先了解一下包与包管理到底是怎么一回事儿。

包(Package)

把一些东西打成一个包(Package),这个包可以提供一些功能,然后在其它地方可以使用这个包提供的功能,这个包里面主要就是一些用 JavaScript 语言写的代码文件。比如在我们自己开发的应用里,可以安装一些包,然后使用它们里面提供的功能。可以把它们想成是一些零部件,或者功能模块。

JavaScript 社区里的小伙伴们,会把自个儿做好的一些包,发布到一个叫 npmjs.com 的网站上。然后大家就都可以在这个网站里面,下载使用自己需要的包。比如我们要开发的照片儿分享应用,需要一个处理照片文件的功能,比如调整文件的尺寸,读取文件信息。这些功能你可以自己造出来,也可以去找一个带这些功能的包,然后把它安装在自个儿开发的项目里面,这样就可以直接使用这些功能了。

在后面我们会在项目里用到一些包,比如下面我们要使用的一个应用框架,其实它就是一个包,在我们自己的项目里面安装了这个包以后,就可以使用这个框架提供的功能了。框架可能会把自己分成很多个包,这么做主要是为了更灵活一些,这样我们就可以根据自己的需求,选择安装自己真正需要的包。

依赖关系

包和包之间可能会存在一个依赖的关系,就是在一个包里面可能会依赖其它的一些包提供的功能,想要正常使用一个包提供的功能,就必须要解决它的依赖。

你在项目里面,想要使用一个包提供的功能,把可以把它下载到自己的项目里面。如果这个包依赖其它的包提供的功能,你还得把这些被依赖的包也下载到自己的项目里,这样才能使用你真正需要的包提供的功能。

其实我们自己开发的应用,也可以把它看成是一个包,在我们的应用里会用到一些包提供的功能,这些包就是我们的应用的依赖。也就是如果想让应用可以正常的工作,就必须得把应用依赖的包安装在项目里。

包之间之所以存在这个依赖关系,主要就是为了减少重复的工作,比如我们要开发的照片分享应用,需要照片处理功能,如果正好有现成的包提供了这个功能,我们就可以直接在项目里安装使用这个包,就不用自己再去开发这个功能了。

包管理

一个包,依赖一些包,这些包可能又会依赖其它的一些包,手工去解决包之间的依赖关系是相当麻烦的一件事儿,几乎是不太可能。所以我们要借助一些包管理工具,在 Node.js 里面,经常用的包管理工具叫 npm( Node Package Manager)。我们之前在电脑上安装了 Node.js 以后,除了 Node.js 以外,还给我们安装了一个叫 npm 的工具。

有了包管理工具以后,你只需要把你真正需要的包告诉它就行了,它会帮你解决这个包的依赖问题,就是它会把这个包依赖的所有的包全都下载到你的项目里。npm 在解决包之间的依赖问题的时候,会读取包里面的 package.json 这个文件。在包里面,都有这么一个文件。

在这个文件里面,会把这个包依赖的一些东西描述清楚,比如它依赖的包的名字是什么,版本是多少。npm 在解决这个包的依赖的时候,会用到这个 package.json 文件,根据这个文件里的依赖描述来解决这个包的依赖。

包管理并不是 Node.js 特有的概念,在其它地方也有,比如在 Linux 类型的操作系统里面,都会带着一个包管理工具,用来管理安装在系统上的软件。

版本号

开发的项目都需要一个版本号,有一种版本号的规范叫 Semantic Versioning,简称是 SemVer,这套规范就是教你怎么给你的项目设置版本号,Node.js 项目都会使用这种版本号。

它就是把一个版本号分成了三个部分,中间用点分隔开。从左往右,第一个部分是 Major 版本,是项目的大版本号,如果项目有非常大的变化,可以更新这个数字。第二部分是 Minor,就是小版本,如果在项目里添加了新的功能,这些功能不会破坏老版本,可以向后兼容,就可以更新这个 Minor 版本号。 最后一部分是 Patch,补丁版本,修复了一些小 Bug 以后,可以更新这个补丁版本号。

比如有个包(项目)它的版本号是 4.17.1,这就是一个使用 SemVer 规范的版本号。4 是它的大版本,17 是它的小版本,1 是它的补丁版本。

给你两个版本号,你大概就能判断这两个版本号代表的项目,它们之间的区别。比如有两个包,版本号分别是 4.17.0 还有 4.17.1,首先你会知道这个 4.17.1 一定比 4.17.0 这个版本的项目更新一些。 然后根据版本号里的补丁版本,我们可以判断出,这个 4.17.1 相对于 4.17.0,多修复了一处错误,就是一个 bug。

如果是 4.17.0 跟 4.16.0 相比的话,根据版本号里的小版本的变化,我们就知道,这个 4.17.0 比 4.16.0 多了一些功能,而且这些功能是向后兼容的,也就是它一般不会破坏我们的已经使用了这个包的项目。就是如果你在项目里已经使用了 4.16.0 这个包里的一些功能,你可以安全的把它更新到 4.17.0 这个版本。

如果是 5.0.0 跟 4.17.1 相比的话,就是一个大版本的更新,也就是 5.0.0 这个包里面的变化会非常的大,有可能这些变化会破坏我们的项目。如果你在项目里已经用了 4.17.1 这个包里的一些功能,如果把它升级成 5.0.0,很有可能会破坏我们的项目,就是以前有的功能,现在可能没有了,或者换了一种方法来实现。所以在升级大版本的时候,要仔细阅读升级的说明文档。

你会发现有些项目的版本号里面带着 alpha 这个词儿,它表示,这个东西还非常不成熟,还在早期的试验阶段,很多东西都还没有定下来,以后很可能会有大的变化。所以一般这种版本的东西不太适合用在生产环境的应用里面。

还有一个词也会出现在项目的版本号里面,就是 beta,它表示这个项目已经在测试阶段了,这种版本的东西要比之前的那个 alpha 更稳定一些,但是用的时候也要非常小心。

再往下走,就到了 rc 这个阶段,Release candidate,表示发布候选。项目开发到这个阶段基本上很多东西都定下来了,后面主要就是修复一些 Bug 之类的。 过了 rc 阶段就是正式发布的版本了。

npm

npm 是 Node.js 的一个包管理工具,它是一个命令行工具。安装了 Node.js 以后会自带这个命令行工具。在后面我们会使用这个工具给项目安装一些包,执行一些自定义的命令,下面先了解一下这个工具的主要用法。

安装源

在用 npm 安装包的时候,它会到一个默认的地方下载需要的包,如果你感觉从这里下载东西很慢,可以修改 npm 的配置,换一个安装源,比如淘宝就会提供一个这样的安装源。

配置 npm 的安装源,可以使用下面这个命令:

npm config set registry 安装源

比如我们要把安装源换成淘宝的,这样在中国大陆地区,使用 npm 安装包的时候速度就会快很多。可以执行:

npm config set registry https://registry.npm.taobao.org

如果你想把这个安装源换成默认的,可以执行:

npm config set registry https://registry.npmjs.org

上面的命令实际上就是修改了一下 NPM 的配置文件,位置是在 ~/.npmrc,你可以查看一下这个文件里的内容。

安装包

在项目里安装需要用的包,可以执行 npm install 这个命令,后面加上要安装的包的名字,如果需要指定一个版本号,可以把版本号放在 @ 符号的后面,如果不特别指定要安装的包的版本号,npm 会给你安装最新版本的包。这个命令还支持一些选项,比如 --save ,意思是把安装的包记录在项目的 package.json 文件里。

npm install 包的名字@版本号 --save

现在可以省略 --save 这个选项了,默认 npm 会自动加上这个选项。注意在给项目安装包的时候,你必须要在项目所在目录的下面执行这个安装命令。

示例:

npm install express@4.17.0 --save

在项目所在目录的下面,执行上面这行命令就会在项目里安装一个叫 express(应用框架) 的包。

依赖(dependencies)

安装的包会被记录在项目的 package.json 文件的 dependencies 这个属性里面,npm 会读取这个文件里的这个依赖下面的信息来判断项目都依赖什么东西。

示例:

  "dependencies": {
    "express": "^4.17.0"
  }

上面记录了一下,说这个项目里面有个依赖(Dependency)叫 express,也就是如果想让这个项目能正常的运行,在项目里必须先要安装 express 这个东西。

node_modules

用 npm 安装的包默认会存放在项目根目录下的 node_modules 这个目录里面。安装了一个包以后,你可以查看一下这个目录里的东西,你会发现里面有很多东西。即使你只是安装了一个包,里面也可能会出现很多个目录。这是因为,包与包之间的依赖关系,npm 会解决包的依赖,它会把所有依赖的东西全部下载下来放到 node_modules 这个目录里面。

这个目录我们是可以随便把它删除掉,因为项目的依赖已经在 package.json 里面写清楚了,在项目的下面,执行 npm install 这个命令,如果在命令里不加其它的东西,npm 就会根据 package.json 文件里写的依赖去把它们下载下来放到项目的 node_modules 目录里面。

版本号里的 ^ 与 ~

在依赖里面记录的包的版本号里面,可能会有一些特别的符号,比如 ^ 与 ~。这个 ^ 表示可以使用这个包的小版本与补丁版本的更新,~ 的意思是可以使用包的补丁版本的更新。如果在版本号里没有特别的符号,就会使用指定版本的包。

比如在依赖里记录的一个包的版本号是 ^4.17.0 ,以后如果这个包有 4.17.x 或者 4.18.x 版本,这样用 npm 升级项目里的包的时候,npm 就会下载使用这个更新的包。但是不会使用大版本更新的包,比如 5.x.x。

如果在版本号的最前面用的是 ~ 这个符号,在以后 npm 就只会使用这个包的小版本更新,也就是如果版本号设置成 ~4.17.0,以后这个包有 4.17.1,4.17.2 的时候,npm 会使用这些更新的包。但是不会使用这个包的小版本号大版本的更新,比如 4.18.x 或者 5.x.x。

package-lock.json

在 package.json 文件里会记录项目依赖的包,那里记录的只是你真正需要的包,但是我们知道包与包之间是有依赖关系的,就是你安装了一个包,这个包可能依赖其它的包,这些其它的包又可能会依赖其它的包,所以 npm 会把所有这些东西都下载到你的项目里。npm 会把它安装的包的详细情况记录在一个叫 package-lock.json 的文件里。

示例:

"express": {
  "version": "4.17.0",
  "resolved": "https://registry.npm.taobao.org/express/download/express-4.17.0.tgz",
  "integrity": "sha1-KIr2IiinP0yOopkLo7eRu4fNRDg=",
  "requires": {
    "accepts": "~1.3.7",
    ...
  }
 }

开发依赖(devDendencies)

在项目里,有些依赖的包可能只是在开发阶段才会用到,正式运行的时候可能用不到这些包,在安装这些只在开发时用的包,可以在命令里面使用 --save-dev 这个选项,这样就会把依赖记录在 package.json 文件的 devDependencies 这个属性里面。本质上开发依赖跟普通的依赖没啥区别,只不过就是为了区分一下这些依赖的包。

npm install 包的名字@版本号 --save-dev

示例:

npm install typescript --save-dev

在项目里执行上面的命令,会把安装的包记录在 package.json 里的 devDependencies 里面。

  "devDependencies": {
    "typescript": "^3.8.3"
  }

命令行工具

有些包其实是个命令行工具,比如很多应用框架就给你提供一个命令行工具,用来快速创建项目与项目需要的一些组件。还有比如后面我们要安装使用的 TypeScript,它里面提供了一个 tsc 命令,可以用来编译项目。

这些命令行工具可以在全局范围安装,也可以安装在某个具体的项目里。如果把它安装在全局范围,这样这个命令行工具就可以在任何地方使用。如果把它安装在项目里,就只能在这个项目所在目录的下面使用这个命令。

如果是安装框架带的这种命令行工具,你可以选择在全局范围安装它,这样你就可以在任何地方创建项目了。在全局范围安装命令行工具,可以在 npm install 命令里面加上 --global 这个选项,它的简写形式是 -g 。在全局范围安装的包,会放到一个特定的目录下面。包里带的可以执行的命令,一般会放在一个叫 .bin 的目录下面。

总结

包提供了功能与工具,在我们自己的项目里可以安装使用它们,这些包可以在 npmjs.com 网站上找到,用 npm 这个命令行工具可以管理项目使用的包,安装源是可以修改的,包之间有依赖关系,npm 可以帮我们解决它们之间的依赖问题,项目依赖的包会记录在 package.json 文件里,在 package-lock.json 文件里会记录更详细的关于项目里使用的包的信息,安装的包会放在 node_modules 目录里面,这个目录可以删除掉,然后用 npm install 命令重建这个目录。

下一站,我们要在项目里选择安装一个应用框架,这个框架也是一些包组成的,可以使用 npm 把它安装在我们的项目里。

微信好友

用微信扫描二维码,
加我好友。

微信公众号

用微信扫描二维码,
订阅宁皓网公众号。

240746680

用 QQ 扫描二维码,
加入宁皓网 QQ 群。

统计

15260
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点