V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
oyps
V2EX  ›  程序员

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

  •  
  •   oyps ·
    oyps · 51 天前 · 2628 次点击
    这是一个创建于 51 天前的主题,其中的信息可能已经有所发展或是发生改变。

    技术参数

    • 前端: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  
       51 天前
    你这个,是不是 nextjs 就解决了
    “实现 npm run dev 一步到位启动前后端开发环境”
    oyps
        2
    oyps  
    OP
       51 天前
    @K332 没用过 NextJS ,不过我这个用的不是 React 而是原生 JS ,应该是没办法
    lisongeee
        3
    lisongeee  
       51 天前
    好奇为什么用 .mts 后缀,.ts 不行吗?

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

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

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

    另外现在一般不用 tsc 编译,用 tsup/unbuild/rollup 都能编译,还能支持编译多个格式,自定义后缀名等
    yagamil
        9
    yagamil  
       50 天前
    发现前端就是爱折腾各种轮子
    xhawk
        10
    xhawk  
       50 天前
    @oyps 我这边有一套跟你很像的环境. 我是这么启动的:
    "dev": "concurrently \"pnpm run dev-front\" \"nodemon --watch database database/server.js\"",
    oyps
        11
    oyps  
    OP
       50 天前
    @lisongeee 只用 TS 可以保持 ES ,只是我偏爱 MTS
    oyps
        12
    oyps  
    OP
       50 天前
    @lisongeee Node.js 的话,现在最新有一个 "module": "NodeNext",然后将后缀设置为 mts 和 cts 来区分我认为比较优雅。Node.js 生态下还好多库都没完全转到 ES ,我是希望能尽最大可能纯血 ES 去做。
    oyps
        13
    oyps  
    OP
       50 天前
    @lisongeee 我说的有点乱了哈哈,就是说是我自己比较喜欢用 mts ,就像 Java 里非要加上 public 、TypeScript 方法非要加上返回值的类型定义一样,觉得优雅一些,虽然不这么做也不影响使用。用了 mts 后就不想用 ts 了,有点回不去了。
    oyps
        14
    oyps  
    OP
       50 天前
    @lisongeee 感谢大佬的分析和建议,我会继续学习的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1940 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 01:03 · PVG 09:03 · LAX 18:03 · JFK 21:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.