@hono/vite-build
@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.
Here are the modules included:
@hono/vite-build/base
@hono/vite-build/cloudflare-pages
@hono/vite-build/cloudflare-workers
@hono/vite-build/bun
@hono/vite-build/node
@hono/vite-build/netlify-functions
@hono/vite-build/vercel
Usage
Install
You can install vite and @hono/vite-build via the npm.
npm i -D vite @hono/vite-build
Or you can install them with Bun.
bun add -D vite @hono/vite-build
Settings
Add "type": "module" to your package.json. Then, create vite.config.ts and edit it. The following is for Bun.
import { defineConfig } from 'vite'
import build from '@hono/vite-build/bun'
export default defineConfig({
plugins: [
build({
entry: './src/index.tsx',
port: 3001,
}),
],
})
Build
Just run vite build.
npm exec vite build
Or
bunx --bun vite build
Run
Run with the command on your runtime. For examples:
Cloudflare Pages:
wrangler pages dev ./dist
Bun:
cd ./dist
bun run ./index.js
Node.js:
cd ./dist
node ./index.js
Common Options
type BuildOptions = {
entry?: string | string[]
output?: string
outputDir?: string
external?: string[]
minify?: boolean
emptyOutDir?: boolean
preset?: 'hono' | 'hono/tiny' | 'hono/quick' '@hono/hono'
}
Default values:
export const defaultOptions = {
entry: ['src/index.ts', './src/index.tsx', './app/server.ts'],
output: 'index.js',
outputDir: './dist',
external: [],
minify: true,
emptyOutDir: false,
staticPaths: [],
preset: 'hono',
}
Platform specific things
Cloudflare Pages
This plugin generates _routes.json automatically. The automatic generation can be overridden by creating a public/_routes.json. See Create a _routes.json file on Cloudflare Docs for more details.
Vercel
By default, the Vercel adapter emits a single function named __hono and a catch-all route.
To emit multiple functions, add the Vercel adapter multiple times in plugins.
import { defineConfig } from 'vite'
import build from '@hono/vite-build/vercel'
export default defineConfig({
plugins: [
build({
entry: './src/server.ts',
vercel: {
name: 'api',
routes: [{ src: '^/api(?:/.*)?$' }],
},
}),
build({
entry: './src/auth.ts',
vercel: {
name: 'auth',
routes: [{ src: '^/auth(?:/.*)?$' }],
function: {
maxDuration: 30,
},
},
}),
],
})
If vercel.routes is omitted, the adapter generates ^/<function-name>(?:/.*)?$.
If vercel.name is omitted, the adapter uses __hono.
Example project
src/index.tsx:
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.html(
<html>
<head>
<link href='/static/style.css' rel='stylesheet' />
</head>
<body>
<h1>Hello!</h1>
</body>
</html>
)
})
export default app
public/static/style.css:
h1 {
font-family: Arial, Helvetica, sans-serif;
}
The project with those file will be built to the following files with @hono/vite-build/bun:
dist
├── index.js
└── static
└── style.css
Build a client
If you also want to build a client-side script, you can configure it as follows.
export default defineConfig(({ mode }) => {
if (mode === 'client') {
return {
build: {
rollupOptions: {
input: './src/client.ts',
output: {
dir: './dist/static',
entryFileNames: 'client.js',
},
},
copyPublicDir: false,
},
}
} else {
return {
plugins: [build()],
}
}
})
The build command:
vite build --mode client && vite build
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.
app.get('/', (c) => {
return c.html(
<html>
<head>
{import.meta.env.PROD ? (
<script type='module' src='/static/client.js'></script>
) : (
<script type='module' src='/src/client.ts'></script>
)}
</head>
<body>Hello!</body>
</html>
)
})
Example
You can see the example project here - hono-vite-jsx
Authors
License
MIT