0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-10 23:01:26 -05:00

feat(cloudflare): add runtime persistence directory option (#23)

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
Alexander Niebuhr 2023-10-19 07:50:13 +02:00 committed by GitHub
parent a64ae13dcf
commit 9094a8673f
5 changed files with 62 additions and 14 deletions

View file

@ -1,3 +1,4 @@
# Astro cloudflare directory mode creates a function directory
functions
.mf
.wrangler

View file

@ -186,17 +186,25 @@ export default defineConfig({
### `runtime`
`runtime: "off" | "local"`
`runtime: { mode: "off" | "local", persistTo: string }`
default `"off"`
default `{ mode: 'off', persistTo: '' }`
Determines whether and how the Cloudflare Runtime is added to `astro dev`.
The Cloudflare Runtime includes [Cloudflare bindings](https://developers.cloudflare.com/pages/platform/functions/bindings), [environment variables](https://developers.cloudflare.com/pages/platform/functions/bindings/#environment-variables), and the [cf object](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties). Read more about [accessing the Cloudflare Runtime](#cloudflare-runtime).
The `mode` property defines how the runtime is added to `astro dev`:
- `local`: uses bindings mocking and locally static placeholders
- `off`: no access to the Cloudflare runtime using `astro dev`. You can alternatively use [Preview with Wrangler](#preview-with-wrangler)
The `persistTo` property defines where the local runtime is persisted to when using `mode: local`. This value is a directory relative to your `astro dev` execution path.
The default value is set to `.wrangler/state/v3` to match the default path Wrangler uses. This means both tools are able to access and use the local state.
Whichever directory is set in `persistTo`, `.wrangler` or your custom value, must be added to `.gitignore`.
```diff lang="js"
// astro.config.mjs
import { defineConfig } from 'astro/config';
@ -205,7 +213,7 @@ import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
output: 'server',
adapter: cloudflare({
+ runtime: 'local',
+ runtime: { mode: 'local' },
}),
});
```

View file

@ -26,6 +26,7 @@ import { wasmModuleLoader } from './utils/wasm-module-loader.js';
export type { AdvancedRuntime } from './entrypoints/server.advanced.js';
export type { DirectoryRuntime } from './entrypoints/server.directory.js';
type CF_RUNTIME = { mode: 'off' } | { mode: 'remote' } | { mode: 'local'; persistTo: string };
type Options = {
mode?: 'directory' | 'advanced';
functionPerRoute?: boolean;
@ -43,11 +44,18 @@ type Options = {
exclude?: string[];
};
/**
* Going forward only the object API should be used. The modes work as known before:
* 'off': current behaviour (wrangler is needed)
* 'local': use a static req.cf object, and env vars defined in wrangler.toml & .dev.vars (astro dev is enough)
* 'remote': use a dynamic real-live req.cf object, and env vars defined in wrangler.toml & .dev.vars (astro dev is enough)
*/
runtime?: 'off' | 'local' | 'remote';
runtime?:
| 'off'
| 'local'
| 'remote'
| { mode: 'off' }
| { mode: 'remote' }
| { mode: 'local'; persistTo?: string };
wasmModuleImports?: boolean;
};
@ -59,6 +67,14 @@ interface BuildConfig {
split?: boolean;
}
const RUNTIME_WARNING = `You are using a deprecated string format for the \`runtime\` API. Please update to the current format for better support.
Example:
Old Format: 'local'
Current Format: { mode: 'local', persistTo: '.wrangler/state/v3' }
Please refer to our runtime documentation for more details on the format. https://docs.astro.build/en/guides/integrations-guide/cloudflare/#runtime`;
export default function createIntegration(args?: Options): AstroIntegration {
let _config: AstroConfig;
let _buildConfig: BuildConfig;
@ -69,7 +85,21 @@ export default function createIntegration(args?: Options): AstroIntegration {
const isModeDirectory = args?.mode === 'directory';
const functionPerRoute = args?.functionPerRoute ?? false;
const runtimeMode = args?.runtime ?? 'off';
let runtimeMode: CF_RUNTIME = { mode: 'off' };
if (args?.runtime === 'remote') {
runtimeMode = { mode: 'remote' };
} else if (args?.runtime === 'local') {
runtimeMode = { mode: 'local', persistTo: '.wrangler/state/v3' };
} else if (
typeof args?.runtime === 'object' &&
args?.runtime.mode === 'local' &&
args.runtime.persistTo === undefined
) {
runtimeMode = { mode: 'local', persistTo: '.wrangler/state/v3' };
} else {
runtimeMode = args?.runtime as CF_RUNTIME;
}
return {
name: '@astrojs/cloudflare',
@ -93,7 +123,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
},
});
},
'astro:config:done': ({ setAdapter, config }) => {
'astro:config:done': ({ setAdapter, config, logger }) => {
setAdapter(getAdapter({ isModeDirectory, functionPerRoute }));
_config = config;
_buildConfig = config.build;
@ -109,12 +139,17 @@ export default function createIntegration(args?: Options): AstroIntegration {
'[@astrojs/cloudflare] `base: "${SERVER_BUILD_FOLDER}"` is not allowed. Please change your `base` config to something else.'
);
}
if (typeof args?.runtime === 'string') {
logger.warn(RUNTIME_WARNING);
}
},
'astro:server:setup': ({ server }) => {
if (runtimeMode !== 'off') {
if (runtimeMode.mode === 'local') {
const typedRuntimeMode = runtimeMode;
server.middlewares.use(async function middleware(req, res, next) {
try {
const cf = await getCFObject(runtimeMode);
const cf = await getCFObject(typedRuntimeMode.mode);
const vars = await getEnvVars();
const D1Bindings = await getD1Bindings();
const R2Bindings = await getR2Bindings();
@ -134,13 +169,13 @@ export default function createIntegration(args?: Options): AstroIntegration {
cachePersist: true,
cacheWarnUsage: true,
d1Databases: D1Bindings,
d1Persist: true,
d1Persist: `${typedRuntimeMode.persistTo}/d1`,
r2Buckets: R2Bindings,
r2Persist: true,
r2Persist: `${typedRuntimeMode.persistTo}/r2`,
kvNamespaces: KVBindings,
kvPersist: true,
kvPersist: `${typedRuntimeMode.persistTo}/kv`,
durableObjects: DOBindings,
durableObjectsPersist: true,
durableObjectsPersist: `${typedRuntimeMode.persistTo}/do`,
});
await _mf.ready;

View file

@ -1,10 +1,11 @@
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
adapter: cloudflare({
runtime: 'local'
runtime: {
mode: 'local',
},
}),
output: 'server',
});

View file

@ -5,5 +5,8 @@
"dependencies": {
"@astrojs/cloudflare": "workspace:*",
"astro": "^3.2.3"
},
"devDependencies": {
"wrangler": "^3.13.1"
}
}