feat: 动态组件

This commit is contained in:
ningmengchongshui 2024-06-16 22:17:29 +08:00
parent 49f9a0a4d7
commit 907a80c914
6 changed files with 126 additions and 83 deletions

24
image/index.js Normal file
View File

@ -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()
})

View File

@ -2,12 +2,11 @@ import '../src/init/require.js'
import '../src/init/config.js' import '../src/init/config.js'
import '../src/init/logger.js' import '../src/init/logger.js'
import '../src/init/redis.js' import '../src/init/redis.js'
import './tailwindcss.js'
import Koa from 'koa' import Koa from 'koa'
import KoaStatic from 'koa-static' import KoaStatic from 'koa-static'
import Router from 'koa-router' import Router from 'koa-router'
import { Component } from 'yunzai/utils' import { Component } from 'yunzai/utils'
import { readdirSync } from 'fs' import { Dirent, readdirSync } from 'fs'
import { join } from 'path' import { join } from 'path'
import mount from 'koa-mount' import mount from 'koa-mount'
@ -17,64 +16,89 @@ const router = new Router()
const Port = 8080 const Port = 8080
const PATH = process.cwd() 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目录 // 得到plugins目录
const flies = readdirSync(join(process.cwd(), 'plugins'), { const flies = readdirSync(join(process.cwd(), 'plugins'), {
withFileTypes: true 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) { for (const flie of flies) {
const dir = flie?.path ?? flie?.parentPath const plugins = readdirSync(join(flie?.parentPath, flie.name), {
if (!dir) {
console.log('flie.name', flie.name, '识别错误')
continue
}
/**
*
*/
const plugins = readdirSync(join(dir, flie.name), {
withFileTypes: true 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) { for (const plugin of plugins) {
/** const routes = await Dynamic(plugin)
* // 不存在
*/ if (!routes) continue
if (/^(routes.jsx|routes.tsx)$/.test(plugin.name)) { // 不是数组
const routes = (await import(`file://${join(plugin.path, plugin.name)}`)) if (!Array.isArray(routes)) continue
?.default //
if (!routes) continue for (const item of routes) {
/** const url = `/${flie.name}${item.url}`
* console.log(`http://127.0.0.1:${Port}${url}`)
*/ Routers.push({
if (Array.isArray(routes)) { parentPath: plugin.parentPath,
/** name: plugin.name,
* uri: url,
*/ url: item.url
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')
})
}
}
} }
} }
} }
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 // static
app.use(mount('/file', KoaStatic(PATH))) app.use(mount('/file', KoaStatic(PATH)))
@ -83,6 +107,11 @@ app.use(router.routes())
// listen 8000 // listen 8000
app.listen(Port, () => { app.listen(Port, () => {
console.log('______________')
console.log('Server is running on port ' + Port) 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('______________')
}) })

View File

@ -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"
}
}

View File

@ -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()
})

View File

@ -16,12 +16,13 @@
"logs": "pm2 logs", "logs": "pm2 logs",
"monit": "pm2 monit", "monit": "pm2 monit",
"pm2": "pm2", "pm2": "pm2",
"image": "nodemon --config image/nodemon.json", "image": "node image/index.js",
"css": "tailwindcss -i ./src/input.css -o ./public/output.css", "css": "tailwindcss -i ./src/input.css -o ./public/output.css",
"format": "prettier --write .", "format": "prettier --write .",
"prepare": "husky" "prepare": "husky"
}, },
"dependencies": { "dependencies": {
"@loadable/component": "^5.16.4",
"art-template": "^4.13.2", "art-template": "^4.13.2",
"chalk": "^5.3.0", "chalk": "^5.3.0",
"chokidar": "^3.6.0", "chokidar": "^3.6.0",

View File

@ -1,4 +1,5 @@
import { createRequire as cRequire } from 'module' import { createRequire as cRequire } from 'module'
/** /**
* @deprecated * @deprecated
* @param basePath * @param basePath
@ -6,6 +7,7 @@ import { createRequire as cRequire } from 'module'
export function createRequire(basePath: string) { export function createRequire(basePath: string) {
return cRequire(basePath) return cRequire(basePath)
} }
/** /**
* @deprecated * @deprecated
* @param path * @param path
@ -16,3 +18,23 @@ export function require(path: string) {
return cRequire(url)(path) 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)
}