vite-elysia-forge 0.0.7 → 0.0.9
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/README.md +131 -61
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,43 +1,40 @@
|
|
|
1
1
|
# vite-elysia-forge
|
|
2
2
|
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<!-- Vite symbol -->
|
|
13
|
-
<polygon points="50,20 70,60 50,100 30,60" fill="url(#viteGradient)" />
|
|
14
|
-
|
|
15
|
-
<!-- Arrow connecting to Elysia -->
|
|
16
|
-
<line x1="80" y1="60" x2="120" y2="60" stroke="#646cff" stroke-width="3" marker-end="url(#arrowhead)" />
|
|
17
|
-
<defs>
|
|
18
|
-
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
19
|
-
<polygon points="0 0, 10 3, 0 6" fill="#646cff" />
|
|
20
|
-
</marker>
|
|
21
|
-
</defs>
|
|
22
|
-
|
|
23
|
-
<!-- Elysia symbol (simplified) -->
|
|
24
|
-
<circle cx="150" cy="30" r="15" fill="#e0db55" />
|
|
25
|
-
<circle cx="150" cy="90" r="15" fill="#e0db55" />
|
|
26
|
-
<rect x="135" y="50" width="30" height="20" fill="#e0db55" />
|
|
27
|
-
</svg>
|
|
28
|
-
|
|
29
|
-
Vite middleware plugin that hot-reloads an Elysia API module and forwards `/api` requests to it during local development.
|
|
30
|
-
|
|
31
|
-
## Installation
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://vitejs.dev/logo.svg" alt="Vite" width="60" height="60" />
|
|
5
|
+
<img src="https://elysiajs.com/assets/elysia.svg" alt="Elysia" width="60" height="60" />
|
|
6
|
+
<img src="https://bun.sh/logo.svg" alt="Bun" width="60" height="60" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
A [Vite](https://vite.dev/) middleware plugin that hot-reloads an [Elysia](https://elysiajs.com/) API module and forwards `/api` requests to it during local development. Powered by [Bun](https://bun.sh/).
|
|
10
|
+
|
|
11
|
+
## 1. Installation
|
|
32
12
|
|
|
33
13
|
```bash
|
|
34
|
-
bun install
|
|
14
|
+
bun install vite-elysia-forge
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 2. Quick Start
|
|
18
|
+
|
|
19
|
+
### 2.1 Create Your API Handler
|
|
20
|
+
|
|
21
|
+
Place your Elysia handler at `src/server/api.ts` (default path):
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { Elysia } from "elysia";
|
|
25
|
+
|
|
26
|
+
export const api = new Elysia({
|
|
27
|
+
prefix: "/api",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
api.get("/", () => "hello from elysia");
|
|
31
|
+
|
|
32
|
+
export default api;
|
|
35
33
|
```
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
### 2.2 Configure Vite
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
2. In your Vite config, register the plugin:
|
|
37
|
+
Register the plugin in your Vite config:
|
|
41
38
|
|
|
42
39
|
```ts
|
|
43
40
|
import { defineConfig } from "vite";
|
|
@@ -46,85 +43,158 @@ import elysiaPlugin from "vite-elysia-forge";
|
|
|
46
43
|
export default defineConfig({
|
|
47
44
|
plugins: [
|
|
48
45
|
elysiaPlugin({
|
|
49
|
-
serverFile: "/server/api.ts",
|
|
46
|
+
serverFile: "./src/server/api.ts",
|
|
50
47
|
}),
|
|
51
48
|
],
|
|
52
49
|
});
|
|
53
50
|
```
|
|
54
51
|
|
|
55
|
-
|
|
52
|
+
### 2.3 Start Development
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
To build and start the app:
|
|
54
|
+
Run Vite as usual and access your API at `/api/*` routes. The plugin will automatically reload the Elysia module when files change.
|
|
60
55
|
|
|
61
56
|
```bash
|
|
62
|
-
bun run
|
|
63
|
-
bun start
|
|
57
|
+
bun run dev
|
|
64
58
|
```
|
|
65
59
|
|
|
66
|
-
|
|
60
|
+
## 3. Configuration Options
|
|
61
|
+
|
|
62
|
+
### 3.1 Plugin Options
|
|
67
63
|
|
|
68
|
-
|
|
64
|
+
```ts
|
|
65
|
+
elysiaPlugin({
|
|
66
|
+
// Path to your Elysia API module (relative to project root)
|
|
67
|
+
serverFile?: string; // default: "/server/api.ts"
|
|
68
|
+
})
|
|
69
|
+
```
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
| ------------ | ------ | ------------ | ------------------------------------------------------- |
|
|
72
|
-
| `serverURL` | string | `"/server/"` | URL prefix to your API module (leading slash required). |
|
|
73
|
-
| `serverFile` | string | `"api.ts"` | Filename of the Elysia module to load and hot-reload. |
|
|
71
|
+
## 4. API Module Requirements
|
|
74
72
|
|
|
75
|
-
|
|
73
|
+
Your API module must export an Elysia instance with a `handle(request: Request) => Promise<Response>` method.
|
|
76
74
|
|
|
77
|
-
|
|
75
|
+
### 4.1 Basic Example
|
|
78
76
|
|
|
79
77
|
```ts
|
|
78
|
+
import { Elysia } from "elysia";
|
|
79
|
+
|
|
80
80
|
export const api = new Elysia({
|
|
81
81
|
prefix: "/api",
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
api.get("/", () => "hello from elysia");
|
|
85
|
+
api.get("/users", () => ["user1", "user2"]);
|
|
85
86
|
|
|
86
87
|
export default api;
|
|
87
88
|
```
|
|
88
89
|
|
|
89
|
-
##
|
|
90
|
+
## 5. Integration with @elysiajs/openapi
|
|
90
91
|
|
|
91
|
-
|
|
92
|
+
To use the [@elysiajs/openapi plugin](https://elysiajs.com/patterns/openapi), add the following to your `tsconfig.json`:
|
|
92
93
|
|
|
93
|
-
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"compilerOptions": {
|
|
97
|
+
"types": ["bun-types"],
|
|
98
|
+
"typeRoots": ["node_modules"]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 5.1 Example with `fromTypes`
|
|
104
|
+
|
|
105
|
+
It is recommended to pre-generate the declaration file (`.d.ts`) to provide type declaration to the generator.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { Elysia, t } from "elysia";
|
|
109
|
+
import { openapi, fromTypes } from "@elysiajs/openapi";
|
|
110
|
+
|
|
111
|
+
const app = new Elysia().use(
|
|
112
|
+
openapi({
|
|
113
|
+
references: fromTypes("server/api"),
|
|
114
|
+
})
|
|
115
|
+
);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 6. Production Deployment
|
|
119
|
+
|
|
120
|
+
### 6.1 Build Configuration
|
|
121
|
+
|
|
122
|
+
Update your `package.json` scripts:
|
|
94
123
|
|
|
95
124
|
```json
|
|
96
125
|
{
|
|
97
126
|
"scripts": {
|
|
127
|
+
"dev": "vite",
|
|
98
128
|
"build": "vite-elysia-forge build",
|
|
99
129
|
"start": "bun dist/server.js"
|
|
100
130
|
}
|
|
101
131
|
}
|
|
102
132
|
```
|
|
103
133
|
|
|
104
|
-
|
|
134
|
+
If your API is located elsewhere, specify the path:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
vite-elysia-forge build src/my-api.ts
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 6.2 Building for Production
|
|
141
|
+
|
|
142
|
+
Run the build command:
|
|
105
143
|
|
|
106
144
|
```bash
|
|
107
145
|
bun run build
|
|
108
146
|
```
|
|
109
147
|
|
|
110
|
-
This
|
|
148
|
+
This command performs the following steps:
|
|
149
|
+
|
|
150
|
+
1. Runs `vite build` to compile your frontend to `dist/`
|
|
151
|
+
2. Automatically generates a temporary entry file that imports your API from `src/server/api.ts`
|
|
152
|
+
3. Bundles the server into a single file at `dist/server.js`
|
|
111
153
|
|
|
112
|
-
|
|
113
|
-
2. Automatically generate a temporary entry file that imports your API from `src/server/api.ts` (default).
|
|
114
|
-
3. Bundle the server into a single file at `dist/server.js`.
|
|
154
|
+
### 6.3 Starting the Production Server
|
|
115
155
|
|
|
116
|
-
|
|
156
|
+
Start the server with:
|
|
117
157
|
|
|
118
158
|
```bash
|
|
119
|
-
|
|
159
|
+
bun start
|
|
120
160
|
```
|
|
121
161
|
|
|
122
|
-
|
|
162
|
+
## 7. Troubleshooting
|
|
163
|
+
|
|
164
|
+
### 7.1 "Bun is not defined" Error
|
|
165
|
+
|
|
166
|
+
If you encounter this error, ensure you are running Vite with the Bun runtime:
|
|
123
167
|
|
|
124
168
|
```bash
|
|
125
|
-
bun
|
|
169
|
+
bunx --bun vite
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Or update your `dev` script in `package.json`:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
"scripts": {
|
|
176
|
+
"dev": "bunx --bun vite"
|
|
177
|
+
}
|
|
126
178
|
```
|
|
127
179
|
|
|
128
|
-
|
|
180
|
+
**Benefits:**
|
|
181
|
+
|
|
182
|
+
- **Access to Bun APIs:** You can use `Bun.file`, `Bun.env`, `bun:sqlite`, and other native Bun features directly in your server code.
|
|
183
|
+
- **Performance:** Vite often starts faster and uses less memory when running under Bun.
|
|
184
|
+
|
|
185
|
+
**Caveats:**
|
|
186
|
+
|
|
187
|
+
- **Node.js Compatibility:** While Bun has excellent Node.js compatibility, some Vite plugins that rely on obscure Node.js internals might behave unexpectedly.
|
|
188
|
+
- **Performance:** Running Vite under Bun is generally faster, but you might encounter edge cases where optimization differs from Node.js.
|
|
189
|
+
|
|
190
|
+
### 7.2 Hot Reload Not Working
|
|
191
|
+
|
|
192
|
+
Check that your file changes are within the dependency graph of your API module. The plugin uses Vite's dependency tracking to determine when to reload.
|
|
193
|
+
|
|
194
|
+
## 8. Authors
|
|
129
195
|
|
|
130
196
|
- Chijioke Udokporo ([@chijiokeudokporo](https://github.com/chijioke-udokporo))
|
|
197
|
+
|
|
198
|
+
## 9. License
|
|
199
|
+
|
|
200
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var path=require('path');function
|
|
1
|
+
'use strict';var path=require('path');function E({serverFile:g="/server/api.ts"}={}){return {name:"vite-elysia-forge",async configureServer(s){let l=g,y=path.resolve(s.config.root,l.slice(1)),f=async()=>(await s.ssrLoadModule(l)).api,p=await f();s.watcher.add(y),s.watcher.on("change",async e=>{let o=await s.moduleGraph.getModuleByUrl(l);if(!o)return;let i=s.moduleGraph.getModulesByFile(e);if(!i||i.size===0)return;let n=false,r=new Set,a=[...i];for(;a.length>0;){let t=a.shift();if(!(!t||!t.id||r.has(t.id))){if(r.add(t.id),t.id===o.id){n=true;break}for(let c of t.importers)a.push(c);}}if(n)try{s.moduleGraph.invalidateModule(o),p=await f(),console.log("[vite-elysia-forge] Reloaded Elysia API module");}catch(t){console.error(`[vite-elysia-forge] Failed to reload Elysia API: ${t}`);}}),s.middlewares.use(async(e,o,i)=>{if(!e.url?.startsWith("/api"))return i();try{let n="http",r=e.headers.host||"localhost:3000",a=`${n}://${r}${e.url}`,t;if(e.method!=="GET"&&e.method!=="HEAD"){let d=[];for await(let h of e)d.push(h);t=Buffer.concat(d).toString();}let c=new Request(a,{method:e.method,headers:e.headers,body:t}),u=await p.handle(c);o.statusCode=u.status,u.headers.forEach((d,h)=>{o.setHeader(h,d);});let m=await u.text();o.end(m);}catch(n){console.error(`[vite-elysia-forge] Elysia error: ${n}`),o.statusCode=500,o.end("Internal Server Error");}});}}}var P=E;
|
|
2
2
|
module.exports=P;
|
package/dist/index.d.cts
CHANGED
|
@@ -20,6 +20,6 @@ interface ConfigOptions {
|
|
|
20
20
|
* @param options - Configuration options for the plugin.
|
|
21
21
|
* @returns A Vite plugin instance.
|
|
22
22
|
*/
|
|
23
|
-
declare function elysiaPlugin({ serverFile }
|
|
23
|
+
declare function elysiaPlugin({ serverFile }?: ConfigOptions): Plugin;
|
|
24
24
|
|
|
25
25
|
export { type ConfigOptions, elysiaPlugin as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,6 @@ interface ConfigOptions {
|
|
|
20
20
|
* @param options - Configuration options for the plugin.
|
|
21
21
|
* @returns A Vite plugin instance.
|
|
22
22
|
*/
|
|
23
|
-
declare function elysiaPlugin({ serverFile }
|
|
23
|
+
declare function elysiaPlugin({ serverFile }?: ConfigOptions): Plugin;
|
|
24
24
|
|
|
25
25
|
export { type ConfigOptions, elysiaPlugin as default };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {resolve}from'path';function
|
|
1
|
+
import {resolve}from'path';function E({serverFile:g="/server/api.ts"}={}){return {name:"vite-elysia-forge",async configureServer(s){let l=g,y=resolve(s.config.root,l.slice(1)),f=async()=>(await s.ssrLoadModule(l)).api,p=await f();s.watcher.add(y),s.watcher.on("change",async e=>{let o=await s.moduleGraph.getModuleByUrl(l);if(!o)return;let i=s.moduleGraph.getModulesByFile(e);if(!i||i.size===0)return;let n=false,r=new Set,a=[...i];for(;a.length>0;){let t=a.shift();if(!(!t||!t.id||r.has(t.id))){if(r.add(t.id),t.id===o.id){n=true;break}for(let c of t.importers)a.push(c);}}if(n)try{s.moduleGraph.invalidateModule(o),p=await f(),console.log("[vite-elysia-forge] Reloaded Elysia API module");}catch(t){console.error(`[vite-elysia-forge] Failed to reload Elysia API: ${t}`);}}),s.middlewares.use(async(e,o,i)=>{if(!e.url?.startsWith("/api"))return i();try{let n="http",r=e.headers.host||"localhost:3000",a=`${n}://${r}${e.url}`,t;if(e.method!=="GET"&&e.method!=="HEAD"){let d=[];for await(let h of e)d.push(h);t=Buffer.concat(d).toString();}let c=new Request(a,{method:e.method,headers:e.headers,body:t}),u=await p.handle(c);o.statusCode=u.status,u.headers.forEach((d,h)=>{o.setHeader(h,d);});let m=await u.text();o.end(m);}catch(n){console.error(`[vite-elysia-forge] Elysia error: ${n}`),o.statusCode=500,o.end("Internal Server Error");}});}}}var P=E;
|
|
2
2
|
export{P as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-elysia-forge",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "A Vite plugin to seamlessly integrate ElysiaJS for full-stack development with Bun runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"author": "chijioke-udokporo",
|
|
14
14
|
"private": false,
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "bun run test && tsup",
|
|
16
|
+
"build": "rm -rf dist &&bun run test && tsup",
|
|
17
17
|
"test": "bun test"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {},
|