Last active
July 29, 2023 20:58
-
-
Save JamieCurnow/374e69a2c3dd3b4952f967aa00a02938 to your computer and use it in GitHub Desktop.
Using firebase web framework with Nuxt 3
This file contains hidden or 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
// preset/entry.ts | |
import '#internal/nitro/virtual/polyfill' | |
import { toNodeListener } from 'h3' | |
import { trapUnhandledNodeErrors } from './utils' | |
const nitroApp = useNitroApp() | |
export const listener = toNodeListener(nitroApp.h3App) | |
/** @deprecated use new `listener` export instead */ | |
export const handler = listener | |
// Trap unhandled errors | |
trapUnhandledNodeErrors() |
This file contains hidden or 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
{ | |
"hosting": { | |
"source": ".", | |
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"], | |
"frameworksBackend": { | |
"region": "europe-west1", | |
"minInstances": 0, | |
"maxInstances": 4, | |
"concurrency": 80 | |
} | |
} | |
} |
This file contains hidden or 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
// preset/index.ts | |
import { fileURLToPath } from 'node:url' | |
import { createRequire } from 'node:module' | |
import type { NitroPreset } from 'nitropack' | |
import { join, resolve } from 'pathe' | |
import { globby } from 'globby' | |
import { readPackageJSON } from 'pkg-types' | |
import { writeFile } from './utils' | |
export default <NitroPreset>{ | |
extends: 'node', | |
entry: fileURLToPath(new URL('./entry.ts', import.meta.url)), | |
// serveStatic: true, | |
hooks: { | |
async compiled(nitro) { | |
const _require = createRequire(import.meta.url) | |
const jsons = await globby(join(nitro.options.output.serverDir, 'node_modules/**/package.json')) | |
const prefixLength = `${nitro.options.output.serverDir}/node_modules/`.length | |
const suffixLength = '/package.json'.length | |
const dependencies = jsons.reduce((obj, packageJson) => { | |
const dirname = packageJson.slice(prefixLength, -suffixLength) | |
if (!dirname.includes('node_modules')) { | |
obj[dirname] = _require(packageJson).version | |
} | |
return obj | |
}, {} as Record<string, string>) | |
const getPackageVersion = async (id: string) => { | |
const pkg = await readPackageJSON(id, { | |
url: nitro.options.nodeModulesDirs | |
}) | |
return pkg.version | |
} | |
await writeFile( | |
resolve(nitro.options.output.serverDir, 'package.json'), | |
JSON.stringify( | |
{ | |
name: 'nitro-output', | |
version: '0.0.0', | |
private: true, | |
dependencies: { | |
'firebase-functions-test': 'latest', | |
'firebase-admin': await getPackageVersion('firebase-admin'), | |
'firebase-functions': await getPackageVersion('firebase-functions'), | |
...dependencies | |
} | |
}, | |
null, | |
2 | |
) | |
) | |
} | |
} | |
} |
This file contains hidden or 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
export default defineNuxtConfig({ | |
ssr: true, | |
nitro: { | |
preset: resolve(__dirname, 'preset/index.ts') | |
} | |
}) |
This file contains hidden or 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
// preset/utils.ts | |
import fsp from 'node:fs/promises' | |
import { dirname } from 'pathe' | |
export function trapUnhandledNodeErrors() { | |
if (process.env.DEBUG) { | |
process.on('unhandledRejection', (err) => console.error('[nitro] [unhandledRejection]', err)) | |
process.on('uncaughtException', (err) => console.error('[nitro] [uncaughtException]', err)) | |
} else { | |
process.on('unhandledRejection', (err) => console.error('[nitro] [unhandledRejection] ' + err)) | |
process.on('uncaughtException', (err) => console.error('[nitro] [uncaughtException] ' + err)) | |
} | |
} | |
export async function writeFile(file: string, contents: Buffer | string) { | |
await fsp.mkdir(dirname(file), { recursive: true }) | |
await fsp.writeFile(file, contents, typeof contents === 'string' ? 'utf8' : undefined) | |
} |
@JamieCurnow Thanks for this! I'm going to try it out. Probably worth adding import { resolve } from "pathe"
to the top of nuxt.config.ts
:)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The index, entry and utils files should all be in the
/preset
sub dir from the nuxt.config.ts.I went with the approach of copying the nitro preset file for firebase and using the nitro entry file for plain node.
With this, you should be able to deploy the app to firebase via the webFrameworks