Skip to content

Commit

Permalink
feat:wrangler dev with dynamic sites + miniflare assets plugin (#6564)
Browse files Browse the repository at this point in the history
* remove tests for assets plugin

* add assets plugin in miniflare

* fix AW behaviour with UW, add fixture and test

*add new assets-only fixture

* pr fixups 2 + changeset

* fixes after merge

* add config for router worker and remove no-op AW

---------

Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
  • Loading branch information
emily-shen and CarmenPopoviciu authored Aug 30, 2024
1 parent dff8d44 commit e8975a9
Show file tree
Hide file tree
Showing 58 changed files with 764 additions and 557 deletions.
7 changes: 7 additions & 0 deletions .changeset/mean-bulldogs-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"miniflare": patch
---

feat: add assets plugin to miniflare

New miniflare plugin for Workers + Assets, with relevant services imported from `workers-shared`.
23 changes: 23 additions & 0 deletions fixtures/workers-with-assets-only/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# workers-with-assets-only

`workers-with-assets-only` is a test fixture that showcases Workers with Assets. This particular fixture sets up an assets-only Workers project.

## dev

To start a dev session you can run

```
wrangler dev
```

or

```
wrangler dev --experimental-assets=./public
```

## Run tests

```
npm run test
```
19 changes: 19 additions & 0 deletions fixtures/workers-with-assets-only/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "workers-assets-only",
"private": true,
"scripts": {
"dev": "npx wrangler dev",
"test:ci": "vitest run",
"test:watch": "vitest",
"type:tests": "tsc -p ./tests/tsconfig.json"
},
"devDependencies": {
"@cloudflare/workers-tsconfig": "workspace:*",
"@cloudflare/workers-types": "^4.20240821.1",
"undici": "^5.28.4",
"wrangler": "workspace:*"
},
"volta": {
"extends": "../../package.json"
}
}
57 changes: 57 additions & 0 deletions fixtures/workers-with-assets-only/public/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Workers with Assets

Welcome to Workers + Assets YAY!

Please proceed with much excitement ^.^

.................
.......-++**********:.
..-+****++**********#:
...-+***+++====+********##=
....:=****+======+***********##+
....-****+======+*************###+
.:==+*+======+***************####=
....-===--=====++****************#####:
....:====-:::-==+******************#####+.
..-====:::::::+*******************#####*..
..-===-:::::::-==+*****************######=..
..-===-::::::-=======***************######*.
...-===-::::::-==========+************######*:.
...-===-::::::-==----========+*********#######:..
.-===-::::::--::::::::::-======+******#######-. .
..:====::::::-=:::-*####*-:::-=======+**#######-.
.:====-:::::-==:::*#########-::========+**#####-
..====-:::::-===-::###########*:::======*******+..
..=+====:::::=====::-############:::====+*******=...
....:=++====:::-======-::###########*:::===+*******-..
...........:-==+**+=++++=============-:::*#########-::===********:..
....--=+************====+++===============:::=*####*=:::-=+*******=..
.:*************###*=====++++================::::::::::-==********:..
..*****#############=======++++==========================+*******+...
...+****#############*==:::-===++++========================********-.
...+****###############+=::::=====+++++====================********+...
.=****################*=-:::-======+++++=================+********:..
..-****##################===:-=========++++++=============+********:..
.+***####################===========+***#++++++=========+********=..
.*###################+-.-=======+****##*==+++++++====+********=...
...-+#############*=...-++=====+****####+=====++++++*********+...
....-*######+:.....++++===******####==========+*######**+..
...+=.....:::-+++++******#####=========+***######*..
.......::::::=++******#####+========***********:...
....::::::...+*****######=======+**********##*.
..:::::....-*****######+=====+**********#####*.
...:::::...:******#####*+++++*********#########+.
..:::::...+*****######+++++++=.=###############:.
.:::::..-*****######-..-=++=..-##########***###..
....::::..=****######=....::::..:########******##*..
...::::..+***######-.....::::...*##***********###=..
..::::...-**####*:......::::...###************###-..
..:::......=##*:......:::::...+##*************###:
...::::...............:::::....+##*************####.
...::::::::::::::..:::::::......**************###-..
.::::::::::::::::::::::..... ...:***********###+....
..::::.......::::::...... ..:********###*:...
........ ...=******###=..
.=***###+..
..*####:...
........
1 change: 1 addition & 0 deletions fixtures/workers-with-assets-only/public/about/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>Learn more about Workers with Assets soon!</p>
1 change: 1 addition & 0 deletions fixtures/workers-with-assets-only/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Hello Workers + Assets World 🚀!</h1>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions fixtures/workers-with-assets-only/public/yay.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

.----------------. .----------------. .----------------.
| .--------------. || .--------------. || .--------------. |
| | ____ ____ | || | __ | || | ____ ____ | |
| | |_ _||_ _| | || | / \ | || | |_ _||_ _| | |
| | \ \ / / | || | / /\ \ | || | \ \ / / | |
| | \ \/ / | || | / ____ \ | || | \ \/ / | |
| | _| |_ | || | _/ / \ \_ | || | _| |_ | |
| | |______| | || ||____| |____|| || | |______| | |
| | | || | | || | | |
| '--------------' || '--------------' || '--------------' |
'----------------' '----------------' '----------------'
155 changes: 155 additions & 0 deletions fixtures/workers-with-assets-only/tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { resolve } from "node:path";
import { fetch } from "undici";
import { afterAll, beforeAll, describe, it } from "vitest";
import { runWranglerDev } from "../../shared/src/run-wrangler-long-lived";

describe("[Workers + Assets] static-assets only site`", () => {
let ip: string, port: number, stop: (() => Promise<unknown>) | undefined;

beforeAll(async () => {
({ ip, port, stop } = await runWranglerDev(resolve(__dirname, ".."), [
"--port=0",
"--inspector-port=0",
]));
});

afterAll(async () => {
await stop?.();
});

it("should respond with static asset content", async ({ expect }) => {
let response = await fetch(`http://${ip}:${port}/index.html`);
let text = await response.text();
expect(response.status).toBe(200);
expect(text).toContain(`<h1>Hello Workers + Assets World 🚀!</h1>`);

response = await fetch(`http://${ip}:${port}/about/index.html`);
text = await response.text();
expect(response.status).toBe(200);
expect(text).toContain(`<p>Learn more about Workers with Assets soon!</p>`);
});

it("should not resolve '/' to '/index.html' ", async ({ expect }) => {
let response = await fetch(`http://${ip}:${port}/`);
expect(response.status).toBe(404);
});

it("should 404 if asset is not found in the asset manifest", async ({
expect,
}) => {
let response = await fetch(`http://${ip}:${port}/hello.html`);
expect(response.status).toBe(404);

response = await fetch(`http://${ip}:${port}/hello.txt`);
expect(response.status).toBe(404);
});

it("should handle content types correctly", async ({ expect }) => {
let response = await fetch(`http://${ip}:${port}/index.html`);
let text = await response.text();
expect(response.status).toBe(200);
expect(response.headers.get("Content-Type")).toBe(
"text/html; charset=utf-8"
);

response = await fetch(`http://${ip}:${port}/README.md`);
text = await response.text();
expect(response.status).toBe(200);
expect(response.headers.get("Content-Type")).toBe(
"text/markdown; charset=utf-8"
);
expect(text).toContain(`Welcome to Workers + Assets YAY!`);

response = await fetch(`http://${ip}:${port}/yay.txt`);
text = await response.text();
expect(response.status).toBe(200);
expect(response.headers.get("Content-Type")).toBe(
"text/plain; charset=utf-8"
);
expect(text).toContain(`.----------------.`);

response = await fetch(`http://${ip}:${port}/lava-lamps.jpg`);
expect(response.status).toBe(200);
expect(response.headers.get("Content-Type")).toBe("image/jpeg");
});

it("should return 405 for non-GET requests if asset route exists", async ({
expect,
}) => {
// as per https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
// excl. TRACE and CONNECT which are not supported

let response = await fetch(`http://${ip}:${port}/index.html`, {
method: "HEAD",
});
expect(response.status).toBe(405);
expect(response.statusText).toBe("Method Not Allowed");

response = await fetch(`http://${ip}:${port}/index.html`, {
method: "POST",
});
expect(response.status).toBe(405);
expect(response.statusText).toBe("Method Not Allowed");

response = await fetch(`http://${ip}:${port}/index.html`, {
method: "PUT",
});
expect(response.status).toBe(405);
expect(response.statusText).toBe("Method Not Allowed");

response = await fetch(`http://${ip}:${port}/index.html`, {
method: "DELETE",
});
expect(response.status).toBe(405);
expect(response.statusText).toBe("Method Not Allowed");

response = await fetch(`http://${ip}:${port}/index.html`, {
method: "OPTIONS",
});
expect(response.status).toBe(405);
expect(response.statusText).toBe("Method Not Allowed");

response = await fetch(`http://${ip}:${port}/index.html`, {
method: "PATCH",
});
expect(response.status).toBe(405);
expect(response.statusText).toBe("Method Not Allowed");
});

it("should return 404 for non-GET requests if asset route does not exist", async ({
expect,
}) => {
// as per https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
// excl. TRACE and CONNECT which are not supported

let response = await fetch(`http://${ip}:${port}/nope.html`, {
method: "HEAD",
});
expect(response.status).toBe(404);

response = await fetch(`http://${ip}:${port}/nope.html`, {
method: "POST",
});
expect(response.status).toBe(404);

response = await fetch(`http://${ip}:${port}/nope.html`, {
method: "PUT",
});
expect(response.status).toBe(404);

response = await fetch(`http://${ip}:${port}/nope.html`, {
method: "DELETE",
});
expect(response.status).toBe(404);

response = await fetch(`http://${ip}:${port}/nope.html`, {
method: "OPTIONS",
});
expect(response.status).toBe(404);

response = await fetch(`http://${ip}:${port}/nope.html`, {
method: "PATCH",
});
expect(response.status).toBe(404);
});
});
7 changes: 7 additions & 0 deletions fixtures/workers-with-assets-only/tests/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@cloudflare/workers-tsconfig/tsconfig.json",
"compilerOptions": {
"types": ["node"]
},
"include": ["**/*.ts", "../../../node-types.d.ts"]
}
13 changes: 13 additions & 0 deletions fixtures/workers-with-assets-only/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"lib": ["ES2020"],
"types": ["@cloudflare/workers-types"],
"moduleResolution": "node",
"noEmit": true,
"skipLibCheck": true
},
"include": ["**/*.ts"],
"exclude": ["tests"]
}
5 changes: 5 additions & 0 deletions fixtures/workers-with-assets-only/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name = "worker-with-asset-only"
compatibility_date = "2024-01-01"

[experimental_assets]
directory = "./public"
4 changes: 2 additions & 2 deletions fixtures/workers-with-assets/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# workers-with-assets
# workers-assets-with-user-worker"

`workers-with-assets` is a test fixture that showcases Workers with Assets. This particular fixture sets up an assets-only Workers project.
`workers-assets-with-user-worker"` is a test fixture that showcases Workers with Assets. This particular fixture sets up a User Worker, assets, and a binding from the user Worker to the assets.

## dev

Expand Down
2 changes: 1 addition & 1 deletion fixtures/workers-with-assets/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "assets-worker",
"name": "workers-assets-with-user-worker",
"private": true,
"scripts": {
"check:type": "tsc",
Expand Down
1 change: 1 addition & 0 deletions fixtures/workers-with-assets/public/binding.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>✨This is from a user Worker binding✨</h1>
18 changes: 18 additions & 0 deletions fixtures/workers-with-assets/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface Env {
// Example binding to a Service. Learn more at https://developers.cloudflare.com/workers/runtime-apis/service-bindings/
ASSETS: Fetcher;
}

export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/assets-binding") {
return await env.ASSETS.fetch(new URL("binding.html", request.url));
}
// 404s from the Asset Worker will return this:
return new Response(
"There were no assets at this route! Hello from the user Worker instead!" +
`\n${new Date()}`
);
},
};
Loading

0 comments on commit e8975a9

Please sign in to comment.