客户在天津市滨海新区做物流管理系统,前端用Vue,后端用Node.js。开发阶段都在本地Windows电脑上做的,一切正常。部署到服务器上的时候,npm install一直报错,试了好几次都装不上依赖。
报错内容
错误信息大概是node-gyp编译失败,具体是某个依赖包在安装过程中需要编译原生模块,而服务器上缺少Python和C++编译工具链。
这个依赖包是canvas,用于在Node.js里生成图片的,需要编译C++代码。本地Windows上有Visual Studio的编译环境,所以能装上。服务器是Linux,默认没有这些编译工具。
解决方案
方案一:在服务器上安装编译工具链。用apt install build-essential python3或者yum install gcc-c++ make python3装上编译环境,然后再npm install就能编译通过了。缺点是编译过程比较慢,而且如果依赖包版本升级,可能还需要重新编译。
方案二:换用预编译的二进制包。很多原生模块都提供了预编译的版本,比如canvas可以用@napi-rs/canvas替代,纯JS实现,不需要编译。改了一下依赖包的引用,把canvas换成了@napi-rs/canvas,npm install秒过。
方案三:用Docker部署。把Node.js项目打包成Docker镜像,在镜像里提前把依赖装好,部署的时候直接拉镜像运行。这样本地和服务器环境完全一致,不会出现“本地能跑服务器跑不了”的问题。
客户选了方案二,因为改动最小,而且@napi-rs/canvas的性能比canvas还好一些。
还遇到一个问题
依赖装完之后,npm run build打包前端的时候报内存不足。服务器的内存是2G,Node.js打包过程中占用的内存超过了默认限制。在命令前加了NODE_OPTIONS=--max-old-space-size=1024,把Node.js的内存上限调高了一点,打包顺利完成。
客户那边的情况
客户在天津滨海新区做物流,系统主要是给内部的调度员和司机用的。开发人员之前没怎么接触过Linux服务器,遇到npm install报错的时候第一反应是“服务器有问题”。其实大部分情况是环境差异导致的,跟服务器本身没关系。
一点补充
Node.js项目部署到Linux服务器上,最常见的坑就是原生模块编译。如果不想折腾编译环境,优先找预编译的替代包。如果项目依赖比较复杂,建议直接用Docker,把环境打包进去,省去服务器上装各种工具的麻烦。
