From 907a80c914cd40a8763972f0acb23cc9371523cc Mon Sep 17 00:00:00 2001 From: ningmengchongshui <916415899@qq.com> Date: Sun, 16 Jun 2024 22:17:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=A8=E6=80=81=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- image/index.js | 24 ++++++++ image/main.ts | 127 ++++++++++++++++++++++++++----------------- image/nodemon.json | 8 --- image/tailwindcss.ts | 25 --------- package.json | 3 +- src/utils/module.ts | 22 ++++++++ 6 files changed, 126 insertions(+), 83 deletions(-) create mode 100644 image/index.js delete mode 100644 image/nodemon.json delete mode 100644 image/tailwindcss.ts diff --git a/image/index.js b/image/index.js new file mode 100644 index 0000000..f409099 --- /dev/null +++ b/image/index.js @@ -0,0 +1,24 @@ +import { spawn } from 'child_process' +const argv = [...process.argv].splice(2) +const argvs = argv.join(' ').replace(/(\S+\.js|\S+\.ts)/g, '') +const child1 = spawn( + 'tailwindcss -i ./src/input.css -o ./public/output.css --watch', + [], + { + shell: true, + stdio: 'inherit' + } +) +const child2 = spawn( + 'node --no-warnings=ExperimentalWarning --loader ts-node/esm image/main.ts', + argvs.split(' '), + { + shell: true, + stdio: 'inherit' + } +) +process.on('SIGINT', () => { + if (child1.pid) process.kill(child1.pid) + if (child2.pid) process.kill(child2.pid) + if (process.pid) process.exit() +}) diff --git a/image/main.ts b/image/main.ts index a874b5c..f3594a4 100644 --- a/image/main.ts +++ b/image/main.ts @@ -2,12 +2,11 @@ import '../src/init/require.js' import '../src/init/config.js' import '../src/init/logger.js' import '../src/init/redis.js' -import './tailwindcss.js' import Koa from 'koa' import KoaStatic from 'koa-static' import Router from 'koa-router' import { Component } from 'yunzai/utils' -import { readdirSync } from 'fs' +import { Dirent, readdirSync } from 'fs' import { join } from 'path' import mount from 'koa-mount' @@ -17,64 +16,89 @@ const router = new Router() const Port = 8080 const PATH = process.cwd() +const Dynamic = async (Router: Dirent) => { + const modulePath = `file://${join(Router.parentPath, Router.name)}?update=${Date.now()}` + return (await import(modulePath))?.default +} + // 得到plugins目录 const flies = readdirSync(join(process.cwd(), 'plugins'), { withFileTypes: true -}).filter(flie => !flie.isFile()) +}) + .filter(flie => !flie.isFile()) + .map(flie => { + const dir = flie?.path ?? flie?.parentPath + flie.parentPath = dir + return flie + }) // 增加兼容性 + +// +const Routers = [] // 解析路由 for (const flie of flies) { - const dir = flie?.path ?? flie?.parentPath - if (!dir) { - console.log('flie.name', flie.name, '识别错误') - continue - } - /** - * - */ - const plugins = readdirSync(join(dir, flie.name), { + const plugins = readdirSync(join(flie?.parentPath, flie.name), { withFileTypes: true - }).filter(flie => flie.isFile()) + }) + .filter( + flie => flie.isFile() && /^(routes.jsx|routes.tsx)$/.test(flie.name) + ) + .map(flie => { + const dir = flie?.path ?? flie?.parentPath + flie.parentPath = dir + return flie + }) // 增加兼容性 + + // for (const plugin of plugins) { - /** - * - */ - if (/^(routes.jsx|routes.tsx)$/.test(plugin.name)) { - const routes = (await import(`file://${join(plugin.path, plugin.name)}`)) - ?.default - if (!routes) continue - /** - * - */ - if (Array.isArray(routes)) { - /** - * - */ - for (const item of routes) { - const url = `/${flie.name}${item.url}` - console.log(`http://127.0.0.1:${Port}${url}`) - /** - * 推送接口 - */ - router.get(url, ctx => { - const options = item?.options ?? {} - const HTML = Com.create(item.element, { - ...options, - html_head: options?.html_head ?? '', - file_create: false - }) - // 转义路径中的所有反斜杠 - const escapedPath = PATH.replace(/\\/g, '\\\\') - // 创建一个正则表达式,'g' 表示全局匹配 - const regex = new RegExp(escapedPath, 'g') - ctx.body = HTML.replace(regex, '/file') - }) - } - } + const routes = await Dynamic(plugin) + // 不存在 + if (!routes) continue + // 不是数组 + if (!Array.isArray(routes)) continue + // + for (const item of routes) { + const url = `/${flie.name}${item.url}` + console.log(`http://127.0.0.1:${Port}${url}`) + Routers.push({ + parentPath: plugin.parentPath, + name: plugin.name, + uri: url, + url: item.url + }) } } } +for (const Router of Routers) { + router.get(Router.uri, async ctx => { + // 动态加载 + const routes = await Dynamic(Router) + // 不存在 + if (!routes) return + // 不是数组 + if (!Array.isArray(routes)) return + // 查找 + const item = routes.find(i => i.url == Router.url) + // 丢失了 + if (!item) return + /** + * 渲染html + */ + const options = item?.options ?? {} + const HTML = Com.create(item.element, { + ...options, + file_create: false + }) + // 转义路径中的所有反斜杠 + const escapedPath = PATH.replace(/\\/g, '\\\\') + // 创建一个正则表达式 + const regex = new RegExp(escapedPath, 'g') + // 置换为file请求 + ctx.body = HTML.replace(regex, '/file') + }) +} + // static app.use(mount('/file', KoaStatic(PATH))) @@ -83,6 +107,11 @@ app.use(router.routes()) // listen 8000 app.listen(Port, () => { + console.log('______________') console.log('Server is running on port ' + Port) - console.log('默认浏览器尺寸 800 X 1280 100%') + console.log('______________') + console.log('自行调整默认浏览器尺寸 800 X 1280 100%') + console.log('如果需要运行时重新计算className') + console.log('请确保一直打开此程序') + console.log('______________') }) diff --git a/image/nodemon.json b/image/nodemon.json deleted file mode 100644 index 98f0093..0000000 --- a/image/nodemon.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "watch": ["plugins"], - "ext": "tsx,jsx", - "exec": "node --no-warnings=ExperimentalWarning --loader ts-node/esm image/main.ts", - "env": { - "NODE_ENV": "development" - } -} diff --git a/image/tailwindcss.ts b/image/tailwindcss.ts deleted file mode 100644 index 96c76db..0000000 --- a/image/tailwindcss.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { spawn } from 'child_process' -/** - * ********** - * 生成css文件 - * ********** - */ -// exec('') - -const child = spawn( - 'tailwindcss -i ./src/input.css -o ./public/output.css --watch', - [], - { - shell: true, - stdio: 'inherit' - } -) -/** - * ************* - * exit - * ************* - */ -process.on('SIGINT', () => { - if (child.pid) process.kill(child.pid) - if (process.pid) process.exit() -}) diff --git a/package.json b/package.json index 8a84a9f..2dc426e 100644 --- a/package.json +++ b/package.json @@ -16,12 +16,13 @@ "logs": "pm2 logs", "monit": "pm2 monit", "pm2": "pm2", - "image": "nodemon --config image/nodemon.json", + "image": "node image/index.js", "css": "tailwindcss -i ./src/input.css -o ./public/output.css", "format": "prettier --write .", "prepare": "husky" }, "dependencies": { + "@loadable/component": "^5.16.4", "art-template": "^4.13.2", "chalk": "^5.3.0", "chokidar": "^3.6.0", diff --git a/src/utils/module.ts b/src/utils/module.ts index 9c6287e..1c58734 100644 --- a/src/utils/module.ts +++ b/src/utils/module.ts @@ -1,4 +1,5 @@ import { createRequire as cRequire } from 'module' + /** * @deprecated 已废弃 * @param basePath @@ -6,6 +7,7 @@ import { createRequire as cRequire } from 'module' export function createRequire(basePath: string) { return cRequire(basePath) } + /** * @deprecated 已废弃 * @param path @@ -16,3 +18,23 @@ export function require(path: string) { return cRequire(url)(path) } } + +const now = () => `?update=${Date.now()}` + +/** + * *********** + * 创建动态模块 + * *********** + * 动态模块每次访问都将重新加载, + * 如果动态模块内包含动态模块, + * 内部模块也会跟着重新加载, + * *********** + * 请确保你的模块是可预测 + * *********** + * 请确保当前模块是可被执行的 + * @param basePath + * @returns + */ +export const createDynamic = (basePath: string) => { + return (path: string) => import(new URL(`${path}${now()}`, basePath).href) +}