-
Notifications
You must be signed in to change notification settings - Fork 164
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* 🎉 Create Bun Transpiler Middleware Package * ➕ Add @types/bun dev dependency * 🔧 Use Bun Testrunner * ✨ Implement Bun Transpiler Middleware * ✅ Add Tests for Bun Transpiler middleware * 📝 Add README to Bun Transpiler middleware * 📝 Add Changeset * 👷 Setup CI for Bun Transpiler middleware * 🔧 Configure Bun as external during Build * 🔧 Setup global build script for Bun Transpiler middleware
- Loading branch information
1 parent
965d5a3
commit 3f39be7
Showing
9 changed files
with
260 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@hono/bun-transpiler': minor | ||
--- | ||
|
||
Added @hono/bun-transpiler middleware |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: ci-bun-transpiler | ||
on: | ||
push: | ||
branches: [main] | ||
paths: | ||
- 'packages/bun-transpiler/**' | ||
pull_request: | ||
branches: ['*'] | ||
paths: | ||
- 'packages/bun-transpiler/**' | ||
|
||
jobs: | ||
ci: | ||
runs-on: ubuntu-latest | ||
defaults: | ||
run: | ||
working-directory: ./packages/bun-transpiler | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: oven-sh/setup-bun@v1 | ||
- run: yarn install --frozen-lockfile | ||
- run: yarn build | ||
- run: yarn test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Bun Transpiler middleware for Hono | ||
|
||
The Bun Transpiler middleware is a Hono middleware designed to transpile content such as TypeScript or TSX. You can place your script written in TypeScript in a directory and serve it using `serveStatic`. When you apply this middleware, your script will automatically be served transpiled into JavaScript code. | ||
|
||
This middleware works only with [Bun](https://bun.sh/). | ||
|
||
## Usage | ||
|
||
### Installation | ||
|
||
```sh | ||
npm i @hono/bun-transpiler | ||
``` | ||
|
||
### Example | ||
|
||
```ts | ||
import { Hono } from 'hono' | ||
import { serveStatic } from 'hono/bun' | ||
import { bunTranspiler } from '@hono/bun-transpiler' | ||
|
||
const app = new Hono() | ||
|
||
app.get('/static/:scriptName{.+.tsx?}', bunTranspiler()) | ||
app.get('/static/*', serveStatic({ root: './' })) | ||
|
||
export default app | ||
``` | ||
|
||
## Notes | ||
|
||
- This middleware does not have a cache feature. If you want to cache the transpiled code, use [Cache Middleware](https://hono.dev/middleware/builtin/cache) or your own custom middleware. | ||
|
||
## Author | ||
|
||
Florian Kapaun <https://github.com/floriankapaun> | ||
|
||
Heavily inspired by [esbuild-transpiler](https://github.com/honojs/middleware/tree/main/packages/esbuild-transpiler) by [Andres C. Rodriguez](https://github.com/acrodrig) and [Yusuke Wada](https://github.com/yusukebe). | ||
|
||
## License | ||
|
||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{ | ||
"name": "@hono/bun-transpiler", | ||
"version": "0.1.1", | ||
"description": "Bun Transpiler Middleware for Hono", | ||
"main": "dist/index.js", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist" | ||
], | ||
"scripts": { | ||
"test": "bun test", | ||
"build": "tsup ./src/index.ts --format esm,cjs --dts --external bun", | ||
"publint": "publint", | ||
"release": "yarn build && yarn test && yarn publint && yarn publish" | ||
}, | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.mts", | ||
"import": "./dist/index.mjs", | ||
"require": "./dist/index.js" | ||
} | ||
}, | ||
"license": "MIT", | ||
"publishConfig": { | ||
"registry": "https://registry.npmjs.org", | ||
"access": "public" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/honojs/middleware.git" | ||
}, | ||
"homepage": "https://github.com/honojs/middleware", | ||
"peerDependencies": { | ||
"hono": "*" | ||
}, | ||
"devDependencies": { | ||
"@types/bun": "^1.0.0", | ||
"hono": "^3.11.7", | ||
"tsup": "^8.0.1", | ||
"vitest": "^1.0.4" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { Hono } from 'hono' | ||
import { bunTranspiler } from '.' | ||
|
||
const HOST = 'http://localhost' | ||
|
||
const TS = 'const add = (a: number, b: number): number => a + b' | ||
const TS_TRANSPILED = 'const add=(a,b)=>a+b;' | ||
const TSX = 'const element = <h1>hello world</h1>' | ||
const TSX_TRANSPILED = | ||
'const element=jsxDEV("h1",{children:"hello world"},undefined,false,undefined,this);' | ||
const BAD = 'function { !!! !@#$ add(a: INT) return a + b + c; }' | ||
|
||
describe('Bun Transpiler middleware', () => { | ||
const app = new Hono() | ||
|
||
app.use('*', bunTranspiler()) | ||
|
||
app.get('/script.js', (c) => c.text(TS)) // Serve TS to test if it gets transpiled | ||
app.get('/script.ts', (c) => c.text(TS)) | ||
app.get('/script.tsx', (c) => c.text(TSX)) | ||
app.get('/bad.ts', (c) => c.text(BAD)) | ||
|
||
it('Should ignore non typescript content paths', async () => { | ||
const res = await app.request(`${HOST}/script.js`) | ||
expect(res).not.toBeNull() | ||
expect(res.status).toBe(200) | ||
expect(await res.text()).toBe(TS) | ||
}) | ||
|
||
it('Should transpile typescript', async () => { | ||
const res = await app.request(`${HOST}/script.ts`) | ||
expect(res).not.toBeNull() | ||
expect(res.status).toBe(200) | ||
expect(await res.text()).toBe(TS_TRANSPILED) | ||
expect(res.headers.get('content-type')).toBe('application/javascript') | ||
}) | ||
|
||
it('Should transpile TSX', async () => { | ||
const res = await app.request(`${HOST}/script.tsx`) | ||
expect(res).not.toBeNull() | ||
expect(res.status).toBe(200) | ||
expect(await res.text()).toBe(TSX_TRANSPILED) | ||
expect(res.headers.get('content-type')).toBe('application/javascript') | ||
}) | ||
|
||
it('Should return error on badly formed typescript', async () => { | ||
const res = await app.request(`${HOST}/bad.ts`) | ||
expect(res).not.toBeNull() | ||
expect(res.status).toBe(500) | ||
expect(await res.text()).toBe('Parse error') | ||
expect(res.headers.get('content-type')).toBe('text/plain') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import Bun from 'bun' | ||
import { createMiddleware } from 'hono/factory' | ||
|
||
type BunTranspilerOptions = { | ||
extensions: string[] | ||
headers: HeadersInit | ||
transpilerOptions: Bun.TranspilerOptions | ||
} | ||
|
||
export const bunTranspiler = ( | ||
options: BunTranspilerOptions = { | ||
extensions: ['.ts', '.tsx'], | ||
headers: { 'content-type': 'application/javascript' }, | ||
transpilerOptions: { | ||
minifyWhitespace: true, | ||
target: 'browser', | ||
}, | ||
} | ||
) => { | ||
return createMiddleware(async (c, next) => { | ||
await next() | ||
const url = new URL(c.req.url) | ||
const { extensions, headers, transpilerOptions } = options | ||
|
||
if (extensions.every((ext) => !url.pathname.endsWith(ext))) return | ||
|
||
try { | ||
const loader = url.pathname.split('.').pop() as Bun.TranspilerOptions['loader'] | ||
const transpiler = new Bun.Transpiler({ | ||
loader, | ||
...transpilerOptions, | ||
}) | ||
const transpiledCode = await transpiler.transformSync(await c.res.text()) | ||
c.res = c.newResponse(transpiledCode, { headers }) | ||
} catch (error) { | ||
console.warn(`Error transpiling ${url.pathname}: ${error}`) | ||
const errorHeaders = { | ||
...headers, | ||
'content-type': 'text/plain', | ||
} | ||
if (error instanceof Error) { | ||
c.res = c.newResponse(error.message, { | ||
status: 500, | ||
headers: errorHeaders, | ||
}) | ||
} else { | ||
c.res = c.newResponse('Malformed Input', { | ||
status: 500, | ||
headers: errorHeaders, | ||
}) | ||
} | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "../../tsconfig.json", | ||
"compilerOptions": { | ||
"rootDir": "./src", | ||
"outDir": "./dist", | ||
}, | ||
"include": [ | ||
"src/**/*.ts" | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters