feat(codegen): P 层闭环 —— 模板生成页面 + 画廊生成面板
- src/codegen.ts:PageDeclaration → definePage 源码(漂亮缩进,语法合法) - src/render.ts:导出 generatePageSource/starterPageFrom;画廊受控 selected/onSelect - playground generator.tsx:选布局→填标题→生成→复制/保存到 pages/ - vite 中间件 /__vr-save:浏览器 POST 落盘 pages/(HMR 生效) - 验证:codegen 产物通过工程 tsc;保存中间件落盘成功;画廊 UI headless 通过
This commit is contained in:
@@ -1,7 +1,42 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import { defineConfig, type Plugin } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { writeFileSync, mkdirSync } from 'node:fs'
|
||||
import { join, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
/** P 层闭环的写盘中间件:浏览器 POST 源码 → 落盘 pages/(HMR 自动生效) */
|
||||
function savePagePlugin(): Plugin {
|
||||
const root = dirname(fileURLToPath(import.meta.url))
|
||||
return {
|
||||
name: 'vr-save-page',
|
||||
configureServer(server) {
|
||||
server.middlewares.use('/__vr-save', (req, res) => {
|
||||
let body = ''
|
||||
req.on('data', (c) => (body += c))
|
||||
req.on('end', () => {
|
||||
try {
|
||||
const { filename, content } = JSON.parse(body) as { filename: string; content: string }
|
||||
if (!/^[a-z0-9-]+\.tsx?$/.test(filename)) {
|
||||
res.statusCode = 400
|
||||
res.end('bad filename')
|
||||
return
|
||||
}
|
||||
const target = join(root, 'pages', filename)
|
||||
mkdirSync(dirname(target), { recursive: true })
|
||||
writeFileSync(target, content, 'utf8')
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
res.end(JSON.stringify({ ok: true, path: `pages/${filename}` }))
|
||||
} catch (e) {
|
||||
res.statusCode = 500
|
||||
res.end(JSON.stringify({ ok: false, error: String(e) }))
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
plugins: [react(), savePagePlugin()],
|
||||
server: { port: 5183, open: false },
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user