Skip to content

Commit

Permalink
making it work
Browse files Browse the repository at this point in the history
  • Loading branch information
remorses committed Jul 28, 2023
1 parent 18b9e0a commit 76209ec
Show file tree
Hide file tree
Showing 13 changed files with 681 additions and 66 deletions.
23 changes: 0 additions & 23 deletions deploy-next-middleware-to-cloudflare/package.json

This file was deleted.

9 changes: 0 additions & 9 deletions deploy-next-middleware-to-cloudflare/src/index.test.ts

This file was deleted.

Empty file.
3 changes: 3 additions & 0 deletions middleflare/bin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

require('./dist/bin.js')
36 changes: 36 additions & 0 deletions middleflare/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "middleflare",
"version": "0.0.0",
"description": "Deploy Next.js middleware to Cloudflare Workers",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"repository": "https://github.com/remorses/middleflare",
"bin": {
"middleflare": "bin.js"
},
"scripts": {
"build": "tsc",
"cli": "tsx src/bin.ts",
"watch": "tsc -w"
},
"files": [
"dist",
"src",
"bin.js",
"esm"
],
"keywords": [],
"author": "Tommaso De Rossi, morse <beats.by.morse@gmail.com>",
"license": "",
"devDependencies": {
"next": "^13.4.12"
},
"dependencies": {
"@cac/required-option": "^1.0.0",
"@cloudflare/workers-types": "^3.8.0",
"@types/node": "^20.4.5",
"cac": "^6.7.14",
"esbuild": "^0.18.17",
"esbuild-plugin-polyfill-node": "^0.3.0"
}
}
37 changes: 37 additions & 0 deletions middleflare/src/bin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { cac } from 'cac'
import { buildMiddleware } from './build'
const { name, version } = require('../package.json')

const cli = cac(name)

cli.command('')
.option('--url <url>', 'Your deployed Next.js url, like xxx.fly.dev', {})
.option('--middleware <middlewarePath>', 'Your Next.js middleware path', {})
.action(async (opts) => {
console.log(opts)
const { middleware, url } = opts
await buildMiddleware({
middleware,
url,
})
})

cli.help()
cli.version(version)

async function main() {
try {
// Parse CLI args without running the command
cli.parse(process.argv, { run: false })
// Run the command yourself
// You only need `await` when your command action returns a Promise
await cli.runMatchedCommand()
} catch (error: any) {
// Handle error here..
// e.g.
console.error(error.stack)
process.exit(1)
}
}

main()
184 changes: 184 additions & 0 deletions middleflare/src/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import { build, context, PluginBuild } from 'esbuild'

import { polyfillNode } from 'esbuild-plugin-polyfill-node'

import fs from 'fs'

import path from 'path'

// console.log(process.env.DIRECT_URL)

export async function buildMiddleware({ middleware, url }) {
if (!middleware) {
throw new Error(`--middleware is required`)
}
if (!url) {
throw new Error(`--url is required`)
}
middleware = path.resolve(middleware)
const u = safeUrl(url)
if (!u) {
throw new Error(`invalid url ${url}`)
}
// to make docker generate native prisma addons
const define = Object.fromEntries(
Object.keys(process.env).map((k) => {
return [`process.env.${k}`, JSON.stringify(process.env[k])]
}),
)
fs.promises.unlink('dist').catch((e) => null)
const index = path.resolve(
path.dirname(require.resolve('../package.json')),
'src/index.ts',
)
const { metafile } = await build({
// entryPoints: ['src/worker.ts'],
stdin: {
contents: `
import { middlewareAdapter } from '${index}';
export default middlewareAdapter({
middlewareModule: await import('${middleware}'),
finalUrl: '${url}',
})
`,
resolveDir: process.cwd(),
loader: 'ts',
},
bundle: true,
platform: 'browser',
sourcemap: false,
// sourcemap: 'inline',
metafile: true,
format: 'esm',
minify: false,
// format: 'esm',
// mainFields: ['module', 'main'],
plugins: [
LooselyIgnoreDeps(),
polyfillNode(), //
StripWasmModulesQuery(),
// UseNextEsm(),
],
external: [],
// target: 'node18',
logOverride: {
'import-is-undefined': 'silent',
},
define,
// splitting: false,
// splitting: true,
// outdir: 'dist',
outfile: 'dist/worker.js',
})

fs.writeFileSync('dist/metafile.json', JSON.stringify(metafile, null, 2))
}

const ignore = ['@vercel/og']
function LooselyIgnoreDeps() {
return {
name: 'Skip binaries',
setup(build: PluginBuild) {
const ignorePath = '/__ignore__'
build.onLoad({ filter: /__ignore__/ }, (args) => {
return {
contents: '',
loader: 'js',
}
})
build.onResolve(
{
filter: /.*/,
},
(args) => {
if (
ignore.some(
(x) => args.path === x || args.path.includes(x),
)
) {
return { path: ignorePath }
}
return
},
)
},
}
}

function UseNextEsm() {
return {
name: 'Use next esm',
setup(build: PluginBuild) {
build.onResolve(
{
filter: /\/next\/dist.*/,
},
(args) => {
if (!args.path.includes('node_modules')) {
return
}
if (!args.path.startsWith('next/')) {
return
}
const newPath = args.path.replace(
'/next/dist/',
'/next/dist/esm/',
)

return {
path: newPath,
}
},
)
},
}
}

function StripWasmModulesQuery() {
return {
name: 'wasm modules',
setup(build: PluginBuild) {
build.onResolve(
{
filter: /\.wasm(?:\?.*)?/,
},
(args) => {
return {
path: removeQuery(
path.isAbsolute(args.path)
? args.path
: path.join(args.resolveDir, args.path),
),
sideEffects: false,
}
},
)
build.onLoad(
{
filter: /\.wasm(?:\?.*)?/,
},
(args) => {
return {
resolveDir: path.dirname(args.path),
contents: fs.readFileSync(args.path),
loader: 'copy',
}
},
)
},
}
}

function removeQuery(url: string) {
const i = url.indexOf('?')
if (i === -1) return url
return url.slice(0, i)
}

function safeUrl(url: string) {
try {
return new URL(url)
} catch (e) {
return null
}
}
1 change: 1 addition & 0 deletions middleflare/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { middlewareAdapter } from './utils'

0 comments on commit 76209ec

Please sign in to comment.