Skip to content

Commit

Permalink
Update and modernize adapter-cloudflare-workers
Browse files Browse the repository at this point in the history
  • Loading branch information
pzuraq committed Apr 11, 2022
1 parent f0df782 commit 9b8a9a4
Show file tree
Hide file tree
Showing 11 changed files with 283 additions and 152 deletions.
5 changes: 5 additions & 0 deletions .changeset/tidy-paws-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-cloudflare-workers': patch
---

Update adapter to use modules API and match the standard adapter-cloudflare implementation more closely
3 changes: 2 additions & 1 deletion packages/adapter-cloudflare-workers/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.DS_Store
node_modules
target
target
/files
37 changes: 27 additions & 10 deletions packages/adapter-cloudflare-workers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,19 @@ export default {

**You will need [Wrangler](https://developers.cloudflare.com/workers/cli-wrangler/install-update) installed on your system**

This adapter expects to find a [wrangler.toml](https://developers.cloudflare.com/workers/platform/sites/configuration) file in the project root. It will determine where to write static assets and the worker based on the `site.bucket` and `site.entry-point` settings.
This adapter expects to find a [wrangler.toml](https://developers.cloudflare.com/workers/platform/sites/configuration) file in the project root. It will determine where to write static assets and the worker based on the `site.bucket` and `build.upload` settings. These values must be set to the following:

Generate this file using `wrangler` from your project directory
```toml
[build.upload]
format = "modules"
dir = "./.svelte-kit/cloudflare"
main = "./_worker.mjs"

[site]
bucket = "./.svelte-kit/cloudflare-bucket"
```

To get started, generate this file using `wrangler` from your project directory

```sh
wrangler init --site my-site-name
Expand All @@ -48,24 +58,31 @@ Now you should get some details from Cloudflare. You should get your:

Get them by visiting your [Cloudflare dashboard](https://dash.cloudflare.com) and click on any domain. There, you can scroll down and on the left, you can see your details under **API**.

Then configure your sites build directory and your account-details in the config file:
Then configure your account-details in the config file:

```toml
account_id = 'YOUR ACCOUNT_ID'
zone_id = 'YOUR ZONE_ID' # optional, if you don't specify this a workers.dev subdomain will be used.
site = {bucket = "./build", entry-point = "./workers-site"}

name = "<your-site-name>"
type = "javascript"
account_id = "<your-account-id>"
workers_dev = true
route = ""
zone_id = ""

compatibility_date = "2022-02-09"

[build]
# Assume it's already been built. You can make this "npm run build" to ensure a build before publishing
command = ""

# All values below here are required by adapter-cloudflare-workers and should not change
[build.upload]
format = "service-worker"
```
format = "modules"
dir = "./.svelte-kit/cloudflare"
main = "./_worker.mjs"

It's recommended that you add the `build` and `workers-site` folders (or whichever other folders you specify) to your `.gitignore`.
[site]
bucket = "./.svelte-kit/cloudflare-bucket"
```

Now, log in with wrangler:

Expand Down
10 changes: 4 additions & 6 deletions packages/adapter-cloudflare-workers/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ declare module 'MANIFEST' {
import { SSRManifest } from '@sveltejs/kit';

export const manifest: SSRManifest;
export const prerendered: Set<string>;
export const prerendered: Map<string, { file: string }>;
}

declare abstract class FetchEvent extends Event {
readonly request: Request;
respondWith(promise: Response | Promise<Response>): void;
passThroughOnException(): void;
waitUntil(promise: Promise<any>): void;
declare module '__STATIC_CONTENT_MANIFEST' {
const value: string;
export = value;
}
61 changes: 0 additions & 61 deletions packages/adapter-cloudflare-workers/files/entry.js

This file was deleted.

194 changes: 126 additions & 68 deletions packages/adapter-cloudflare-workers/index.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import { existsSync, readFileSync, writeFileSync } from 'fs';
import { posix } from 'path';
import { execSync } from 'child_process';
import esbuild from 'esbuild';
import * as esbuild from 'esbuild';
import toml from '@iarna/toml';
import { fileURLToPath } from 'url';

/** @type {import('.')} */
export default function () {
export default function (options = {}) {
return {
name: '@sveltejs/adapter-cloudflare-workers',

async adapt(builder) {
const { site } = validate_config(builder);

// @ts-ignore
const { bucket } = site;
validate_config(builder);

// @ts-ignore
const entrypoint = site['entry-point'] || 'workers-site';

const files = fileURLToPath(new URL('./files', import.meta.url).href);
const tmp = builder.getBuildDirectory('cloudflare-workers-tmp');
const dest = builder.getBuildDirectory('cloudflare');
const bucket = builder.getBuildDirectory('cloudflare-bucket');
const tmp = builder.getBuildDirectory('cloudflare-tmp');

builder.rimraf(dest);
builder.rimraf(bucket);
builder.rimraf(entrypoint);
builder.rimraf(tmp);

builder.mkdirp(tmp);

builder.writeStatic(bucket);
builder.writeClient(bucket);
builder.writePrerendered(bucket);

const relativePath = posix.relative(tmp, builder.getServerDirectory());

builder.log.info('Installing worker dependencies...');
builder.copy(`${files}/_package.json`, `${tmp}/package.json`);
Expand All @@ -33,83 +38,136 @@ export default function () {
builder.log.info(stdout.toString());

builder.log.minor('Generating worker...');
const relativePath = posix.relative(tmp, builder.getServerDirectory());

builder.copy(`${files}/entry.js`, `${tmp}/entry.js`, {
writeFileSync(
`${tmp}/manifest.js`,
`export const manifest = ${builder.generateManifest({
relativePath
})};\n\nexport const prerendered = new Map(${JSON.stringify(
Array.from(builder.prerendered.pages.entries())
)});\n`
);

builder.copy(`${files}/worker.js`, `${tmp}/_worker.js`, {
replace: {
SERVER: `${relativePath}/index.js`,
MANIFEST: './manifest.js'
}
});

writeFileSync(
`${tmp}/manifest.js`,
`export const manifest = ${builder.generateManifest({
relativePath
})};\n\nexport const prerendered = new Set(${JSON.stringify(builder.prerendered.paths)});\n`
);
const external = ['__STATIC_CONTENT_MANIFEST'];

if (options.external) {
external.push(...options.external);
}

await esbuild.build({
entryPoints: [`${tmp}/entry.js`],
outfile: `${entrypoint}/index.js`,
bundle: true,
target: 'es2020',
platform: 'browser'
platform: 'browser',
...options,
entryPoints: [`${tmp}/_worker.js`],
external,
outfile: `${dest}/_worker.mjs`,
allowOverwrite: true,
format: 'esm',
bundle: true
});

writeFileSync(`${entrypoint}/package.json`, JSON.stringify({ main: 'index.js' }));

builder.log.minor('Copying assets...');
builder.writeClient(bucket);
builder.writeStatic(bucket);
builder.writePrerendered(bucket);
}
};
}

/** @param {import('@sveltejs/kit').Builder} builder */
function validate_config(builder) {
if (existsSync('wrangler.toml')) {
let wrangler_config;

try {
wrangler_config = toml.parse(readFileSync('wrangler.toml', 'utf-8'));
} catch (err) {
err.message = `Error parsing wrangler.toml: ${err.message}`;
throw err;
}
if (!existsSync('wrangler.toml')) {
builder.log.error(
'Consult https://developers.cloudflare.com/workers/platform/sites/configuration on how to setup your site'
);

builder.log(
`
Sample wrangler.toml:
name = "<your-site-name>"
type = "javascript"
account_id = "<your-account-id>"
workers_dev = true
route = ""
zone_id = ""
compatibility_date = "2022-02-09"
[build]
# Assume it's already been built. You can make this "npm run build" to ensure a build before publishing
command = ""
# All values below here are required by adapter-cloudflare-workers and should not change
[build.upload]
format = "modules"
dir = "./.svelte-kit/cloudflare"
main = "./_worker.mjs"
[site]
bucket = "./.svelte-kit/cloudflare-bucket"`
.replace(/^\t+/gm, '')
.trim()
);

throw new Error('Missing a wrangler.toml file');
}

let wrangler_config;

try {
wrangler_config = toml.parse(readFileSync('wrangler.toml', 'utf-8'));
} catch (err) {
err.message = `Error parsing wrangler.toml: ${err.message}`;
throw err;
}

// @ts-ignore
if (!wrangler_config.site || wrangler_config.site.bucket !== './.svelte-kit/cloudflare-bucket') {
throw new Error(
'You must specify site.bucket in wrangler.toml, and it must equal "./.svelte-kit/cloudflare-bucket"'
);
}

// @ts-ignore
if (
// @ts-ignore
if (!wrangler_config.site || !wrangler_config.site.bucket) {
throw new Error(
'You must specify site.bucket in wrangler.toml. Consult https://developers.cloudflare.com/workers/platform/sites/configuration'
);
}
!wrangler_config.build ||
// @ts-ignore
!wrangler_config.build.upload ||
// @ts-ignore
wrangler_config.build.upload.format !== 'modules'
) {
throw new Error(
'You must specify build.upload.format in wrangler.toml, and it must equal "modules"'
);
}

return wrangler_config;
if (
// @ts-ignore
!wrangler_config.build ||
// @ts-ignore
!wrangler_config.build.upload ||
// @ts-ignore
wrangler_config.build.upload.dir !== './.svelte-kit/cloudflare'
) {
throw new Error(
'You must specify build.upload.dir in wrangler.toml, and it must equal "./.svelte-kit/cloudflare"'
);
}

builder.log.error(
'Consult https://developers.cloudflare.com/workers/platform/sites/configuration on how to setup your site'
);

builder.log(
`
Sample wrangler.toml:
name = "<your-site-name>"
type = "javascript"
account_id = "<your-account-id>"
workers_dev = true
route = ""
zone_id = ""
[site]
bucket = "./.cloudflare/assets"
entry-point = "./.cloudflare/worker"`
.replace(/^\t+/gm, '')
.trim()
);

throw new Error('Missing a wrangler.toml file');
if (
// @ts-ignore
!wrangler_config.build ||
// @ts-ignore
!wrangler_config.build.upload ||
// @ts-ignore
wrangler_config.build.upload.main !== './_worker.mjs'
) {
throw new Error(
'You must specify build.upload.main in wrangler.toml, and it must equal "./_worker.mjs"'
);
}
}
Loading

0 comments on commit 9b8a9a4

Please sign in to comment.