diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 0000000..1e13871 --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,16 @@ +# bun 编译配置:将 dist 下的所有资源一并内嵌到可执行文件中 +# 注意:命令行中的 --compile/--outfile 参数依然可以覆盖这里的设置 + +[compile] +# 入口文件(与 package.json 的 bundle:exe 一致) +entrypoint = "dist/booststap.js" + +# 需要内嵌到可执行文件中的静态资源(包含服务端/客户端产物) +assets = [ + "dist/**" +] + +# 输出可执行文件路径 +outfile = "dist/koa-ssr.exe" + + diff --git a/internal/helper/src/env.ts b/internal/helper/src/env.ts index 799d3a6..4f46500 100644 --- a/internal/helper/src/env.ts +++ b/internal/helper/src/env.ts @@ -1,11 +1,9 @@ -const isProduction = process.env.NODE_ENV === 'production' const port = process.env.PORT || 5173 const base = process.env.BASE || '/' export const Env = { - isProduction, port: Number(port), base } \ No newline at end of file diff --git a/internal/helper/src/path.ts b/internal/helper/src/path.ts index 0a105e2..405960d 100644 --- a/internal/helper/src/path.ts +++ b/internal/helper/src/path.ts @@ -1,14 +1,12 @@ import path from "node:path" import fs from "node:fs/promises" -export const isProduction = process.env.NODE_ENV === 'production' - export function getPathByRoot(...argus: string[]) { return path.resolve(import.meta.dir, '../../..', ...argus) } // 生产环境路径配置 -export const TemplateHtml = isProduction ? await fs.readFile('./client/index.html', 'utf-8') : "" +export const TemplateHtml = process.env.NODE_ENV === 'production' ? await fs.readFile('./client/index.html', 'utf-8') : "" export const serverPublic = path.resolve("./public") export const serverModules = path.resolve("./modules") export const jobsDir = path.resolve("./jobs/jobs") diff --git a/package.json b/package.json index 5f8b1bf..3694e64 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "dev": "bun run --hot packages/server/src/booststap.ts", "build:client": "bun run --filter client build", "start": "cd dist && cross-env NODE_ENV=production bun run booststap.js", - "build:all": "tsup --config tsup.config.ts", + "build:all": "cross-env NODE_ENV=production tsup --config tsup.config.ts", "build": "rimraf dist && bun run build:client && bun run build:all && node scripts/build.js", + "bundle:exe": "bun build --compile ./dist/booststap.js ./dist/jobs/**/* --minify --outfile ./dist/koa-ssr.exe", + "build:exe": "bun run build && bun run bundle:exe", "tsc:booststap": "tsc packages/booststap/src/server.ts --outDir dist --module es2022 --target es2022 --lib es2022,dom --moduleResolution bundler --esModuleInterop --skipLibCheck --forceConsistentCasingInFileNames --noEmit false --incremental false", "tsc:server": "tsc packages/server/src/**/*.ts --outDir dist/server --module es2022 --target es2022 --lib es2022,dom --moduleResolution bundler --esModuleInterop --skipLibCheck --forceConsistentCasingInFileNames --noEmit false --incremental false" }, diff --git a/packages/client/components.d.ts b/packages/client/components.d.ts index 34cb5de..a18904a 100644 --- a/packages/client/components.d.ts +++ b/packages/client/components.d.ts @@ -14,6 +14,9 @@ declare module 'vue' { CookieDemo: typeof import('./src/components/CookieDemo.vue')['default'] DataFetch: typeof import('./src/components/DataFetch.vue')['default'] HelloWorld: typeof import('./src/components/HelloWorld.vue')['default'] + MazBtn: typeof import('maz-ui/components/MazBtn')['default'] + MazExpandAnimation: typeof import('maz-ui/components/MazExpandAnimation')['default'] + MazInput: typeof import('maz-ui/components/MazInput')['default'] Msg: typeof import('./src/components/ChatBox/_/Msg.vue')['default'] Node: typeof import('./src/components/ChatBox/_/Node.vue')['default'] QuillEditor: typeof import('./src/components/QuillEditor/index.vue')['default'] diff --git a/packages/client/src/typed-router.d.ts b/packages/client/src/typed-router.d.ts index 1924560..3ba7ea3 100644 --- a/packages/client/src/typed-router.d.ts +++ b/packages/client/src/typed-router.d.ts @@ -1,7 +1,7 @@ /* eslint-disable */ /* prettier-ignore */ // @ts-nocheck -// Generated by unplugin-vue-router. \u203C\uFE0F DO NOT MODIFY THIS FILE \u203C\uFE0F +// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️ // It's recommended to commit this file. // Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry. diff --git a/packages/core/src/SsrMiddleWare.ts b/packages/core/src/SsrMiddleWare.ts index 8582769..9b3cc08 100644 --- a/packages/core/src/SsrMiddleWare.ts +++ b/packages/core/src/SsrMiddleWare.ts @@ -1,8 +1,8 @@ import fs from 'node:fs/promises' -import { isProduction, TemplateHtml, getPathByRoot, clientRoot, ssrManifest, entryServer } from "helper/path" +import { TemplateHtml, getPathByRoot, clientRoot, ssrManifest, entryServer } from "helper/path" import { parseCookieHeader } from "helper/cookie" import { Env } from "helper/env" -import { ViteDevServer } from 'vite' +import type { ViteDevServer } from 'vite' import Send from 'koa-send' import type Koa from 'koa' import c2k from 'koa-connect' @@ -12,7 +12,7 @@ const base = Env.base export async function SsrMiddleWare(app: Koa, options?: { onDevViteClose?: Function }) { let vite: ViteDevServer - if (!isProduction) { + if (process.env.NODE_ENV !== 'production') { // Dev mode: create Vite server in middleware mode. const { createServer } = await import('vite') vite = await createServer({ @@ -54,7 +54,7 @@ export async function SsrMiddleWare(app: Koa, options?: { onDevViteClose?: Funct let template let render let manifest - if (!isProduction) { + if (process.env.NODE_ENV !== 'production') { // Always read fresh template in development template = await fs.readFile(getPathByRoot('packages', 'client/index.html'), 'utf-8') template = await vite.transformIndexHtml(url, template) diff --git a/packages/server/src/jobs/index.ts b/packages/server/src/jobs/index.ts index c4d3a2d..3773723 100644 --- a/packages/server/src/jobs/index.ts +++ b/packages/server/src/jobs/index.ts @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; import scheduler from './scheduler'; import { TaskOptions } from 'node-cron'; -import { isProduction, jobsDir } from 'helper/path'; +import { jobsDir } from 'helper/path'; import { logger } from '@/logger'; interface OneJob { @@ -18,11 +18,11 @@ export function defineJob(job: OneJob) { return job; } -const _jobsDir = isProduction ? jobsDir : path.join(__dirname, 'jobs'); +const _jobsDir = process.env.NODE_ENV === 'production' ? jobsDir : path.join(__dirname, 'jobs'); const jobModules: Record = {}; fs.readdirSync(_jobsDir).forEach(async file => { - if (!file.endsWith(isProduction ? 'Job.js' : 'Job.ts')) return; + if (!file.endsWith(process.env.NODE_ENV === 'production' ? 'Job.js' : 'Job.ts')) return; const jobModule = await import(path.join(_jobsDir, file)); const job = jobModule.default || jobModule; if (job && job.id && job.cronTime && typeof job.task === 'function') { diff --git a/packages/server/src/middleware/install.ts b/packages/server/src/middleware/install.ts index 3c519b5..aa9811d 100644 --- a/packages/server/src/middleware/install.ts +++ b/packages/server/src/middleware/install.ts @@ -12,7 +12,7 @@ import { DefaultContext, Next, ParameterizedContext } from "koa" import { AuthMiddleware } from "./Auth" import Session from "./Session" import Send from "./Send" -import { getPathByRoot, isProduction, serverModules, serverPublic } from "helper/path" +import { getPathByRoot, serverModules, serverPublic } from "helper/path" type App = typeof app @@ -31,7 +31,7 @@ export default async (app: App) => { }) - const publicPath = isProduction ? serverPublic : getPathByRoot("public") + const publicPath = process.env.NODE_ENV === 'production' ? serverPublic : getPathByRoot("public") app.use(async (ctx, next) => { if (!ctx.path.startsWith("/public")) return await next() if (ctx.method.toLowerCase() === "get") { @@ -65,7 +65,7 @@ export default async (app: App) => { app.use(bodyParser()) app.use( await Controller({ - root: isProduction ? serverModules : path.resolve(__dirname, "../modules"), + root: process.env.NODE_ENV === 'production' ? serverModules : path.resolve(__dirname, "../modules"), handleBeforeEachRequest: (options: any) => { const { auth = true } = options || {} return async (ctx: ParameterizedContext, next: Next) => { diff --git a/tsup.config.ts b/tsup.config.ts index 9e57ea1..909642e 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -10,9 +10,13 @@ const modulesEntries = await fg(["packages/server/src/modules/**/*.ts"], { }); export default defineConfig({ entry: ["packages/server/src/booststap.ts", ...jobsEntries, ...modulesEntries], format: "esm", + treeshake: true, sourcemap: false, clean: false, cjsInterop: true, + define: { + "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV), + }, external: [ ...Object.keys(pkg.dependencies), ...Object.keys(spkg.dependencies),