diff options
Diffstat (limited to 'packages/integrations/cloudflare/src')
-rw-r--r-- | packages/integrations/cloudflare/src/index.ts | 145 | ||||
-rw-r--r-- | packages/integrations/cloudflare/src/server.directory.ts | 2 |
2 files changed, 103 insertions, 44 deletions
diff --git a/packages/integrations/cloudflare/src/index.ts b/packages/integrations/cloudflare/src/index.ts index 252dd778a..f4ee26fea 100644 --- a/packages/integrations/cloudflare/src/index.ts +++ b/packages/integrations/cloudflare/src/index.ts @@ -1,8 +1,9 @@ import { createRedirectsFromAstroRoutes } from '@astrojs/underscore-redirects'; -import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro'; +import type { AstroAdapter, AstroConfig, AstroIntegration, RouteData } from 'astro'; import esbuild from 'esbuild'; import * as fs from 'fs'; import * as os from 'os'; +import { dirname } from 'path'; import glob from 'tiny-glob'; import { fileURLToPath, pathToFileURL } from 'url'; @@ -14,20 +15,21 @@ interface BuildConfig { server: URL; client: URL; serverEntry: string; + split?: boolean; } export function getAdapter(isModeDirectory: boolean): AstroAdapter { return isModeDirectory ? { - name: '@astrojs/cloudflare', - serverEntrypoint: '@astrojs/cloudflare/server.directory.js', - exports: ['onRequest'], - } + name: '@astrojs/cloudflare', + serverEntrypoint: '@astrojs/cloudflare/server.directory.js', + exports: ['onRequest', 'manifest'], + } : { - name: '@astrojs/cloudflare', - serverEntrypoint: '@astrojs/cloudflare/server.advanced.js', - exports: ['default'], - }; + name: '@astrojs/cloudflare', + serverEntrypoint: '@astrojs/cloudflare/server.advanced.js', + exports: ['default'], + }; } const SHIM = `globalThis.process = { @@ -41,6 +43,7 @@ export default function createIntegration(args?: Options): AstroIntegration { let _config: AstroConfig; let _buildConfig: BuildConfig; const isModeDirectory = args?.mode === 'directory'; + let _entryPoints = new Map<RouteData, URL>(); return { name: '@astrojs/cloudflare', @@ -90,35 +93,99 @@ export default function createIntegration(args?: Options): AstroIntegration { vite.ssr.target = 'webworker'; } }, + 'astro:build:ssr': ({ manifest, entryPoints }) => { + _entryPoints = entryPoints; + }, 'astro:build:done': async ({ pages, routes, dir }) => { - const entryPath = fileURLToPath(new URL(_buildConfig.serverEntry, _buildConfig.server)); - const entryUrl = new URL(_buildConfig.serverEntry, _config.outDir); - const buildPath = fileURLToPath(entryUrl); - // A URL for the final build path after renaming - const finalBuildUrl = pathToFileURL(buildPath.replace(/\.mjs$/, '.js')); - - await esbuild.build({ - target: 'es2020', - platform: 'browser', - conditions: ['workerd', 'worker', 'browser'], - entryPoints: [entryPath], - outfile: buildPath, - allowOverwrite: true, - format: 'esm', - bundle: true, - minify: _config.vite?.build?.minify !== false, - banner: { - js: SHIM, - }, - logOverride: { - 'ignored-bare-import': 'silent', - }, - }); + const functionsUrl = new URL('functions/', _config.root); + + if (isModeDirectory) { + await fs.promises.mkdir(functionsUrl, { recursive: true }); + } + + if (isModeDirectory && _buildConfig.split) { + const entryPointsRouteData = [..._entryPoints.keys()] + const entryPointsURL = [..._entryPoints.values()] + const entryPaths = entryPointsURL.map((entry) => fileURLToPath(entry)); + const outputDir = fileURLToPath(new URL('.astro', _buildConfig.server)); + + // NOTE: AFAIK, esbuild keeps the order of the entryPoints array + const { outputFiles } = await esbuild.build({ + target: 'es2020', + platform: 'browser', + conditions: ['workerd', 'worker', 'browser'], + entryPoints: entryPaths, + outdir: outputDir, + allowOverwrite: true, + format: 'esm', + bundle: true, + minify: _config.vite?.build?.minify !== false, + banner: { + js: SHIM, + }, + logOverride: { + 'ignored-bare-import': 'silent', + }, + write: false, + }); - // Rename to worker.js - await fs.promises.rename(buildPath, finalBuildUrl); + // loop through all bundled files and write them to the functions folder + for (const [index, outputFile] of outputFiles.entries()) { + // we need to make sure the filename in the functions folder + // matches to cloudflares routing capabilities (see their docs) + // IN: src/pages/[language]/files/[...path].astro + // OUT: [language]/files/[[path]].js + const fileName = entryPointsRouteData[index].component + .replace('src/pages/', '') + .replace('.astro', '.js') + .replace(/(\[\.\.\.)(\w+)(\])/g, (_match, _p1, p2, _p3) => { + return `[[${p2}]]`; + }); + + const fileUrl = new URL(fileName, functionsUrl) + const newFileDir = dirname(fileURLToPath(fileUrl)); + if (!fs.existsSync(newFileDir)) { + fs.mkdirSync(newFileDir, { recursive: true }); + } + await fs.promises.writeFile(fileUrl, outputFile.contents); + } - // throw the server folder in the bin + } else { + const entryPath = fileURLToPath(new URL(_buildConfig.serverEntry, _buildConfig.server)); + const entryUrl = new URL(_buildConfig.serverEntry, _config.outDir); + const buildPath = fileURLToPath(entryUrl); + // A URL for the final build path after renaming + const finalBuildUrl = pathToFileURL(buildPath.replace(/\.mjs$/, '.js')); + + await esbuild.build({ + target: 'es2020', + platform: 'browser', + conditions: ['workerd', 'worker', 'browser'], + entryPoints: [entryPath], + outfile: buildPath, + allowOverwrite: true, + format: 'esm', + bundle: true, + minify: _config.vite?.build?.minify !== false, + banner: { + js: SHIM, + }, + logOverride: { + 'ignored-bare-import': 'silent', + }, + }); + + // Rename to worker.js + await fs.promises.rename(buildPath, finalBuildUrl); + + if (isModeDirectory) { + const directoryUrl = new URL('[[path]].js', functionsUrl); + await fs.promises.rename(finalBuildUrl, directoryUrl); + } + + } + + // // // throw the server folder in the bin const serverUrl = new URL(_buildConfig.server); await fs.promises.rm(serverUrl, { recursive: true, force: true }); @@ -225,14 +292,6 @@ export default function createIntegration(args?: Options): AstroIntegration { ) ); } - - if (isModeDirectory) { - const functionsUrl = new URL('functions/', _config.root); - await fs.promises.mkdir(functionsUrl, { recursive: true }); - - const directoryUrl = new URL('[[path]].js', functionsUrl); - await fs.promises.rename(finalBuildUrl, directoryUrl); - } }, }, }; diff --git a/packages/integrations/cloudflare/src/server.directory.ts b/packages/integrations/cloudflare/src/server.directory.ts index da2360557..f9f71a33b 100644 --- a/packages/integrations/cloudflare/src/server.directory.ts +++ b/packages/integrations/cloudflare/src/server.directory.ts @@ -61,5 +61,5 @@ export function createExports(manifest: SSRManifest) { }); }; - return { onRequest }; + return { onRequest, manifest }; } |