小天管理 发表于 2024年7月18日 发表于 2024年7月18日 技术参数 前端: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 -w 和 nodemon 和 vite 每一个都会阻塞终端,但我希望能实现 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 -w 和 nodemon 和 vite 的,可是 nodemon 执行前必须要确保待执行的 .mjs 文件存在,可是 tsc -w 不一定来得及编译完成,所以我就在 concurrently 加一个一次性的 tsc,可是 concurrently 会执行一次 nodemon,tsc -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))
已推荐帖子