wildpig 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/built-api-routes.ts +0 -22
- package/index.html +1 -1
- package/index.ts +15 -2
- package/package.json +2 -4
- package/scripts/build.ts +1 -1
- package/scripts/dev.ts +18 -3
- package/scripts/prod.ts +17 -1
- package/src/WildpigServer.ts +15 -12
- package/src/config.ts +22 -0
- package/{entry → src/entry}/client.tsx +1 -2
- package/{entry → src/entry}/server.tsx +3 -3
- package/src/hooks/afterStartServer.ts +10 -5
- package/{router → src/router}/ServerDataGuard.tsx +2 -2
- package/{router → src/router}/index.ts +2 -5
- package/src/router/pageRoutes.ts +4 -0
- package/src/utils/server/globalMap.ts +30 -0
- /package/{router → src/router}/types.ts +0 -0
- /package/{store → src/store}/serverDataStore.tsx +0 -0
- /package/{utils → src/utils}/client/environment.ts +0 -0
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { middleware } from "@/api/middleware"
|
|
2
|
-
import {
|
|
3
|
-
GET as GET1,
|
|
4
|
-
} from "#/src/api/hello/index";
|
|
5
|
-
import {
|
|
6
|
-
GET as GET2,
|
|
7
|
-
} from "#/src/api/server-data/home/index";
|
|
8
|
-
import {
|
|
9
|
-
GET as GET3,
|
|
10
|
-
} from "#/src/api/server-data/post/index";
|
|
11
|
-
|
|
12
|
-
export default {
|
|
13
|
-
"/api/hello": {
|
|
14
|
-
GET: (req: any) => middleware(req, GET1),
|
|
15
|
-
},
|
|
16
|
-
"/api/server-data/home": {
|
|
17
|
-
GET: (req: any) => middleware(req, GET2),
|
|
18
|
-
},
|
|
19
|
-
"/api/server-data/post": {
|
|
20
|
-
GET: (req: any) => middleware(req, GET3),
|
|
21
|
-
},
|
|
22
|
-
}
|
package/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title><!--title--></title>
|
|
7
|
-
<script type="module" src="/node_modules/wildpig/entry/client.tsx"></script>
|
|
7
|
+
<script type="module" src="/node_modules/wildpig/src/entry/client.tsx"></script>
|
|
8
8
|
<!--server-data-->
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/index.ts
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
|
|
2
2
|
import { onAfterStartServer } from "./src/hooks/afterStartServer";
|
|
3
|
-
|
|
3
|
+
import { defineConfig } from "./src/config";
|
|
4
|
+
import { serverDataStore } from "./src/store/serverDataStore";
|
|
5
|
+
import { ServerDataGuard } from "./src/router/ServerDataGuard";
|
|
6
|
+
import type { WildPigRouteObject } from "./src/router/types";
|
|
4
7
|
|
|
5
8
|
export {
|
|
6
|
-
|
|
9
|
+
// config
|
|
10
|
+
defineConfig,
|
|
11
|
+
|
|
12
|
+
// hook
|
|
13
|
+
onAfterStartServer,
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
// router
|
|
17
|
+
serverDataStore,
|
|
18
|
+
ServerDataGuard,
|
|
19
|
+
WildPigRouteObject
|
|
7
20
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wildpig",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"author": "eriktse",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"peerDependencies": {
|
|
@@ -25,9 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"scripts": {
|
|
28
|
-
"
|
|
29
|
-
"build": "wildpig build",
|
|
30
|
-
"start": "wildpig start",
|
|
28
|
+
"build": "bun run build.ts",
|
|
31
29
|
"local-publish": "yalc publish"
|
|
32
30
|
}
|
|
33
31
|
}
|
package/scripts/build.ts
CHANGED
package/scripts/dev.ts
CHANGED
|
@@ -2,23 +2,38 @@ import { createServer as createViteServer } from "vite";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { WildpigServer } from "../src/WildpigServer";
|
|
4
4
|
import chalk from "chalk";
|
|
5
|
+
import { IWildpigConfig, setWildpigConfig } from "../src/config";
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
const __dirname = import.meta.dirname;
|
|
8
9
|
const __rootdir = path.resolve(__dirname, "../../../");
|
|
9
10
|
|
|
11
|
+
|
|
12
|
+
|
|
10
13
|
// 启动vite server
|
|
11
14
|
const viteServer = await createViteServer({
|
|
12
15
|
configFile: path.resolve(__rootdir, "./vite.config.ts"),
|
|
13
16
|
});
|
|
14
17
|
await viteServer.listen(viteServer.config.server.port);
|
|
15
|
-
console.log(chalk.green(`Vite server running at port ${viteServer.config.server.port}`));
|
|
16
18
|
|
|
17
19
|
|
|
20
|
+
|
|
21
|
+
// 加载配置文件
|
|
22
|
+
let config: IWildpigConfig | undefined;
|
|
23
|
+
try{
|
|
24
|
+
config = (await import("../../../wildpig.config.ts"!)).default;
|
|
25
|
+
if(config)setWildpigConfig(config);
|
|
26
|
+
}catch(e){
|
|
27
|
+
console.error("获取wildpig.config.ts配置文件失败,请检查!", e);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 运行初始化代码
|
|
31
|
+
const initEntry = config?.initEntry || "src/index.ts";
|
|
18
32
|
try{
|
|
19
|
-
await import("../../../
|
|
33
|
+
await import(("../../../" + initEntry)!);
|
|
34
|
+
console.log(chalk.green("初始化代码执行成功:", initEntry));
|
|
20
35
|
}catch(e){
|
|
21
|
-
console.warn("未执行初始化代码,请检查文件是否存在:
|
|
36
|
+
console.warn("未执行初始化代码,请检查文件是否存在:" + initEntry)
|
|
22
37
|
}
|
|
23
38
|
|
|
24
39
|
const wildpigServer = new WildpigServer(viteServer);
|
package/scripts/prod.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
import { WildpigServer } from "../src/WildpigServer";
|
|
2
|
+
import { IWildpigConfig, setWildpigConfig } from "../src/config";
|
|
2
3
|
|
|
4
|
+
// 加载配置文件
|
|
5
|
+
let config: IWildpigConfig | undefined;
|
|
3
6
|
try{
|
|
4
|
-
await import("../../../
|
|
7
|
+
config = (await import("../../../wildpig.config.ts"!)).default;
|
|
8
|
+
if(config)setWildpigConfig(config);
|
|
5
9
|
}catch(e){
|
|
10
|
+
console.error("获取wildpig.config.ts配置文件失败,请检查!");
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
|
|
14
|
+
// 运行初始化代码
|
|
15
|
+
const initEntry = config?.initEntry || "src/index.ts";
|
|
16
|
+
try{
|
|
17
|
+
const initPath = `"../../../${initEntry}`.replace(".ts", "");
|
|
18
|
+
await import(initPath);
|
|
19
|
+
}catch(e){
|
|
20
|
+
console.warn("未执行初始化代码,请检查文件是否存在:" + initEntry);
|
|
7
21
|
}
|
|
8
22
|
|
|
23
|
+
|
|
24
|
+
|
|
9
25
|
const wildpigServer = new WildpigServer();
|
|
10
26
|
await wildpigServer.createServer();
|
package/src/WildpigServer.ts
CHANGED
|
@@ -2,17 +2,18 @@ import { getApiRouteModules } from "./ApiRoutes";
|
|
|
2
2
|
import { type ViteDevServer} from "vite";
|
|
3
3
|
import { matchRoutes } from "react-router";
|
|
4
4
|
import fs from "node:fs";
|
|
5
|
-
import { WildPigRouteObject } from "
|
|
5
|
+
import { WildPigRouteObject } from "./router/types";
|
|
6
6
|
import packageInfo from "../package.json";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import chalk from "chalk";
|
|
9
9
|
|
|
10
10
|
const __dirname = import.meta.dirname;
|
|
11
|
-
import { ICreateServerOptions } from "./types";
|
|
12
11
|
import { handleAfterStartServer } from "./hooks/afterStartServer";
|
|
12
|
+
import { getWildpigConfig } from "./config";
|
|
13
13
|
|
|
14
14
|
const env = process.env;
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
export class WildpigServer {
|
|
17
18
|
private viteServer: ViteDevServer | undefined;
|
|
18
19
|
constructor(viteServer?: ViteDevServer | undefined){
|
|
@@ -50,7 +51,7 @@ export class WildpigServer {
|
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
// 服务端请求,获取服务端数据
|
|
53
|
-
const routes = this.viteServer ? (await this.viteServer.ssrLoadModule("/node_modules/wildpig/router/index.ts"!)).
|
|
54
|
+
const routes = this.viteServer ? (await this.viteServer.ssrLoadModule("/node_modules/wildpig/src/router/index.ts"!)).default as WildPigRouteObject[] : (await import("./router/index")).default;
|
|
54
55
|
const matches = matchRoutes(routes, url.pathname);
|
|
55
56
|
if(!matches)return new Response("404 Not Found", { status: 404 });
|
|
56
57
|
|
|
@@ -85,7 +86,7 @@ export class WildpigServer {
|
|
|
85
86
|
// 1. 读取 index.html
|
|
86
87
|
const template = this.viteServer ? await this.viteServer.transformIndexHtml(request.url, fs.readFileSync('./index.html', 'utf-8')) : fs.readFileSync(path.resolve(__dirname, './client/index.html'), 'utf-8');
|
|
87
88
|
// 2. 获取渲染函数
|
|
88
|
-
const { render } = this.viteServer ? await this.viteServer.ssrLoadModule("/node_modules/wildpig/entry/server.tsx") : await import('
|
|
89
|
+
const { render } = this.viteServer ? await this.viteServer.ssrLoadModule("/node_modules/wildpig/src/entry/server.tsx") : await import('./entry/server')
|
|
89
90
|
// 3. 获取应用程序 HTML
|
|
90
91
|
const appHtml = await render(request, serverData);
|
|
91
92
|
|
|
@@ -106,28 +107,30 @@ export class WildpigServer {
|
|
|
106
107
|
|
|
107
108
|
|
|
108
109
|
/** 启动后的描述性文字 */
|
|
109
|
-
async afterStart (
|
|
110
|
+
async afterStart () {
|
|
111
|
+
const config = getWildpigConfig();
|
|
110
112
|
// 启动后的文字
|
|
111
113
|
console.log(chalk.blue.bgGreen(` 🐗 WildPig version ${packageInfo?.version} by ${packageInfo?.author} `));
|
|
112
114
|
console.log(chalk.green(" Strong & Fast Fullstack Framework\n"));
|
|
113
|
-
console.log(chalk.green("✨ WildPig is running on port " + (
|
|
115
|
+
console.log(chalk.green("✨ WildPig is running on port " + (config?.server?.port || 3000)));
|
|
114
116
|
console.log(chalk.yellow(`💻 Wildpig is Running in ${chalk.yellow.bold(env.NODE_ENV)} mode.`));
|
|
115
117
|
if(this.viteServer)console.log(chalk.green("⚡ Vite server is running on port " + this.viteServer.config.server?.port));
|
|
116
|
-
console.log(chalk.green(`🔗 Click to debug in Browser: http://localhost:${
|
|
118
|
+
console.log(chalk.green(`🔗 Click to debug in Browser: http://localhost:${config?.server?.port || 3000}`));
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
async createServer (
|
|
120
|
-
const
|
|
121
|
+
async createServer () {
|
|
122
|
+
const config = getWildpigConfig();
|
|
123
|
+
const apiModules = await getApiRouteModules(env.NODE_ENV === "development" ? "dev" : "prod");
|
|
121
124
|
const server = Bun.serve({
|
|
122
|
-
port:
|
|
123
|
-
hostname:
|
|
125
|
+
port: config?.server?.port || 3000,
|
|
126
|
+
hostname: config?.server?.host || "0.0.0.0",
|
|
124
127
|
routes:{
|
|
125
128
|
...apiModules,
|
|
126
129
|
"/*": await this.frontHandler(apiModules),
|
|
127
130
|
},
|
|
128
131
|
development: env.NODE_ENV === "development",
|
|
129
132
|
})
|
|
130
|
-
await this.afterStart(
|
|
133
|
+
await this.afterStart();
|
|
131
134
|
// 服务器创建好了, 触发afterStartServer回调
|
|
132
135
|
await handleAfterStartServer(server);
|
|
133
136
|
return server;
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { wildpigGlobalMap } from "./utils/server/globalMap";
|
|
2
|
+
|
|
3
|
+
export interface IWildpigConfig {
|
|
4
|
+
server?: {
|
|
5
|
+
host?: string,
|
|
6
|
+
port?: number | string,
|
|
7
|
+
},
|
|
8
|
+
/**
|
|
9
|
+
* 入口文件,默认为src/index.ts,用户可以在这里编写一些自定义的初始化代码
|
|
10
|
+
*/
|
|
11
|
+
initEntry?: string,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
export const defineConfig = (config: IWildpigConfig) => config;
|
|
17
|
+
|
|
18
|
+
export const getWildpigConfig = () => wildpigGlobalMap.getItem("__wildpigConfig") as IWildpigConfig | undefined;
|
|
19
|
+
|
|
20
|
+
export const setWildpigConfig = (_config: IWildpigConfig) => {
|
|
21
|
+
wildpigGlobalMap.setItem("__wildpigConfig", _config);
|
|
22
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { createBrowserRouter } from "react-router";
|
|
2
|
-
import
|
|
2
|
+
import routes from "../router";
|
|
3
3
|
import { hydrateRoot } from "react-dom/client"
|
|
4
4
|
// 这个文件由Vite加载
|
|
5
5
|
const { App } = await import('/src/App'!);
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
const render = () => {
|
|
9
8
|
// 获取serverData
|
|
10
9
|
const serverData = (window as any).__SERVER_DATA__ || undefined;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { renderToString } from "react-dom/server"
|
|
2
2
|
import { createStaticHandler, createStaticRouter } from "react-router"
|
|
3
|
-
import
|
|
3
|
+
import routes from "../router";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
const { App } = await import("
|
|
5
|
+
|
|
6
|
+
const { App } = await import("../../../../src/App"!);
|
|
7
7
|
|
|
8
8
|
export const render = async (req: Request, serverData?: any): Promise<string> => {
|
|
9
9
|
// 1. 创建处理器
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { Server } from "bun";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { wildpigGlobalMap } from "../utils/server/globalMap";
|
|
3
|
+
// 初始化或获取全局回调数组
|
|
4
|
+
const getCallbacks = () => {
|
|
5
|
+
if (!wildpigGlobalMap.getItem("__wildpigAfterStartServerCallbacks")) {
|
|
6
|
+
wildpigGlobalMap.setItem("__wildpigAfterStartServerCallbacks", []);
|
|
7
|
+
}
|
|
8
|
+
return wildpigGlobalMap.getItem("__wildpigAfterStartServerCallbacks") as ((server: Server<undefined>) => void)[];
|
|
9
|
+
};
|
|
5
10
|
|
|
6
11
|
export const onAfterStartServer = async (cb: (server: Server<undefined>) => void) => {
|
|
7
|
-
|
|
12
|
+
getCallbacks().push(cb);
|
|
8
13
|
}
|
|
9
14
|
|
|
10
15
|
export const handleAfterStartServer = async (server: Server<undefined>) => {
|
|
11
|
-
for (const cb of
|
|
16
|
+
for (const cb of getCallbacks()) {
|
|
12
17
|
cb(server);
|
|
13
18
|
}
|
|
14
19
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect } from "react"
|
|
2
2
|
import { matchRoutes, Outlet, useLocation, useNavigate } from "react-router"
|
|
3
3
|
import { serverDataStore } from "../store/serverDataStore";
|
|
4
|
-
import {
|
|
4
|
+
import { pageRoutes } from "./pageRoutes";
|
|
5
5
|
|
|
6
6
|
export const ServerDataGuard = () => {
|
|
7
7
|
const location = useLocation();
|
|
@@ -11,7 +11,7 @@ export const ServerDataGuard = () => {
|
|
|
11
11
|
serverDataStore.set(undefined);
|
|
12
12
|
|
|
13
13
|
const pathname = location.pathname;
|
|
14
|
-
const matches = matchRoutes(
|
|
14
|
+
const matches = matchRoutes(pageRoutes, pathname);
|
|
15
15
|
const lastMatch = matches?.at(-1);
|
|
16
16
|
if(!lastMatch) {
|
|
17
17
|
// 404
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
+
import { pageRoutes } from "./pageRoutes";
|
|
1
2
|
import { ServerDataGuard } from "./ServerDataGuard";
|
|
2
3
|
import { WildPigRouteObject } from "./types";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
let pageRoutes: WildPigRouteObject[] = (await import("../../../src/router/routes"!)).default;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export const routes = [
|
|
5
|
+
export default [
|
|
9
6
|
{
|
|
10
7
|
path: "/",
|
|
11
8
|
Component: ServerDataGuard,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// 全局注册器
|
|
2
|
+
declare global {
|
|
3
|
+
var __wildpigGlobalMap: Map<string, any>;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const getWildpigGlobalMap = () => {
|
|
7
|
+
if (!globalThis.__wildpigGlobalMap) {
|
|
8
|
+
globalThis.__wildpigGlobalMap = new Map();
|
|
9
|
+
}
|
|
10
|
+
return globalThis.__wildpigGlobalMap;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const getItem = <T>(key: string): T | undefined => {
|
|
14
|
+
if (!getWildpigGlobalMap().has(key)) return undefined;
|
|
15
|
+
return getWildpigGlobalMap().get(key) as T;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const setItem = <T>(key: string, value: T) => {
|
|
19
|
+
getWildpigGlobalMap().set(key, value);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const getAll = () => {
|
|
23
|
+
return getWildpigGlobalMap();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const wildpigGlobalMap = {
|
|
27
|
+
getItem,
|
|
28
|
+
setItem,
|
|
29
|
+
getAll
|
|
30
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|