请教大佬,怎么优雅的配置开发环境 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
oyps
V2EX    程序员

请教大佬,怎么优雅的配置开发环境

  •  
  •   oyps
    oyps 2024-07-18 17:22:46 +08:00 3191 次点击
    这是一个创建于 480 天前的主题,其中的信息可能已经有所发展或是发生改变。

    技术参数

    • 前端:Vanilla JS + TypeScript + Vite
    • 后端:Node.js + TypeScript + Nodemon
    • 前后端都使用 .mts 后缀

    项目结构

    client/ --- 前端 Vite 项目 src/main.mts --- 前端 TS 代码文件 index.html --- Vite 入口 vite.config.mts --- Vite 配置 tsconfig.json --- 前端 TS 配置 package.json server/ --- 后端 Node.js Koa 项目 src/main.mts --- 后端 TS 代码文件 tsconfig.json --- 后端 TS 配置 package.json dev.mjs package.json 

    希望实现的目标

    • 后端修改 .mts 文件后,自动编译为 .mjs,然后自动重启后端,已知 ts-node 运行 .mts 文件有一堆报错
    • tsc -wnodemonvite 每一个都会阻塞终端,但我希望能实现 npm run dev 一步到位启动前后端开发环境

    我目前的方案(期待大大佬给给建议)

    • client/package.json
      { "build": "vite build", "dev": "vite --host=0.0.0.0", "preview": "vite preview" } 
    • server/package.json
      { "build": "tsc", "build:watch": "tsc -w", "dev": "nodemon dist/main.mjs" } 
    • package.json
      { "build:client": "npm run build --prefix client", "build:server": "npm run build --prefix server", "build": "npm run build:client && npm run build:server", "dev:client": "npm run dev --prefix client", "dev:server": "npm run dev --prefix server", "build:watch:server": "npm run build:watch --prefix server", "dev": "node dev.mjs" } 

    dev.mjs

    本来想用 concurrently 并发执行 tsc -wnodemonvite 的,可是 nodemon 执行前必须要确保待执行的 .mjs 文件存在,可是 tsc -w 不一定来得及编译完成,所以我就在 concurrently 加一个一次性的 tsc,可是 concurrently 会执行一次 nodemontsc -w 又会触发一次 nodemon,如果 Koa 在服务运行中时还打印内容的话,终端就会出现重复的一堆打印内容,实在不优雅。

    import { spawn } from 'cross-spawn' const tscWatchProcess = spawn('npm', ['run', 'build:watch:server']) await new Promise((resolve, reject) => { tscWatchProcess.stdout.on('data', /** @param {Buffer} chunk */ chunk => { if (chunk.toString().includes('Watching for file changes')) { resolve() } } ) tscWatchProcess.stdout.on('error', reject) tscWatchProcess.stderr.on('error', reject) tscWatchProcess.stderr.on('data', reject) }) const viteProcess = spawn('npm', ['run', 'dev:client']) const modemOnProcess= spawn('npm', ['run', 'dev:server']) /** * @param {string} tag * @param {Buffer} chunk * @param {boolean} isError */ const handler = (tag, chunk) => { chunk.toString().split('\n').forEach(line => { if (line) console.log(`${line}`) }) } viteProcess.stdout.on('data', chunk => handler('client', chunk)) modemonProcess.stdout.on('data', chunk => handler('server', chunk)) viteProcess.stderr.on('data', chunk => handler('client', chunk)) modemonProcess.stderr.on('data', chunk => handler('server', chunk)) 
    14 条回复    2024-07-19 17:52:27 +08:00
    K332
        1
    K332  
       2024-07-18 18:01:16 +08:00
    你这个,是不是 nextjs 就解决了
    “实现 npm run dev 一步到位启动前后端开发环境”
    oyps
        2
    oyps  
    OP
       2024-07-18 18:20:33 +08:00
    @K332 没用过 NextJS ,不过我这个用的不是 React 而是原生 JS ,应该是没办法
    lisongeee
        3
    lisongeee  
       2024-07-18 19:21:12 +08:00
    好奇为什么用 .mts 后缀,.ts 不行吗?

    直接运行 ts 可以直接用 https://www.npmjs.com/package/tsx
    duhbbx1119
        4
    duhbbx1119  
       2024-07-18 20:40:00 +08:00
    你玩儿真是花,我要是前后端一起,直接用 nextjs 了
    xhawk
        5
    xhawk  
       2024-07-18 23:26:03 +08:00 via Android
    你用 nodemon 是对的,但是要修改 npm run dev 脚本,你可以用 gpt 来协助处理一下
    oyps
        6
    oyps  
    OP
       2024-07-19 03:27:36 +08:00
    @lisongeee 用 .mts 是为了优雅的保持 ES 模块。tsx 还没用过,之前是用的 ts-node ,看来又出了个类似的。

    @duhbbx1119 主要就是自己折腾,全原生去打造项目,可定制性强,路由也要自己写。

    @xhawk 问过 GPT 了,没什么有价值的信息,GPT 给我提供的是 ts-node ,可是那个东西不适合 .mts
    realJamespond
        7
    realJamespond  
       2024-07-19 09:55:13 +08:00
    纯后端 nestjs 了解下
    lisongeee
        8
    lisongeee  
       2024-07-19 10:02:57 +08:00
    只用 ts 怎么就不能保持 es 模块了,好奇你是不是没在 package.json 设置 type:"module",因为只有这种情况下才一定需要 .mjs

    另外现在一般不用 tsc 编译,用 tsup/unbuild/rollup 都能编译,还能支持编译多个格式,自定义后缀名等
    yagamil
        9
    yagamil  
       2024-07-19 10:09:07 +08:00
    发现前端就是爱折腾各种轮子
    xhawk
        10
    xhawk  
       2024-07-19 14:44:04 +08:00
    @oyps 我这边有一套跟你很像的环境. 我是这么启动的:
    "dev": "concurrently \"pnpm run dev-front\" \"nodemon --watch database database/server.js\"",
    oyps
        11
    oyps  
    OP
       2024-07-19 16:03:47 +08:00
    @lisongeee 只用 TS 可以保持 ES ,只是我偏爱 MTS
    oyps
        12
    oyps  
    OP
       2024-07-19 16:07:57 +08:00
    @lisongeee Node.js 的话,现在最新有一个 "module": "NodeNext",然后将后缀设置为 mts 和 cts 来区分我认为比较优雅。Node.js 生态下还好多库都没完全转到 ES ,我是希望能尽最大可能纯血 ES 去做。
    oyps
        13
    oyps  
    OP
       2024-07-19 16:31:29 +08:00
    @lisongeee 我说的有点乱了哈哈,就是说是我自己比较喜欢用 mts ,就像 Java 里非要加上 public 、TypeScript 方法非要加上返回值的类型定义一样,觉得优雅一些,虽然不这么做也不影响使用。用了 mts 后就不想用 ts 了,有点回不去了。
    oyps
        14
    oyps  
    OP
       2024-07-19 17:52:27 +08:00
    @lisongeee 感谢大佬的分析和建议,我会继续学习的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5171 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 09:04 PVG 17:04 LAX 01:04 JFK 04:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86