Skip to content

Instantly share code, notes, and snippets.

@mattfysh
Last active January 31, 2025 00:01
Show Gist options
  • Save mattfysh/897c3c83e06353bbf542122cec38eaa6 to your computer and use it in GitHub Desktop.
Save mattfysh/897c3c83e06353bbf542122cec38eaa6 to your computer and use it in GitHub Desktop.
bun build --target cloudflare
import path from 'node:path'
import Bun from 'bun'
import { z } from 'zod'
function soft(to: string, from: string) {
return new URL(import.meta.resolve(to, from)).pathname
}
function hard(to: string, from: string) {
return Bun.resolveSync(to, path.dirname(from))
}
const BrowserPkgSchema = z.object({
browser: z.string().or(z.record(z.string())),
})
const result = await Bun.build({
// using target=bun strips `node:` prefixes from specifiers
// but cloudflare requires them, and we cannot use target=browser
// or bun will include node polyfil's and does not respect --external
// @see https://github.com/oven-sh/bun/issues/2701
target: 'node',
entrypoints: ['src/index.ts'],
outdir: 'dist',
external: ['cloudflare:*'],
conditions: ['workerd', 'worker', 'browser'],
minify: true,
define: {
// prevent `createRequire(import.meta.url)` from failing
// on cloudflare where this value does not exist
'import.meta.url': JSON.stringify('file:///no'),
},
plugins: [
{
name: 'sink',
setup(build) {
const remap: Record<string, string> = {}
build.onResolve({ filter: /.*/ }, async args => {
try {
if (args.path[0] === '.') {
const resolved = hard(args.path, args.importer)
const browser = remap[resolved]
return browser ? { path: browser } : undefined
}
const pkgPath = soft(`${args.path}/package.json`, args.importer)
const file = Bun.file(pkgPath)
const contents = await file.json()
const { browser } = BrowserPkgSchema.parse(contents)
if (typeof browser !== 'string') {
for (const [k, v] of Object.entries(browser)) {
remap[soft(k, pkgPath)] = soft(v, pkgPath)
}
return undefined
}
const entry = path.resolve(path.dirname(pkgPath), browser)
return { path: entry }
} catch (_) {
return undefined
}
})
},
},
],
})
if (!result.success) {
throw new Error(String(result.logs.join('\n')))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment