Skip to content

Commit

Permalink
adding paths from _redirect file into the auto generated _routes.json…
Browse files Browse the repository at this point in the history
… + docs adjustment
  • Loading branch information
AirBorne04 authored and AirBorne04 committed Nov 21, 2022
1 parent 9ab2ab2 commit f598704
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
2 changes: 1 addition & 1 deletion packages/integrations/cloudflare/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Cloudflare has support for adding custom [headers](https://developers.cloudflare

### Custom `_routes.json`

By default, `@astrojs/cloudflare` will generate a `_routes.json` file that lists all files from your `dist/` folder in the `exclude` array. This will enable Cloudflare to serve files without a function invocation. Creating a custom `_routes.json` will override this automatic optimization and, if not configured manually, cause function invocations that will count against the request limits of your Cloudflare plan.
By default, `@astrojs/cloudflare` will generate a `_routes.json` file that lists all files from your `dist/` folder and redirects from the `_redirects` file in the `exclude` array. This will enable Cloudflare to serve files and process static redirects without a function invocation. Creating a custom `_routes.json` will override this automatic optimization and, if not configured manually, cause function invocations that will count against the request limits of your Cloudflare plan.

## Troubleshooting

Expand Down
49 changes: 44 additions & 5 deletions packages/integrations/cloudflare/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro';
import esbuild from 'esbuild';
import * as fs from 'fs';
import * as os from 'os';
import glob from 'tiny-glob';
import { fileURLToPath } from 'url';

Expand Down Expand Up @@ -139,23 +140,61 @@ export default function createIntegration(args?: Options): AstroIntegration {
.then((stat) => stat.isFile())
.catch(() => false);

// this creates a _routes.json, in case there is none present
// to enable cloudflare to handle static files directly (without calling the worker)
// this creates a _routes.json, in case there is none present to enable
// cloudflare to handle static files and support _redirects configuration
// (without calling the function)
if (!routesExists) {
const staticFiles = (
const staticPathList: Array<string> = (
await glob(`${fileURLToPath(_buildConfig.client)}/**/*`, {
cwd: fileURLToPath(_config.outDir),
filesOnly: true,
})
).filter((file) => cloudflareSpecialFiles.indexOf(file) < 0);
)
.filter((file: string) => cloudflareSpecialFiles.indexOf(file) < 0)
.map((file: string) => `/${file}`);

const redirectsExists = await fs.promises
.stat(new URL('./_redirects', _config.outDir))
.then((stat) => stat.isFile())
.catch(() => false);

// convert all redirect source paths into a list of routes
// and add them to the static path
if (redirectsExists) {
const redirects = (
await fs.promises.readFile(new URL('./_redirects', _config.outDir), 'utf-8')
)
.split(os.EOL)
.map((line) => {
const parts = line.split(' ');
if (parts.length < 2) {
return null;
} else {
// convert /products/:id to /products/*
return (
parts[0]
.replace(/\/:.*?(?=\/|$)/g, '/*')
// remove query params as they are not supported by cloudflare
.replace(/\?.*$/, '')
);
}
})
.filter(
(line, index, arr) => line !== null && arr.indexOf(line) === index
) as string[];

if (redirects.length > 0) {
staticPathList.push(...redirects);
}
}

await fs.promises.writeFile(
new URL('./_routes.json', _config.outDir),
JSON.stringify(
{
version: 1,
include: ['/*'],
exclude: staticFiles.map((file) => `/${file}`),
exclude: staticPathList,
},
null,
2
Expand Down

0 comments on commit f598704

Please sign in to comment.