@hono/vite-build 1.0.0
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 +221 -0
- package/dist/adapter/bun/index.d.ts +10 -0
- package/dist/adapter/bun/index.js +26 -0
- package/dist/adapter/cloudflare-pages/index.d.ts +8 -0
- package/dist/adapter/cloudflare-pages/index.js +53 -0
- package/dist/adapter/cloudflare-workers/index.d.ts +8 -0
- package/dist/adapter/cloudflare-workers/index.js +13 -0
- package/dist/adapter/node/index.d.ts +10 -0
- package/dist/adapter/node/index.js +33 -0
- package/dist/base.d.ts +25 -0
- package/dist/base.js +100 -0
- package/dist/entry/index.d.ts +13 -0
- package/dist/entry/index.js +53 -0
- package/dist/entry/serve-static.d.ts +7 -0
- package/dist/entry/serve-static.js +11 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +7 -0
- package/package.json +85 -0
package/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# @hono/vite-build
|
|
2
|
+
|
|
3
|
+
`@hono/vite-build` is a set of Vite plugins for building Hono applications with Vite. It supports multiple runtimes and platforms, allowing you to build a project that includes JavaScript files for these platforms from a Hono app.
|
|
4
|
+
|
|
5
|
+
Here are the modules included:
|
|
6
|
+
|
|
7
|
+
- `@hono/vite-build/base`
|
|
8
|
+
- `@hono/vite-build/cloudflare-pages`
|
|
9
|
+
- `@hono/vite-build/cloudflare-workers`
|
|
10
|
+
- `@hono/vite-build/bun`
|
|
11
|
+
- `@hono/vite-build/node`
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Install
|
|
16
|
+
|
|
17
|
+
You can install `vite` and `@hono/vite-build` via the npm.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i -D vite @hono/vite-build
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or you can install them with Bun.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
bun add -D vite @hono/vite-build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Settings
|
|
30
|
+
|
|
31
|
+
Add `"type": "module"` to your package.json. Then, create `vite.config.ts` and edit it. The following is for Bun.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { defineConfig } from 'vite'
|
|
35
|
+
import build from '@hono/vite-build/bun'
|
|
36
|
+
// import build from '@hono/vite-build/cloudflare-pages'
|
|
37
|
+
// import build from '@hono/vite-build/cloudflare-workers'
|
|
38
|
+
// import build from '@hono/vite-build/node'
|
|
39
|
+
|
|
40
|
+
export default defineConfig({
|
|
41
|
+
plugins: [
|
|
42
|
+
build({
|
|
43
|
+
// Defaults are `src/index.ts`,`./src/index.tsx`,`./app/server.ts`
|
|
44
|
+
entry: './src/index.tsx',
|
|
45
|
+
}),
|
|
46
|
+
],
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Build
|
|
51
|
+
|
|
52
|
+
Just run `vite build`.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm exec vite build
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
bunx --bun vite build
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Run
|
|
65
|
+
|
|
66
|
+
Run with the command on your runtime. For examples:
|
|
67
|
+
|
|
68
|
+
Cloudflare Pages:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
wrangler pages dev ./dist
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Bun:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
cd ./dist
|
|
78
|
+
bun run ./index.js
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Node.js:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
cd ./dist
|
|
85
|
+
node ./index.js
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Common Options
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
type BuildOptions = {
|
|
92
|
+
entry?: string | string[]
|
|
93
|
+
output?: string
|
|
94
|
+
outputDir?: string
|
|
95
|
+
external?: string[]
|
|
96
|
+
minify?: boolean
|
|
97
|
+
emptyOutDir?: boolean
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Default values:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
export const defaultOptions = {
|
|
105
|
+
entry: ['src/index.ts', './src/index.tsx', './app/server.ts'],
|
|
106
|
+
output: 'index.js',
|
|
107
|
+
outputDir: './dist',
|
|
108
|
+
external: [],
|
|
109
|
+
minify: true,
|
|
110
|
+
emptyOutDir: false,
|
|
111
|
+
staticPaths: [],
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Platform specific things
|
|
116
|
+
|
|
117
|
+
### Cloudflare Pages
|
|
118
|
+
|
|
119
|
+
This plugin generates `_routes.json` automatically. The automatic generation can be overridden by creating a `public/_routes.json`. See [Create a `_routes.json` file](https://developers.cloudflare.com/pages/functions/routing/#create-a-_routesjson-file) on Cloudflare Docs for more details.
|
|
120
|
+
|
|
121
|
+
## Example project
|
|
122
|
+
|
|
123
|
+
`src/index.tsx`:
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
import { Hono } from 'hono'
|
|
127
|
+
|
|
128
|
+
const app = new Hono()
|
|
129
|
+
|
|
130
|
+
app.get('/', (c) => {
|
|
131
|
+
return c.html(
|
|
132
|
+
<html>
|
|
133
|
+
<head>
|
|
134
|
+
<link href='/static/style.css' rel='stylesheet' />
|
|
135
|
+
</head>
|
|
136
|
+
<body>
|
|
137
|
+
<h1>Hello!</h1>
|
|
138
|
+
</body>
|
|
139
|
+
</html>
|
|
140
|
+
)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
export default app
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`public/static/style.css`:
|
|
147
|
+
|
|
148
|
+
```css
|
|
149
|
+
h1 {
|
|
150
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The project with those file will be built to the following files with `@hono/vite-build/bun`:
|
|
155
|
+
|
|
156
|
+
```txt
|
|
157
|
+
dist
|
|
158
|
+
├── index.js
|
|
159
|
+
└── static
|
|
160
|
+
└── style.css
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Build a client
|
|
164
|
+
|
|
165
|
+
If you also want to build a client-side script, you can configure it as follows.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
export default defineConfig(({ mode }) => {
|
|
169
|
+
if (mode === 'client') {
|
|
170
|
+
return {
|
|
171
|
+
build: {
|
|
172
|
+
rollupOptions: {
|
|
173
|
+
input: './src/client.ts',
|
|
174
|
+
output: {
|
|
175
|
+
dir: './dist/static',
|
|
176
|
+
entryFileNames: 'client.js',
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
copyPublicDir: false,
|
|
180
|
+
},
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
return {
|
|
184
|
+
plugins: [build()],
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The build command:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
vite build --mode client && vite build
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`import.meta.env.PROD` is helpful in detecting whether it is in development or production mode if you are using it on a Vite dev server.
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
app.get('/', (c) => {
|
|
200
|
+
return c.html(
|
|
201
|
+
<html>
|
|
202
|
+
<head>
|
|
203
|
+
{import.meta.env.PROD ? (
|
|
204
|
+
<script type='module' src='/static/client.js'></script>
|
|
205
|
+
) : (
|
|
206
|
+
<script type='module' src='/src/client.ts'></script>
|
|
207
|
+
)}
|
|
208
|
+
</head>
|
|
209
|
+
<body>Hello!</body>
|
|
210
|
+
</html>
|
|
211
|
+
)
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Authors
|
|
216
|
+
|
|
217
|
+
- Yusuke Wada <https://github.com/yusukebe>
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
MIT
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { BuildOptions } from '../../base.js';
|
|
3
|
+
import '../../entry/index.js';
|
|
4
|
+
|
|
5
|
+
type BunBuildOptions = {
|
|
6
|
+
staticRoot?: string | undefined;
|
|
7
|
+
} & BuildOptions;
|
|
8
|
+
declare const bunBuildPlugin: (pluginOptions?: BunBuildOptions) => Plugin;
|
|
9
|
+
|
|
10
|
+
export { BunBuildOptions, bunBuildPlugin as default };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import buildPlugin from "../../base.js";
|
|
2
|
+
import { serveStaticHook } from "../../entry/serve-static.js";
|
|
3
|
+
const bunBuildPlugin = (pluginOptions) => {
|
|
4
|
+
return {
|
|
5
|
+
...buildPlugin({
|
|
6
|
+
...{
|
|
7
|
+
entryContentBeforeHooks: [
|
|
8
|
+
async (appName, options) => {
|
|
9
|
+
let code = "import { serveStatic } from 'hono/bun'\n";
|
|
10
|
+
code += serveStaticHook(appName, {
|
|
11
|
+
filePaths: options?.staticPaths,
|
|
12
|
+
root: pluginOptions?.staticRoot
|
|
13
|
+
});
|
|
14
|
+
return code;
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
...pluginOptions
|
|
19
|
+
}),
|
|
20
|
+
name: "@hono/vite-build/bun"
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
var bun_default = bunBuildPlugin;
|
|
24
|
+
export {
|
|
25
|
+
bun_default as default
|
|
26
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { BuildOptions } from '../../base.js';
|
|
3
|
+
import '../../entry/index.js';
|
|
4
|
+
|
|
5
|
+
type CloudflarePagesBuildOptions = BuildOptions;
|
|
6
|
+
declare const cloudflarePagesBuildPlugin: (pluginOptions?: CloudflarePagesBuildOptions) => Plugin;
|
|
7
|
+
|
|
8
|
+
export { CloudflarePagesBuildOptions, cloudflarePagesBuildPlugin as default };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { readdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import buildPlugin, { defaultOptions } from "../../base.js";
|
|
4
|
+
const WORKER_JS_NAME = "_worker.js";
|
|
5
|
+
const ROUTES_JSON_NAME = "_routes.json";
|
|
6
|
+
const cloudflarePagesBuildPlugin = (pluginOptions) => {
|
|
7
|
+
let config;
|
|
8
|
+
const staticPaths = [];
|
|
9
|
+
return {
|
|
10
|
+
...buildPlugin({
|
|
11
|
+
...pluginOptions,
|
|
12
|
+
output: WORKER_JS_NAME
|
|
13
|
+
}),
|
|
14
|
+
configResolved: async (resolvedConfig) => {
|
|
15
|
+
config = resolvedConfig;
|
|
16
|
+
},
|
|
17
|
+
writeBundle: async () => {
|
|
18
|
+
const paths = await readdir(resolve(config.root, config.build.outDir), {
|
|
19
|
+
withFileTypes: true
|
|
20
|
+
});
|
|
21
|
+
if (paths.some((p) => p.name === ROUTES_JSON_NAME)) {
|
|
22
|
+
return;
|
|
23
|
+
} else {
|
|
24
|
+
paths.forEach((p) => {
|
|
25
|
+
if (p.isDirectory()) {
|
|
26
|
+
staticPaths.push(`/${p.name}/*`);
|
|
27
|
+
} else {
|
|
28
|
+
if (p.name === WORKER_JS_NAME) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
staticPaths.push(`/${p.name}`);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const staticRoutes = {
|
|
35
|
+
version: 1,
|
|
36
|
+
include: ["/*"],
|
|
37
|
+
exclude: staticPaths
|
|
38
|
+
};
|
|
39
|
+
const path = resolve(
|
|
40
|
+
config.root,
|
|
41
|
+
pluginOptions?.outputDir ?? defaultOptions.outputDir,
|
|
42
|
+
"_routes.json"
|
|
43
|
+
);
|
|
44
|
+
await writeFile(path, JSON.stringify(staticRoutes));
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
name: "@hono/vite-build/cloudflare-pages"
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
var cloudflare_pages_default = cloudflarePagesBuildPlugin;
|
|
51
|
+
export {
|
|
52
|
+
cloudflare_pages_default as default
|
|
53
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { BuildOptions } from '../../base.js';
|
|
3
|
+
import '../../entry/index.js';
|
|
4
|
+
|
|
5
|
+
type CloudflareWorkersBuildOptions = BuildOptions;
|
|
6
|
+
declare const cloudflareWorkersBuildPlugin: (pluginOptions?: CloudflareWorkersBuildOptions) => Plugin;
|
|
7
|
+
|
|
8
|
+
export { CloudflareWorkersBuildOptions, cloudflareWorkersBuildPlugin as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import buildPlugin from "../../base.js";
|
|
2
|
+
const cloudflareWorkersBuildPlugin = (pluginOptions) => {
|
|
3
|
+
return {
|
|
4
|
+
...buildPlugin({
|
|
5
|
+
...pluginOptions
|
|
6
|
+
}),
|
|
7
|
+
name: "@hono/vite-build/cloudflare-workers"
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
var cloudflare_workers_default = cloudflareWorkersBuildPlugin;
|
|
11
|
+
export {
|
|
12
|
+
cloudflare_workers_default as default
|
|
13
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { BuildOptions } from '../../base.js';
|
|
3
|
+
import '../../entry/index.js';
|
|
4
|
+
|
|
5
|
+
type NodeBuildOptions = {
|
|
6
|
+
staticRoot?: string | undefined;
|
|
7
|
+
} & BuildOptions;
|
|
8
|
+
declare const nodeBuildPlugin: (pluginOptions?: NodeBuildOptions) => Plugin;
|
|
9
|
+
|
|
10
|
+
export { NodeBuildOptions, nodeBuildPlugin as default };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import buildPlugin from "../../base.js";
|
|
2
|
+
import { serveStaticHook } from "../../entry/serve-static.js";
|
|
3
|
+
const nodeBuildPlugin = (pluginOptions) => {
|
|
4
|
+
return {
|
|
5
|
+
...buildPlugin({
|
|
6
|
+
...{
|
|
7
|
+
entryContentBeforeHooks: [
|
|
8
|
+
async (appName, options) => {
|
|
9
|
+
let code = "import { serveStatic } from '@hono/node-server/serve-static'\n";
|
|
10
|
+
code += serveStaticHook(appName, {
|
|
11
|
+
filePaths: options?.staticPaths,
|
|
12
|
+
root: pluginOptions?.staticRoot
|
|
13
|
+
});
|
|
14
|
+
return code;
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
entryContentAfterHooks: [
|
|
18
|
+
async (appName) => {
|
|
19
|
+
let code = "import { serve } from '@hono/node-server'\n";
|
|
20
|
+
code += `serve(${appName})`;
|
|
21
|
+
return code;
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
...pluginOptions
|
|
26
|
+
}),
|
|
27
|
+
name: "@hono/vite-build/node"
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
var node_default = nodeBuildPlugin;
|
|
31
|
+
export {
|
|
32
|
+
node_default as default
|
|
33
|
+
};
|
package/dist/base.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { UserConfig, ConfigEnv, Plugin } from 'vite';
|
|
2
|
+
import { GetEntryContentOptions } from './entry/index.js';
|
|
3
|
+
|
|
4
|
+
type BuildOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* @default ['src/index.ts', './src/index.tsx', './app/server.ts']
|
|
7
|
+
*/
|
|
8
|
+
entry?: string | string[];
|
|
9
|
+
/**
|
|
10
|
+
* @default './dist'
|
|
11
|
+
*/
|
|
12
|
+
output?: string;
|
|
13
|
+
outputDir?: string;
|
|
14
|
+
external?: string[];
|
|
15
|
+
/**
|
|
16
|
+
* @default true
|
|
17
|
+
*/
|
|
18
|
+
minify?: boolean;
|
|
19
|
+
emptyOutDir?: boolean;
|
|
20
|
+
apply?: ((this: void, config: UserConfig, env: ConfigEnv) => boolean) | undefined;
|
|
21
|
+
} & Omit<GetEntryContentOptions, 'entry'>;
|
|
22
|
+
declare const defaultOptions: Required<Omit<BuildOptions, 'entryContentAfterHooks' | 'entryContentBeforeHooks'>>;
|
|
23
|
+
declare const buildPlugin: (options: BuildOptions) => Plugin;
|
|
24
|
+
|
|
25
|
+
export { BuildOptions, buildPlugin as default, defaultOptions };
|
package/dist/base.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { builtinModules } from "module";
|
|
2
|
+
import { readdirSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { getEntryContent } from "./entry/index.js";
|
|
5
|
+
const defaultOptions = {
|
|
6
|
+
entry: ["src/index.ts", "./src/index.tsx", "./app/server.ts"],
|
|
7
|
+
output: "index.js",
|
|
8
|
+
outputDir: "./dist",
|
|
9
|
+
external: [],
|
|
10
|
+
minify: true,
|
|
11
|
+
emptyOutDir: false,
|
|
12
|
+
apply: (_config, { command, mode }) => {
|
|
13
|
+
if (command === "build" && mode !== "client") {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
},
|
|
18
|
+
staticPaths: []
|
|
19
|
+
};
|
|
20
|
+
const buildPlugin = (options) => {
|
|
21
|
+
const virtualEntryId = "virtual:build-entry-module";
|
|
22
|
+
const resolvedVirtualEntryId = "\0" + virtualEntryId;
|
|
23
|
+
let config;
|
|
24
|
+
const output = options.output ?? defaultOptions.output;
|
|
25
|
+
return {
|
|
26
|
+
name: "@hono/vite-build",
|
|
27
|
+
configResolved: async (resolvedConfig) => {
|
|
28
|
+
config = resolvedConfig;
|
|
29
|
+
},
|
|
30
|
+
resolveId(id) {
|
|
31
|
+
if (id === virtualEntryId) {
|
|
32
|
+
return resolvedVirtualEntryId;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async load(id) {
|
|
36
|
+
if (id === resolvedVirtualEntryId) {
|
|
37
|
+
let staticPaths = [];
|
|
38
|
+
const direntPaths = [];
|
|
39
|
+
try {
|
|
40
|
+
const publicDirPaths = readdirSync(resolve(config.root, config.publicDir), {
|
|
41
|
+
withFileTypes: true
|
|
42
|
+
});
|
|
43
|
+
direntPaths.push(...publicDirPaths);
|
|
44
|
+
const buildOutDirPaths = readdirSync(resolve(config.root, config.build.outDir), {
|
|
45
|
+
withFileTypes: true
|
|
46
|
+
});
|
|
47
|
+
direntPaths.push(...buildOutDirPaths);
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
const uniqueStaticPaths = /* @__PURE__ */ new Set();
|
|
51
|
+
direntPaths.forEach((p) => {
|
|
52
|
+
if (p.isDirectory()) {
|
|
53
|
+
uniqueStaticPaths.add(`/${p.name}/*`);
|
|
54
|
+
} else {
|
|
55
|
+
if (p.name === output) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
uniqueStaticPaths.add(`/${p.name}`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
staticPaths = Array.from(uniqueStaticPaths);
|
|
62
|
+
const entry = options.entry ?? defaultOptions.entry;
|
|
63
|
+
return await getEntryContent({
|
|
64
|
+
entry: Array.isArray(entry) ? entry : [entry],
|
|
65
|
+
entryContentBeforeHooks: options.entryContentBeforeHooks,
|
|
66
|
+
entryContentAfterHooks: options.entryContentAfterHooks,
|
|
67
|
+
staticPaths
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
apply: options?.apply ?? defaultOptions.apply,
|
|
72
|
+
config: async () => {
|
|
73
|
+
return {
|
|
74
|
+
ssr: {
|
|
75
|
+
external: options?.external ?? defaultOptions.external,
|
|
76
|
+
noExternal: true,
|
|
77
|
+
target: "webworker"
|
|
78
|
+
},
|
|
79
|
+
build: {
|
|
80
|
+
outDir: options?.outputDir ?? defaultOptions.outputDir,
|
|
81
|
+
emptyOutDir: options?.emptyOutDir ?? defaultOptions.emptyOutDir,
|
|
82
|
+
minify: options?.minify ?? defaultOptions.minify,
|
|
83
|
+
ssr: true,
|
|
84
|
+
rollupOptions: {
|
|
85
|
+
external: [...builtinModules, /^node:/],
|
|
86
|
+
input: virtualEntryId,
|
|
87
|
+
output: {
|
|
88
|
+
entryFileNames: output
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
var base_default = buildPlugin;
|
|
97
|
+
export {
|
|
98
|
+
base_default as default,
|
|
99
|
+
defaultOptions
|
|
100
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type EntryContentHookOptions = {
|
|
2
|
+
staticPaths: string[];
|
|
3
|
+
};
|
|
4
|
+
type EntryContentHook = (appName: string, options?: EntryContentHookOptions) => string | Promise<string>;
|
|
5
|
+
type GetEntryContentOptions = {
|
|
6
|
+
entry: string[];
|
|
7
|
+
entryContentBeforeHooks?: EntryContentHook[];
|
|
8
|
+
entryContentAfterHooks?: EntryContentHook[];
|
|
9
|
+
staticPaths?: string[];
|
|
10
|
+
};
|
|
11
|
+
declare const getEntryContent: (options: GetEntryContentOptions) => Promise<string>;
|
|
12
|
+
|
|
13
|
+
export { EntryContentHook, EntryContentHookOptions, GetEntryContentOptions, getEntryContent };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { normalize } from "node:path";
|
|
2
|
+
const normalizePaths = (paths) => {
|
|
3
|
+
return paths.map((p) => {
|
|
4
|
+
let normalizedPath = normalize(p).replace(/\\/g, "/");
|
|
5
|
+
if (normalizedPath.startsWith("./")) {
|
|
6
|
+
normalizedPath = normalizedPath.substring(2);
|
|
7
|
+
}
|
|
8
|
+
return "/" + normalizedPath;
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
const getEntryContent = async (options) => {
|
|
12
|
+
const staticPaths = options.staticPaths ?? [""];
|
|
13
|
+
const globStr = normalizePaths(options.entry).map((e) => `'${e}'`).join(",");
|
|
14
|
+
const hooksToString = async (appName, hooks) => {
|
|
15
|
+
if (hooks) {
|
|
16
|
+
const str = (await Promise.all(
|
|
17
|
+
hooks.map((hook) => {
|
|
18
|
+
return hook(appName, {
|
|
19
|
+
staticPaths
|
|
20
|
+
});
|
|
21
|
+
})
|
|
22
|
+
)).join("\n");
|
|
23
|
+
return str;
|
|
24
|
+
}
|
|
25
|
+
return "";
|
|
26
|
+
};
|
|
27
|
+
const appStr = `const modules = import.meta.glob([${globStr}], { import: 'default', eager: true })
|
|
28
|
+
let added = false
|
|
29
|
+
for (const [, app] of Object.entries(modules)) {
|
|
30
|
+
if (app) {
|
|
31
|
+
mainApp.route('/', app)
|
|
32
|
+
mainApp.notFound(app.notFoundHandler)
|
|
33
|
+
added = true
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (!added) {
|
|
37
|
+
throw new Error("Can't import modules from [${globStr}]")
|
|
38
|
+
}`;
|
|
39
|
+
const mainAppStr = `import { Hono } from 'hono'
|
|
40
|
+
const mainApp = new Hono()
|
|
41
|
+
|
|
42
|
+
${await hooksToString("mainApp", options.entryContentBeforeHooks)}
|
|
43
|
+
|
|
44
|
+
${appStr}
|
|
45
|
+
|
|
46
|
+
${await hooksToString("mainApp", options.entryContentAfterHooks)}
|
|
47
|
+
|
|
48
|
+
export default mainApp`;
|
|
49
|
+
return mainAppStr;
|
|
50
|
+
};
|
|
51
|
+
export {
|
|
52
|
+
getEntryContent
|
|
53
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const serveStaticHook = (appName, options) => {
|
|
2
|
+
let code = "";
|
|
3
|
+
for (const path of options.filePaths ?? []) {
|
|
4
|
+
code += `${appName}.use('${path}', serveStatic({ root: '${options.root ?? "./"}' }))
|
|
5
|
+
`;
|
|
6
|
+
}
|
|
7
|
+
return code;
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
serveStaticHook
|
|
11
|
+
};
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hono/vite-build",
|
|
3
|
+
"description": "Vite plugin to build your Hono app",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "vitest --run",
|
|
10
|
+
"build": "rimraf dist && tsup && publint",
|
|
11
|
+
"watch": "tsup --watch",
|
|
12
|
+
"prerelease": "yarn build",
|
|
13
|
+
"release": "yarn publish"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./bun": {
|
|
24
|
+
"types": "./dist/adapter/bun/index.d.ts",
|
|
25
|
+
"import": "./dist/adapter/bun/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./node": {
|
|
28
|
+
"types": "./dist/adapter/node/index.d.ts",
|
|
29
|
+
"import": "./dist/adapter/node/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./cloudflare-pages": {
|
|
32
|
+
"types": "./dist/adapter/cloudflare-pages/index.d.ts",
|
|
33
|
+
"import": "./dist/adapter/cloudflare-pages/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./cloudflare-workers": {
|
|
36
|
+
"types": "./dist/adapter/cloudflare-workers/index.d.ts",
|
|
37
|
+
"import": "./dist/adapter/cloudflare-workers/index.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"typesVersions": {
|
|
41
|
+
"*": {
|
|
42
|
+
"types": [
|
|
43
|
+
"./dist/types"
|
|
44
|
+
],
|
|
45
|
+
"bun": [
|
|
46
|
+
"./dist/adapter/bun/index.d.ts"
|
|
47
|
+
],
|
|
48
|
+
"node": [
|
|
49
|
+
"./dist/adapter/node/index.d.ts"
|
|
50
|
+
],
|
|
51
|
+
"cloudflare-pages": [
|
|
52
|
+
"./dist/adapter/cloudflare-pages/index.d.ts"
|
|
53
|
+
],
|
|
54
|
+
"cloudflare-workers": [
|
|
55
|
+
"./dist/adapter/cloudflare-workers/index.d.ts"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"author": "Yusuke Wada <yusuke@kamawada.com> (https://github.com/yusukebe)",
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "https://github.com/honojs/vite-plugins.git"
|
|
64
|
+
},
|
|
65
|
+
"publishConfig": {
|
|
66
|
+
"registry": "https://registry.npmjs.org",
|
|
67
|
+
"access": "public"
|
|
68
|
+
},
|
|
69
|
+
"homepage": "https://github.com/honojs/vite-plugins",
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"glob": "^10.3.10",
|
|
72
|
+
"hono": "^4.6.1",
|
|
73
|
+
"publint": "^0.1.12",
|
|
74
|
+
"rimraf": "^5.0.1",
|
|
75
|
+
"tsup": "^7.2.0",
|
|
76
|
+
"vite": "^5.4.5",
|
|
77
|
+
"vitest": "^2.1.1"
|
|
78
|
+
},
|
|
79
|
+
"peerDependencies": {
|
|
80
|
+
"hono": "*"
|
|
81
|
+
},
|
|
82
|
+
"engines": {
|
|
83
|
+
"node": ">=18.14.1"
|
|
84
|
+
}
|
|
85
|
+
}
|