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.
@@ -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
- onAfterStartServer
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.0",
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
- "dev": "wildpig dev",
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
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
- import { packageApiRoutes } from "../src/ApiRoutes";
3
2
  import { build as viteBuild } from "vite";
3
+ import { packageApiRoutes } from "../src/ApiRoutes";
4
4
  import { IBuildOptions } from "../src/types";
5
5
  import chalk from "chalk";
6
6
 
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("../../../src/index.ts"!);
33
+ await import(("../../../" + initEntry)!);
34
+ console.log(chalk.green("初始化代码执行成功:", initEntry));
20
35
  }catch(e){
21
- console.warn("未执行初始化代码,请检查文件是否存在:src/index.ts")
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("../../../src/index.ts"!);
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();
@@ -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 "../router/types";
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"!)).routes as WildPigRouteObject[] : (await import("../router")).routes;
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('../entry/server')
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 (options?: ICreateServerOptions) {
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 " + (options?.port || 3000)));
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:${options?.port || 3000}`));
118
+ console.log(chalk.green(`🔗 Click to debug in Browser: http://localhost:${config?.server?.port || 3000}`));
117
119
  }
118
120
 
119
- async createServer (options?: ICreateServerOptions) {
120
- const apiModules = await getApiRouteModules(env.NODE_ENV === "development" ? "dev" : "prod") as any;
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: options?.port || 3000,
123
- hostname: options?.host || "0.0.0.0",
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(options);
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 { routes } from "../router";
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 { routes } from "../router";
3
+ import routes from "../router";
4
4
 
5
- // 这个文件由Vite加载
6
- const { App } = await import("../../../src/App"!);
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
- let afterStartServerCallbacks: ((server: Server<undefined>) => void)[] = [];
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
- afterStartServerCallbacks.push(cb);
12
+ getCallbacks().push(cb);
8
13
  }
9
14
 
10
15
  export const handleAfterStartServer = async (server: Server<undefined>) => {
11
- for (const cb of afterStartServerCallbacks) {
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 { routes } from ".";
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(routes, pathname);
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,4 @@
1
+ import { WildPigRouteObject } from "./types";
2
+
3
+ // 用户代码(会在index.js中被引入)
4
+ export const pageRoutes: WildPigRouteObject[] = (await import("../../../../src/router/routes"!)).default;
@@ -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