当前位置: 首页 > news >正文

最近给 node 项目写 CLI 库的时遇到的两个开发问题

node 环境,项目形式是 monorepo。

工程可以认为是某种开放的引擎(有一个 packages 文件夹装所有的库,以及一个用户的目录)

我的 cli 库需要动态执行用户的一些文件(.ts)。

压根没料到这么麻烦

这个事情看起来很简单,如果 cli 也在用户目录下,我们直接运行 tsx 之类的工具就行。

不过现在的情况是,因为仓库是 monorepo,这里 cli 库是一个子库,于是流程是

  • 用 vite 把 cli 提前打包成 bin
  • 在用户目录里安装到 devDependencies

这样就遇到了两个很神秘的问题。

--import tsx

用 node 执行 cli.js (里面包含 import("xxx.ts") 语句) 会报错,因为原生肯定不支持 ts。
一个解决方案是 node --import tsx cli.js,这样肯定能工作,然而

简单研究了一下,vite 打包成 bin 以后没办法加参数 --import tsx,除非手工改产物(也可能是我不知道怎么做)

解决方案就比较邪恶,我们把入口文件换成一个 bin.js(而不是 cli.js)
我们 spawn 一个子进程,把参数加上去以后,运行 dist/cli.js

#!/usr/bin/env nodeimport { spawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import path from 'node:path';const __dirname = path.dirname(fileURLToPath(import.meta.url));const CLI_DIST = path.join(__dirname, 'dist', 'cli.js');const args = ['--no-warnings', '--import', 'tsx', CLI_DIST, ...process.argv.slice(2)];const child = spawn(process.execPath, args, {stdio: 'inherit',shell: false,
});child.on('exit', (code) => process.exit(code ?? 0));

这个代码是个原型,如果你写正式工程,这里还要提前判用户 node 版本(因为低版本没有 --import)

这样的好处是 cli 打包结果很纯洁,非常小,不含 tsx 等解释器的东西(peer 装到用户那边)。
同时 cli 实际拿到的 process.argv 依然是不含 --import tsx 的,保留了原样。

执行环境不同

这里遇到了第二个问题,执行环境不同

// cli 的代码
import { some } from '@repo/lib'
await import('user.ts');
console.log(some)// user.ts 的代码
import { some } from '@repo/lib'
console.log(some)

这两个 some 不是同一个,估计是因为 user.ts 是被动态导入的。

解决方法是我们让 cli 拿到用户侧导入的库的储存地址,然后 import 进来就行

import { createRequire } from 'module';
import { pathToFileURL } from 'url';const require = createRequire(import.meta.url);
const libPath = require.resolve('@repo/lib'); // 拿到用户的那个 lib 的 pathconst { some } = (await import(pathToFileURL(path).href)).default as typeof import('@repo/lib');

这样是 some 就是同一个了,有点神秘啊这个做法。。。

http://www.jsqmd.com/news/254837/

相关文章:

  • 真正的风险在于工作流安全而非模型安全
  • 本周网络安全威胁通报:AI语音克隆漏洞等多起事件
  • Anaconda+CUDA+PyTorch下载教程
  • 设备一离线任务就挂?我在鸿蒙分布式项目中踩过的失败恢复坑
  • 关于DAG定向问题的一些补充
  • 有关平衡树
  • 51单片机_DS1302
  • 工具Cursor(三)MCP(2)自定义mcp tools集成到cursor中的demo
  • 20260116紫题训练总结 - Link
  • Playwright处理验证码的自动化解决方案
  • 【2026目标检测】高质量模型汇总
  • 工具Cursor(三)MCP(1)介绍
  • 拥有AI员工,才发现误会了领导
  • 阿里千问落地谷歌UCP+A2UI,中国率先进入AI办事时代
  • 浙大陆展团队突破铁催化难题,实现高效氢联硅化反应 | 乐研试剂
  • P3349 [ZJOI2016] 小星星 - Link
  • 企业如何破解业法财融合痛点?AI风控探针的 4 个落地步骤
  • Nature发表、Science点赞!清华揭秘AI让科学家走捷径却让科学走窄路
  • 【RAG召回排序】2025最全排序模型梳理
  • AI技术唾手可得的时代,挖掘新需求是产品突围的关键——某知名聚合DNS管理系统的需求洞察
  • 编程已终结!AI时代的原生智能软件架构长啥样?Claude给了个指南
  • 安卓神器 --- 浏览器 之 yandex 狐猴浏览器 chrome firefox
  • P11714 [清华集训 2014] 主旋律 Sol
  • 夏天还不算开始——我,不会退役
  • GD5F1GM7UEYIGR:兆易创新1Gbit SPI NAND闪存,高效低功耗
  • 4B超越8B比肩30B!清华、面壁智能端侧智能体天花板开源
  • 企业软件供应链安全治理立项,方案书/立项书该怎么写?
  • [Non] 字符串问题
  • 谷歌Veo 3.1更新:更一致性、更具创造力和控制力
  • 评正高写书10万字什么价格?