0

一个部署 NodeJS 项目遇到的依赖问题

 4 months ago
source link: https://paugram.com/tech/pnpm-not-install-dev-deps-on-ci.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一个部署 NodeJS 项目遇到的依赖问题

一个部署 NodeJS 项目遇到的依赖问题

2023.10.30做个技术宅 0 447

又是一个万恶的周一,回到公司发现上周五改完需求提交的代码在 CI 的时候发生了故障(还好只是测试环境)。简单概括,就是不知道为什么 ua-parser-js 这个依赖的 TypeScript 类型读取不到,需要安装一个叫 @types/ua-parser-js 的库。

Type error: Could not find a declaration file for module 'ua-parser-js'. '/app/node_modules/.pnpm/[email protected]/node_modules/ua-parser-js/src/ua-parser.js' implicitly has an 'any' type.

Try `npm i --save-dev @types/ua-parser-js` if it exists or add a new declaration (.d.ts) file containing `declare module 'ua-parser-js';`

  1 | import axios from "axios";
> 2 | import uap from "ua-parser-js";
    |                 ^

而实际上这个库我是已经安装了的,只是它写在了 package.json 文件的 devDependencies 里面。这个项目的 package.json 有个很诡异的点,就是几乎所有的包都写在了 dependencies 里面,包括其他 @types/xxxx 的包,我就觉得很奇怪,为什么读取不到 devDependencies 里面的包呢?

我从 CI 的流程一步一步看,最终定位到了 DockerFile 文件,光看代码的执行流程并没有发现什么奇怪的问题,总体来说就是安装依赖,启动进程,然后导出 3000 端口映射。我尝试用自己本地的 Docker 环境跑了一遍。

FROM node:18.15.0 AS runner

WORKDIR /app

ENV NODE_ENV production

RUN addgroup --system --gid 941 nodejs
RUN adduser --system --uid 941 nextjs

COPY . ./

WORKDIR ./

RUN chmod 777 .
RUN npx --yes pnpm install
RUN npx pnpm build

USER nextjs

EXPOSE 3000

ENV PORT 3000

CMD ["npm", "start"]
docker build -t usercenter .

结果和前文一样,也是一模一样的报错。我尝试排查问题,并把这个配置文件发到了群里,@提莫 认为可能是环境变量 ENV NODE_ENV production 这行设置导致的。这小小的变量设置影响会有这么大么,我去掉它重新打包,发现的确正常了。

devDeps 是干什么的

先不说环境变量的事,为什么要有 devDependencies 而不是直接 dependencies 一把梭呢,我认为这个包如果要提供给其他包使用,总会有一个打包好的版本可以直接使用(不需要在父项目里面再执行构建一遍代码),那么负责构建过程的包是不是就没有必要被再次安装了?

如果你要构建这个项目本身,则还是必须安装 devDependencies 下的依赖才行,可以看看用 Vite 一类的脚手架,他们的 package.json 是不是就是这么写的?

为什么没有安装 devDeps

既然 devDependencies 的使用方式是正确的,那么错就错在其他地方了。仔细看过程,环境变量的设置放在了最前面,后面才安装依赖文件,这就可能导致没能安装上 devDependencies 下的所有依赖。

这个猜想是正确的,我查阅了 PNPM 的文档,的确是这样子。因此这个 DockerFile 的过程是存在问题的,不应该在安装依赖之前强制设置成 production 模式。

pnpm will not install any package listed in devDependencies and will remove those insofar they were already installed, if the NODE_ENV environment variable is set to production. Use this flag to instruct pnpm to ignore NODE_ENV and take its production status from this flag instead.

如果 NODE_ENV 环境变量被设置为 production, pnpm 将不会安装 devDependencies 中列出的任何包,并且将删除那些已经安装的包。使用这个标志可以指示 pnpm 忽略 NODE_ENV,并从这个标志中获取它的生产状态。

同时感谢群友 @咲奈 的回答:

  1. 好像确实是这样,如果你在 pnpm i 安装的时候就给了 NODE_ENV 为生产,就不装 devDeps
  2. Docker 文件里不需要声明 NODE_ENV,因为你也没用到这个变量,还影响了 pnpm i 安装的依赖
  3. Scripts 里不需要使用 cross-env 设定 NODE_ENV,在常规情况下,它的值一般只有 development / test / production,并且由构建工具自动帮你设定,你不需要设定。
  4. 如果在特殊情况下,需要在过程中 productionNODE_ENV 下执行 pnpm i,workaround 时先把 NODE_ENV 改成 development 装完依赖再改回来。
  5. 不应该把 @types/* 下面的依赖放到 deps 里,虽然大部分情况下,依赖在哪都是无所谓的,这只是个通俗约定,但你问的 GPT 骗了你

Paul

特立独行的一只前端菜狗。本站未注明转载的文章均为原创,并采用 CC BY-NC-SA 4.0 授权协议,转载请注明来源,谢谢!如本站内容对你有所帮助的话,不妨 捐助支持 一下?同时欢迎订阅关注 我的日记,唠嗑(分享)每日的折腾经历。


Recommend

  • 4

    记Quartz中使用AutoFac依赖注入遇到的问题发布于 8 月 15 日       最近在做一个需求,就是在Job中捕捉异常,然后通过邮件或者消息的方式推送给指定人员,在需求实现...

  • 3
    • xuedingmiao.com 2 years ago
    • Cache

    前端项目nodejs自动部署脚本

    一个脚本辅助部署前端项目 公司有些项目环境没有接入 jenkins 所以部署起来比较麻烦,所以写个脚本节约部署时间。 # 背景 前端项目分开发、测试...

  • 4

    Python 实战项目解决循环依赖问题 ...

  • 2

    加强版的微信支付APIv3媒体文件上传无依赖版NodeJS实现 没啥思路,纯体力活,就是用NodeJS来实现一把媒体文件上传的 rfc1867/rfc2388 协议。 NodeJS上可以搜罗到的 multipart 实现,大部分是解释器,装载器引用最多的是

  • 1
    • thenorthmemory.github.io 2 years ago
    • Cache

    rfc2388表单上传文件NodeJS无依赖版本实现

    rfc2388表单上传文件NodeJS无依赖版本实现 - TheNorthMemory官方文档小分队犯了一个错误,就是试图用文本语言来表达非字符内容,整得一众开发者迷途了,社区反馈波澜滔滔。这支小分队应该每人扣一个长鹅抱宠,捐给像俺这样努力帮扶开发者的贡献者(😄)。其实rfc...

  • 3
    • wwj718.github.io 2 years ago
    • Cache

    Ruby/Nodejs解释器版本依赖笔记

    最近在折腾一个项目,对Ruby/Nodejs的版本有要求 ruby –version // ruby 2.2.3 node –version // v0.12.4 npm –version // 2.10.1 Ubuntu14.04 采用RVM来...

  • 11
    • zjinc36.github.io 3 years ago
    • Cache

    项目遇到的问题之Spark

    Aug 29, 2020BigDataSparkStreaming优雅关闭如何优雅的关闭SparkStreaming任务(将写好的代码打包,Spark-Submit) => Kill -9 xxx ?开启另外一个线程每5秒...

  • 10
    • zjinc36.github.io 3 years ago
    • Cache

    项目遇到的问题之Sqoop

    项目遇到的问题之Sqoop想了20分钟的博客名世界是唯物辩证的项目遇到的问题之SqoopAug 28, 2020BigDa...

  • 4

  • 5

    注意⚠️:阅读本文可能会浪费您宝贵的 5 分钟,本篇主要是吐槽和分享个人为维护 Github 项目以来的一些有趣的经历,所以阅读本文并不会增长你的技术,但是可能会给你带来一点欢乐。 开通 Github 至今也有 6 年...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK