Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: honojs/vite-plugins
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: @hono/vite-dev-server@0.18.1
Choose a base ref
...
head repository: honojs/vite-plugins
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: @hono/vite-dev-server@0.18.2
Choose a head ref
  • 7 commits
  • 16 files changed
  • 5 contributors

Commits on Jan 22, 2025

  1. chore: bump vite (#216)

    yusukebe authored Jan 22, 2025
    Copy the full SHA
    c40d227 View commit details

Commits on Jan 29, 2025

  1. feat(build): Add netlify-functions adapter (#218)

    Why?
    ====
    
    So we can build a bundle targetting the netlify-functions runtime.
    
    How?
    ====
    
    * Extend `EntryContentOptions` with `entryContentDefaultExportHook`
      to allow customizing the way the default export of the bundle is
      built.
    
    * Alter `getEntryContent` to use the `entryContentDefaultExportHook`
      for defining the default export, defaulting to the previous
      behavior if not defined.
    
    * Add `netlifyFunctionsBuildPlugin` as a new exported adapter that
      wraps the hono app in the `hono/netlify` `handle()` adapter and
      defines a `config` export to make the hono app respond to the
      root path in Netlify.
    chadxz authored Jan 29, 2025
    Copy the full SHA
    65e2f76 View commit details
  2. Version Packages (#221)

    github-actions[bot] authored Jan 29, 2025
    Copy the full SHA
    78cc3cd View commit details

Commits on Feb 14, 2025

  1. Fixed problem with source map not working when reading entry files (#228

    )
    
    * fix(dev-server): Improve error handling by fixing stack trace for SSR errors
    
    * add changeset
    mo36924 authored Feb 14, 2025
    Copy the full SHA
    5153b84 View commit details

Commits on Feb 24, 2025

  1. fix(dev-server): support hot reload for Vite6 (#231)

    * fix(dev-server): support hot reload for Vite6
    
    * add changeset
    yusukebe authored Feb 24, 2025
    Copy the full SHA
    eb196d5 View commit details
  2. chore: bump vite (#232)

    yusukebe authored Feb 24, 2025
    Copy the full SHA
    c99bc48 View commit details
  3. Version Packages (#229)

    Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
    github-actions[bot] and github-actions[bot] authored Feb 24, 2025
    Copy the full SHA
    ad5a6e8 View commit details
62 changes: 62 additions & 0 deletions packages/build/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,67 @@
# @hono/vite-build

## 1.3.0

### Minor Changes

- [#218](https://github.com/honojs/vite-plugins/pull/218) [`65e2f768a26d0665aaa05f60abf36bb66a6b6fa9`](https://github.com/honojs/vite-plugins/commit/65e2f768a26d0665aaa05f60abf36bb66a6b6fa9) Thanks [@chadxz](https://github.com/chadxz)! - Added a new Netlify Functions build adapter.

This adapter can be imported from `@hono/vite-build/netlify-functions` and will
compile your Hono app to comply with the requirements of the Netlify Functions
runtime.

- The default export will have the `hono/netlify` adapter applied to it.
- A `config` object will be exported, setting the function path to `'/*'` and
`preferStatic` to `true`.

Please note, this is for the Netlify Functions runtime, not the Netlify Edge
Functions runtime.

Example:

```ts
// vite.config.ts
import { defineConfig } from 'vite'
import devServer from '@hono/vite-dev-server'
import build from '@hono/vite-build/netlify-functions'

export default defineConfig({
plugins: [
devServer({
entry: './src/index.ts',
}),
build({
entry: './src/index.ts',
output: 'functions/server/index.js',
}),
],
})
```

If you also have a `public/publish` directory for your assets that should be
published to the corresponding Netlify site, then after running a build, you
would end up with a directory structure like:

```
dist/
functions/
server/
index.js
publish/
robots.txt
....
```

then you can use a netlify.toml that looks like:

```toml
# https://ntl.fyi/file-based-build-config
[build]
command = "vite build"
functions = "dist/functions"
publish = "dist/publish"
```

## 1.2.1

### Patch Changes
4 changes: 3 additions & 1 deletion packages/build/README.md
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ Here are the modules included:
- `@hono/vite-build/cloudflare-workers`
- `@hono/vite-build/bun`
- `@hono/vite-build/node`
- `@hono/vite-build/netlify-functions`

## Usage

@@ -36,6 +37,7 @@ import build from '@hono/vite-build/bun'
// import build from '@hono/vite-build/cloudflare-pages'
// import build from '@hono/vite-build/cloudflare-workers'
// import build from '@hono/vite-build/node'
// import build from '@hono/vite-build/netlify-functions'

export default defineConfig({
plugins: [
@@ -51,7 +53,7 @@ export default defineConfig({

### Build

Just run `vite build`.
Just run `vite build`.

```bash
npm exec vite build
11 changes: 9 additions & 2 deletions packages/build/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@hono/vite-build",
"description": "Vite plugin to build your Hono app",
"version": "1.2.1",
"version": "1.3.0",
"types": "dist/index.d.ts",
"module": "dist/index.js",
"type": "module",
@@ -36,6 +36,10 @@
"types": "./dist/adapter/cloudflare-workers/index.d.ts",
"import": "./dist/adapter/cloudflare-workers/index.js"
},
"./netlify-functions": {
"types": "./dist/adapter/netlify-functions/index.d.ts",
"import": "./dist/adapter/netlify-functions/index.js"
},
"./deno": {
"types": "./dist/adapter/deno/index.d.ts",
"import": "./dist/adapter/deno/index.js"
@@ -57,6 +61,9 @@
],
"cloudflare-workers": [
"./dist/adapter/cloudflare-workers/index.d.ts"
],
"netlify-functions": [
"./dist/adapter/netlify-functions/index.d.ts"
]
}
},
@@ -77,7 +84,7 @@
"publint": "^0.1.12",
"rimraf": "^5.0.1",
"tsup": "^7.2.0",
"vite": "^5.4.5",
"vite": "^6.1.1",
"vitest": "^2.1.1"
},
"peerDependencies": {
21 changes: 21 additions & 0 deletions packages/build/src/adapter/netlify-functions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Plugin } from 'vite'
import type { BuildOptions } from '../../base.js'
import buildPlugin from '../../base.js'

export type NetlifyFunctionsBuildOptions = BuildOptions

export default function netlifyFunctionsBuildPlugin(
pluginOptions?: NetlifyFunctionsBuildOptions
): Plugin {
return {
...buildPlugin({
...{
entryContentBeforeHooks: [() => 'import { handle } from "hono/netlify"'],
entryContentAfterHooks: [() => 'export const config = { path: "/*", preferStatic: true }'],
entryContentDefaultExportHook: (appName) => `export default handle(${appName})`,
},
...pluginOptions,
}),
name: '@hono/vite-build/netlify-functions',
}
}
7 changes: 5 additions & 2 deletions packages/build/src/base.ts
Original file line number Diff line number Diff line change
@@ -25,7 +25,10 @@ export type BuildOptions = {
} & Omit<GetEntryContentOptions, 'entry'>

export const defaultOptions: Required<
Omit<BuildOptions, 'entryContentAfterHooks' | 'entryContentBeforeHooks'>
Omit<
BuildOptions,
'entryContentAfterHooks' | 'entryContentBeforeHooks' | 'entryContentDefaultExportHook'
>
> = {
entry: ['src/index.ts', './src/index.tsx', './app/server.ts'],
output: 'index.js',
@@ -46,7 +49,6 @@ const buildPlugin = (options: BuildOptions): Plugin => {
const virtualEntryId = 'virtual:build-entry-module'
const resolvedVirtualEntryId = '\0' + virtualEntryId
let config: ResolvedConfig

const output = options.output ?? defaultOptions.output

return {
@@ -94,6 +96,7 @@ const buildPlugin = (options: BuildOptions): Plugin => {
entry: Array.isArray(entry) ? entry : [entry],
entryContentBeforeHooks: options.entryContentBeforeHooks,
entryContentAfterHooks: options.entryContentAfterHooks,
entryContentDefaultExportHook: options.entryContentDefaultExportHook,
staticPaths,
})
}
15 changes: 12 additions & 3 deletions packages/build/src/entry/index.ts
Original file line number Diff line number Diff line change
@@ -13,6 +13,13 @@ export type GetEntryContentOptions = {
entry: string[]
entryContentBeforeHooks?: EntryContentHook[]
entryContentAfterHooks?: EntryContentHook[]
/**
* Explicitly specify the default export for the app. Make sure your export
* incorporates the app passed as the `appName` argument.
*
* @default `export default ${appName}`
*/
entryContentDefaultExportHook?: EntryContentHook
staticPaths?: string[]
}

@@ -67,7 +74,10 @@ export const getEntryContent = async (options: GetEntryContentOptions) => {
throw new Error("Can't import modules from [${globStr}]")
}`

const mainAppStr = `import { Hono } from 'hono'
const defaultExportHook =
options.entryContentDefaultExportHook ?? (() => 'export default mainApp')

return `import { Hono } from 'hono'
const mainApp = new Hono()
${await hooksToString('mainApp', options.entryContentBeforeHooks)}
@@ -76,6 +86,5 @@ ${appStr}
${await hooksToString('mainApp', options.entryContentAfterHooks)}
export default mainApp`
return mainAppStr
${await hooksToString('mainApp', [defaultExportHook])}`
}
38 changes: 38 additions & 0 deletions packages/build/test/adapter.test.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ import { existsSync, readFileSync, rmSync } from 'node:fs'
import bunBuildPlugin from '../src/adapter/bun'
import cloudflarePagesPlugin from '../src/adapter/cloudflare-pages'
import denoBuildPlugin from '../src/adapter/deno'
import netlifyFunctionsPlugin from '../src/adapter/netlify-functions'
import nodeBuildPlugin from '../src/adapter/node'

describe('Build Plugin with Bun Adapter', () => {
@@ -41,6 +42,43 @@ describe('Build Plugin with Bun Adapter', () => {
})
})

describe('Build Plugin with Netlify Functions Adapter', () => {
const testDir = './test/mocks/app-static-files'
const entry = './src/server.ts'

afterEach(() => {
rmSync(`${testDir}/dist`, { recursive: true, force: true })
})

it('Should build the project correctly with the plugin', async () => {
const outputFile = `${testDir}/dist/index.js`

await build({
root: testDir,
plugins: [
netlifyFunctionsPlugin({
entry,
minify: false,
}),
],
})

expect(existsSync(outputFile)).toBe(true)

const output = readFileSync(outputFile, 'utf-8')
expect(output).toContain('Hello World')
expect(output).toContain('{ path: "/*", preferStatic: true }')
expect(output).toContain('handle(mainApp)')

const outputFooTxt = readFileSync(`${testDir}/dist/foo.txt`, 'utf-8')
expect(outputFooTxt).toContain('foo')

const outputJsClientJs = readFileSync(`${testDir}/dist/js/client.js`, 'utf-8')
// eslint-disable-next-line quotes
expect(outputJsClientJs).toContain("console.log('foo')")
})
})

describe('Build Plugin with Cloudflare Pages Adapter', () => {
const testDir = './test/mocks/app-static-files'

2 changes: 1 addition & 1 deletion packages/cloudflare-pages/package.json
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@
"publint": "^0.1.12",
"rimraf": "^5.0.1",
"tsup": "^7.2.0",
"vite": "^5.2.10",
"vite": "^6.1.1",
"vitest": "^1.2.1"
},
"peerDependencies": {
8 changes: 8 additions & 0 deletions packages/dev-server/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# @hono/vite-dev-server

## 0.18.2

### Patch Changes

- [#231](https://github.com/honojs/vite-plugins/pull/231) [`eb196d52a7f2059540c64a9c0b94298d49a00b90`](https://github.com/honojs/vite-plugins/commit/eb196d52a7f2059540c64a9c0b94298d49a00b90) Thanks [@yusukebe](https://github.com/yusukebe)! - fix: support hot reload for Vite6

- [#228](https://github.com/honojs/vite-plugins/pull/228) [`5153b84779b279274836512f7172c53e5cc11ae7`](https://github.com/honojs/vite-plugins/commit/5153b84779b279274836512f7172c53e5cc11ae7) Thanks [@mo36924](https://github.com/mo36924)! - fix: Fixed problem with source map not working when reading entry files

## 0.18.1

### Patch Changes
3 changes: 2 additions & 1 deletion packages/dev-server/e2e-bun/mock/app.ts
Original file line number Diff line number Diff line change
@@ -9,7 +9,8 @@ app.get('/', (c) => {
})

app.get('/with-nonce', (c) => {
c.header('content-security-policy', 'script-src-elem \'self\' \'nonce-ZMuLoN/taD7JZTUXfl5yvQ==\';')
// eslint-disable-next-line quotes -- allowing using double-quotes bc of embedded single quotes
c.header('content-security-policy', "script-src-elem 'self' 'nonce-ZMuLoN/taD7JZTUXfl5yvQ==';")
return c.html('<h1>Hello Vite!</h1>')
})

3 changes: 2 additions & 1 deletion packages/dev-server/e2e/mock/worker.ts
Original file line number Diff line number Diff line change
@@ -13,7 +13,8 @@ app.get('/', (c) => {
})

app.get('/with-nonce', (c) => {
c.header('content-security-policy', 'script-src-elem \'self\' \'nonce-ZMuLoN/taD7JZTUXfl5yvQ==\';')
// eslint-disable-next-line quotes -- allowing using double-quotes bc of embedded single quotes
c.header('content-security-policy', "script-src-elem 'self' 'nonce-ZMuLoN/taD7JZTUXfl5yvQ==';")
return c.html('<h1>Hello Vite!</h1>')
})

4 changes: 2 additions & 2 deletions packages/dev-server/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@hono/vite-dev-server",
"description": "Vite dev-server plugin for Hono",
"version": "0.18.1",
"version": "0.18.2",
"types": "dist/index.d.ts",
"module": "dist/index.js",
"type": "module",
@@ -81,7 +81,7 @@
"publint": "^0.2.5",
"rimraf": "^5.0.1",
"tsup": "^7.2.0",
"vite": "^5.2.10",
"vite": "^6.1.1",
"vitest": "^0.34.6",
"wrangler": "^3.63.1"
},
14 changes: 13 additions & 1 deletion packages/dev-server/src/dev-server.ts
Original file line number Diff line number Diff line change
@@ -107,7 +107,15 @@ export function devServer(options?: DevServerOptions): VitePlugin {
loadModule = options.loadModule
} else {
loadModule = async (server, entry) => {
const appModule = await server.ssrLoadModule(entry)
let appModule
try {
appModule = await server.ssrLoadModule(entry)
} catch (e) {
if (e instanceof Error) {
server.ssrFixStacktrace(e)
}
throw e
}
const exportName = options?.export ?? defaultOptions.export
const app = appModule[exportName] as { fetch: Fetch }
if (!app) {
@@ -200,6 +208,10 @@ export function devServer(options?: DevServerOptions): VitePlugin {
}
})
},
handleHotUpdate({ server }) {
server.ws.send({ type: 'full-reload' })
return []
},
config: () => {
return {
server: {
2 changes: 1 addition & 1 deletion packages/ssg/package.json
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@
"publint": "^0.1.12",
"rimraf": "^5.0.1",
"tsup": "^7.2.0",
"vite": "^5.2.10",
"vite": "^6.1.1",
"vitest": "^1.2.1"
},
"peerDependencies": {
2 changes: 1 addition & 1 deletion packages/ssg/test/app.ts
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ app.get('/', (c) => {
})

app.get('/dynamic-import', async (c) => {
// @ts-expect-error
// @ts-expect-error this is a test
const module = await import('./sample.js')
return c.text('Dynamic import works: ' + module.default)
})
Loading