Nodejs开发进阶G-部署和管理

本文来探讨一下nodejs系统和应用的部署和管理。主要包括nodejs系统本身,nodejs应用和应用所使用或者依赖的库和工具(也称为npm)等几个部分。

nodejs程序文件结构

首先,我们来看看nodejs程序,是如何以系列文件和目录的形式,存在于一个操作系统的文件系统当中的,就是所谓的nodejs程序文件结构。为了方便起见,我们只讨论nodejs在Linux系统下的情况。在默认情况下,安装完成之后,nodejs相关文件和程序,会分布在以下位置:

  • /usr/bin: 包括node、npm、npx等程序文件
  • /usr/include/node: 头文件,用于扩展的开发和编译
  • /usr/lib/node_modules: 全局库文件和模块
  • /usr/share/{doc/node|man/man.1/node1.}: 文档和帮助信息

这里面,最重要的主程序,就是一个单一可执行文件 /usr/bin/node,大小约为96M。而我们熟悉的nodejs官方配套的npm软件包管理命令,不是一个可执行文件,而是一个软连接符号,链接到lib/node_nodules/npm模块目录中的npm-cli.js程序文件。比如我们列表bin目录看到的那样:

shell 复制代码
$ ls node-v20.10.0-linux-x64/bin -l
total 93976
lrwxrwxrwx 1 yanjh yanjh       45 Nov 22 19:42 corepack -> ../lib/node_modules/corepack/dist/corepack.js
-rwxr-xr-x 1 yanjh yanjh 96227728 Nov 22 19:42 node
lrwxrwxrwx 1 yanjh yanjh       38 Nov 22 19:42 npm -> ../lib/node_modules/npm/bin/npm-cli.js
lrwxrwxrwx 1 yanjh yanjh       38 Nov 22 19:42 npx -> ../lib/node_modules/npm/bin/npx-cli.js

作为跨平台的应用,nodejs也可以按照到Windows或者MAC系统之下,它们也会有类似的目录结构,细节可能有所不同,但基本逻辑应该是相同的,由于在生产环境中,这种部署方式比较少见,我们就不深入讨论了。

了解和熟悉这些内容,可以让我们更好的理解nodejs的安装和部署过程,后续可以更好支持进行手动安装或者故障排查等操作。

nodejs版本和系统安装

在不同的操作系统上,nodejs系统的安装和配置方式略有差异,但基本上都比较简单。比如Windows系统,提供了MSI安装文件,只需要下载执行即可。Linux系统的情况稍微复杂一点。我们以debian系统为例,其安装命令代码如下:

shell 复制代码
sudo -i 
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - &&\
apt-get install -y nodejs
node -v
npm -v

debian安装需要先切换到管理员角色;然后下载和执行一个在线的安装脚本,这个脚本将检查安装环境,并进行相关的设置(软件库配置、公钥等等); 并更新软件库;最后作为一般的软件进行安装,软件包名为"nodejs"。最后使用node和npm命令来检查是否安装正确和确认当前使用的版本。

遗憾的是,虽然nodejs支持很多类型的操作系统,但对于不同的操作系统,它的安装方式都略有差异,没有一个通用或者统一的方式,详见相关的安装和技术文件。

nodejs系统手动离线安装

在笔者的工作环境中,有很多是不方便直接连接互联网来进行支撑软件的安装的。作为一个基础支撑软件,就需要研究和实现nodejs的离线安装。我们以linux系统为例,简单的说明一下这个过程。

1 下载nodejs的二进制版本

可以到nodejs下载的主页面,看到并下载预编译好的二进制程序包:

nodejs.org/en/download...

这里的linux预编译版本,只有x64和arm两个选择,我们选择并点击Linux Binaries(x64),这个链接是一个.xz文件,也可以直接使用wget下载,如:

wget nodejs.org/dist/v20.10...

下载后,也是一个.xz文件。整个二进制软件包,压缩的大小仅为不到30M。

2 传输到部署系统

我们可以通过其他任何方式,比如U盘,或者内网的ftp,将这个文件复制到要安装的操作系统之上。一般而言,对于主流的操作系统发行版本,都不会有兼容性的问题。

3 解压缩

这里需要注意的是,这个文件的压缩方式是xz,对应可以使用tar命令将其解压:

tar -xvf node-v20.10.0-linux-x64.tar.xz

ls node-v20.10.0-linux-x64

bin CHANGELOG.md include lib LICENSE README.md share

如果不能正常解压缩,可能需要安装xz工具,或者将其在工作电脑上解压后,以文件夹的方式复制到部署系统上。正常解压后,可以看到软件的目录结构,包括bin、include、lib、share等文件夹。

4 复制文件夹

我们可以将这个目录结构,复制到合适的位置:

sudo cp -r node-v20.10.0-linux-x64/{bin,include,lib,share} /usr/

作为系统基本的应用程序安装,这里需要管理员权限。

5 检查安装

node是一个可执行程序,配套的npm是一个js程序,它们都在/usr/bin文件夹中,可以使用以下命令来检查和执行:

node -v

npm -v

如果看到正确的输出版本,就表明nodejs已经基本安装完成了。

NPM

nodejs作为一个比较成熟的Web应用开发平台,一个重要的特点和优势就是在长时间的发展过程当中,逐步建立了一个丰富而强大的生态系统,其重要表现就是拥有一个以npm技术为核心的软件包管理工具。

特点和优势

狭义而言,NPM(Node Package Manager)是 Node.js 的包管理程序,它用于基于互联网来在线管理和分发JavaScript代码和软件包。和传统的程序库和管理方式相比,NPM提供了更加简单易用而强大的特点和功能,包括:

  • 内容和形态

npm提供的不仅仅是扩展的程序库,实际上它提供的软件包的功能和形态非常丰富,不仅仅是扩展库,可能还包括各种框架、工具等等。包括了几乎所有的技术类型、方向和形态,可谓五花八门,博大精深,应有尽有。据一个不完整的统计,在2022年9月,npm软件仓库中大约容纳了210万个软件包项目,应该世界上单一编程语言最大的代码仓库。

下面是一些应用比较广泛的包:

  • 命令行工具

可以使用简单的命令行操作,来搜索、管理、安装、更新、卸载软件包。npm还提供了多种类型的执行脚本的支持。来帮助在开发过程中的执行、调试等工作。

  • 简单配置

每个Node.js项目都可以通过一个package.json配置文件来进行npm的管理,在软件包和依赖方面,它包含了项目的元数据、依赖项列表、脚本命令等。这个文件可以由NPM创建和管理,也可以手动编辑和配置,然后使用npm命令来实现变更。这个文件就是标准的JSON格式,配置的项目和操作的过程都非常简单直观,易于使用。

  • 在线的全球软件包仓库

NPM建立并提供了一个全球性的软件包仓库(NPM Registry),全世界的开发者都可以方便的从这个仓库中查找、下载、集成软件包到自己的应用当中,也可以编写、发布自己的软件包或者功能模块到这个库当中来帮助别人。大家相互支持发展合作,促进整个nodejs开源社区和生态的发展和合作。

  • 依赖管理

NPM可以帮助自动的管理项目所需的依赖项,一般开发者会在项目中引入一些主要的扩展库和模块,并且在package.json 文件中进行记录。然后使用npm install命令,npm会自动的搜索、下载和配置这些扩展模块所依赖的软件包项目,不需要开发者关心和配置额外的依赖项目。

依赖黑洞

可能是由于npm提供的依赖管理机制太过于方便,随着软件库的日益庞大,它们之间的依赖关系也越来越复杂,有被滥用和无法控制的趋势。下面这张图,就在讽刺npm的复杂和臃肿。

所以,开发者在选择npm的时候,也尽量优先选择比较简洁,使用广泛,依赖关系比较简单的软件包。

安装和配置

npm和其仓库的官方站点在: www.npmjs.com/

nodejs的安装过程,就包括了npm的安装,可以直接基于命令进行使用。但由于一些网络技术方面的原因,在中国直接使用NPM的体验并不是很好,主要表现在软件包的下载速度比较慢,连接也不是很可靠,因为它们的默认的主站和服务器都在国外。针对这种情况,国内的互联网业者在国内建立了一些镜像来改善这个问题,其中主要和广泛使用的就是淘宝提供的镜像源。需要注意,这个源在2023年使用了新的域名,所以下面的配置方式就是基于这个新域名的。

使用这个镜像,需要一些配置工作,有两个方法。一个是安装一个cnpm的工具来替换npm命令;另一个是修改npm软件仓库的默认设置,指向镜像仓库;笔者一般使用后者,操作过程和命令如下:

shell 复制代码
// 查看当前源
npm config get registry

// 修改使用镜像源
npm config set registry https://registry.npmmirror.com/

// 还原成为默认官方源
npm config set registry https://registry.npmjs.org/

// 如果要安装 cnpm 
npm install -g cnpm --registry=https://registry.npmmirror.com/

// 使用 cnpm
cnpm install fastify async 

常用命令

npm安装完成之后,一般是作为全局命令来进行工作的。我们可以通过 npm help 来看一下它提供的功能:

shell 复制代码
yanjh@WK-YANJH-AMD:~$ npm help
npm <command>

Usage:

npm install        install all the dependencies in your project
npm install <foo>  add the <foo> dependency to your project
npm test           run this project's tests
npm run <foo>      run the script named <foo>
npm <command> -h   quick help on <command>
npm -l             display usage info for all commands
npm help <term>    search for help on <term>
npm help npm       more involved overview

All commands:
    access, adduser, audit, bugs, cache, ci, completion,
    config, dedupe, deprecate, diff, dist-tag, docs, doctor,
    edit, exec, explain, explore, find-dupes, fund, get, help,
    help-search, hook, init, install, install-ci-test,
    install-test, link, ll, login, logout, ls, org, outdated,
    owner, pack, ping, pkg, prefix, profile, prune, publish,
    query, rebuild, repo, restart, root, run-script, sbom,
    search, set, shrinkwrap, star, stars, start, stop, team,
    test, token, uninstall, unpublish, unstar, update, version,
    view, whoami

Specify configs in the ini-formatted file:
    /home/yanjh/.npmrc
or on the command line via: npm <command> --key=value

More configuration info: npm help config
Configuration fields: npm help 7 config

npm@10.2.5 /usr/lib/node_modules/npm

可以看到,npm提供了丰富而强大的功能。但我们日常使用,只是其中很小的一部分,比如下面的一些命令和使用场景包括:

  • 安装全局包

一般用于安装一些全局可以使用工具,如pm2等。

sudo npm i pm2 -g

这里i是install的简写。-g是全局安装命令标签。

简单而言,全局安装需要管理员权限(sudo),会将软件包安装到全局模块文件夹中(/usr/lib/node_modules);而普通安装,只影响当前项目的内容,比如它会将软件包安装到项目文件夹的node_modules文件夹中。两者没有直接的逻辑关系。

如果要想在本地项目中,使用全局的npm包,可以使用npm link命令,它会项目中创建一个全局包的软链接。这种情况通常用于在开发和测试环境中共享一些常用的软件包。

  • 项目初始化

结合使用init命令,npm可以为当前文件夹建立nodejs项目配置信息,从而创建nodejs开发项目。

shell 复制代码
$ npm init -y 
Wrote to /home/yanjh/ntest/package.json:
... 

可以看到,这个init命令,实际上就是在当前文件夹中,创建一个package.json文件,这个就是用来控制当前nodejs程序项目的配置文件。这里的-y标签,就是yes,无需交互使用默认配置进行操作,当然,这些默认创建的内容,随后都可以使用命令或者手动进行编辑。

关于package.json文件,这部分的内容其实比较关键和重要,笔者在后续有一个独立的章节深入详细讨论。

  • 安装新软件包(并保存到package.json)

可以使用install子命令,在当前项目中安装所需要的软件包。这个命令可以直接指定npm的名称,执行时npm会在全球在线仓库中搜索、下载并在本地项目中安装这个软件包。这个过程是在线并且自动执行的。

npm i async --save

默认情况下,npm会将软件包,安装到当前项目的node_modules文件夹中,但不会修改package.json中相关的配置。而--save选项可以在package.json中增加这个软件包的信息。这样,如果项目进行了移植,下次就可以使用install自动进行安装。

  • 基于package.json配置安装软件包

npm i

i,就是install的简写。这个命令,会搜索当前package.json配置文件中(以前已经配置并且使用的)软件包的信息,进行自动化的安装,就和指定软件包名称一样,但可以批量的进行操作。这种方式通常在项目移植或者迁移过程中使用。

  • 更新npm版本

npm自身也是一个在不断升级中的软件,可以使用基本相同的方式对npm自己进行升级。基本的操作命令如下:

sudo npm i npm -g

npm模块离线安装

除了nodejs系统本身之外,我们的nodejs应用开发和运行,可能会依赖一些第三方库或者软件包。在正常的情况下,它们可能会使用前面提到的方式,使用npm命令来进行安装,但在离线的情况下,是没有在线的npm仓库可以使用的。

这时笔者摸索出的一种解决方案是:

用和生产环境相同的操作系统和软件环境基本相同的一个系统,部署一个可以正常使用npm环境,在正常安装npm软件包之后,将node_modules文件夹,整体复制到生产环境的相同的位置,一般就是项目文件的node_modules文件夹。

这里要注意的几个问题:

  • 测试环境和生产环境的操作系统和支撑软件尽量使用相同的配置,包括但不限于操作系统类型、版本、内核版本,用户名词、目录结构、node版本、其他支撑软件的版本和配置(如数据库客户端、OpenSSL..)等等。
  • 如果遇到需要进行编译操作的npm软件,还需要特别注意编译器和编译环境的一致

另外还有一种方式是有些npm会提供安装包文件,或者可以手动将已有模块打包,然后可以使用npm指定安装包文件来直接安装,例如:

npm pack

npm i -g my_module-0.0.1.tgz

PM2

由于本文的篇幅和内容限制,这部分内容独立成章,详见其他相关章节。

小结

本文主要探讨了nodejs环境的安装、配置和管理方面的内容。如nodejs程序文件结构,npm包管理的机制和操作,package.json文件,以及使用pm2进行nodejs应用管理等等。

相关推荐
桃园码工11 分钟前
第一章:Go 语言概述 1.什么是 Go 语言? --Go 语言轻松入门
开发语言·后端·golang
bpmf_fff11 分钟前
十、事件类型(鼠标事件、焦点.. 、键盘.. 、文本.. 、滚动..)、事件对象、事件流(事件捕获、事件冒泡、阻止冒泡和默认行为、事件委托)
前端·javascript
悦涵仙子1 小时前
vueuse中的useTemplateRefsList
前端·javascript·vue.js
萧萧玉树1 小时前
分布式在线评测系统
前端·c++·后端·负载均衡
桃园码工1 小时前
第一章:Go 语言概述 2.安装和配置 Go 开发环境 --Go 语言轻松入门
开发语言·后端·golang
蒙特网站2 小时前
网站布局编辑器前端开发:设计要点与关键考量
前端·javascript·学习·html
yun_shuo2 小时前
文件内容扫描工具
electron·node.js·vue
理想不理想v2 小时前
前端开发工程师需要学什么?
java·前端·vue.js·webpack·node.js
hummhumm2 小时前
第 36 章 - Go语言 服务网格
java·运维·前端·后端·python·golang·java-ee
凡人的AI工具箱2 小时前
40分钟学 Go 语言高并发:Pipeline模式(一)
开发语言·后端·缓存·架构·golang