Skip to content

Commit

Permalink
Prioritise workerd condition when bundling (#2629)
Browse files Browse the repository at this point in the history
* Prioritise `workerd` condition when bundling

Ref: https://runtime-keys.proposal.wintercg.org/#workerd

* fixup! Prioritise `workerd` condition when bundling

* fixup! Prioritise `workerd` condition when bundling

* fixup! Prioritise `workerd` condition when bundling
  • Loading branch information
mrbbot authored Jan 27, 2023
1 parent a235135 commit 151733e
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 1 deletion.
10 changes: 10 additions & 0 deletions .changeset/chilly-donuts-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"wrangler": minor
---

Prefer the `workerd` `exports` condition when bundling.

This can be used to build isomorphic libraries that have different implementations depending on the JavaScript runtime they're running in.
When bundling, Wrangler will try to load the [`workerd` key](https://runtime-keys.proposal.wintercg.org/#workerd).
This is the [standard key](https://runtime-keys.proposal.wintercg.org/#workerd) for the Cloudflare Workers runtime.
Learn more about the [conditional `exports` field here](https://nodejs.org/api/packages.html#conditional-exports).
7 changes: 7 additions & 0 deletions fixtures/isomorphic-random-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Isomorphic Package Example

This package implements an isomorphic library that generates cryptographically-strong pseudorandom numbers.
What this package does isn't really important here, the key part is the [`package.json`](./package.json)'s `exports` field.
Conditional exports provide a way to load a different file depending on where the module is being imported from.
By default, Wrangler will try to look for a [**`workerd`** key](https://runtime-keys.proposal.wintercg.org/#workerd).
This allows you as a library developer to implement different behaviour for different JavaScript runtimes.
10 changes: 10 additions & 0 deletions fixtures/isomorphic-random-example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "isomorphic-random-example",
"version": "0.0.1",
"private": true,
"description": "Isomorphic secure-random library, demonstrating `exports` use with Workers",
"exports": {
"node": "./src/node.js",
"workerd": "./src/workerd.mjs"
}
}
5 changes: 5 additions & 0 deletions fixtures/isomorphic-random-example/src/node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const crypto = require("node:crypto");

module.exports.randomBytes = function (length) {
return new Uint8Array(crypto.randomBytes(length));
};
3 changes: 3 additions & 0 deletions fixtures/isomorphic-random-example/src/workerd.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function randomBytes(length) {
return crypto.getRandomValues(new Uint8Array(length));
}
12 changes: 12 additions & 0 deletions fixtures/worker-app/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { now } from "./dep";
import { randomBytes } from "isomorphic-random-example";

/** @param {Uint8Array} array */
function hexEncode(array) {
return Array.from(array)
.map((x) => x.toString(16).padStart(2, "0"))
.join("");
}

export default {
async fetch(request) {
const { pathname } = new URL(request.url);
if (pathname === "/random") return new Response(hexEncode(randomBytes(8)));

console.log(
request.method,
request.url,
Expand Down
6 changes: 6 additions & 0 deletions fixtures/worker-app/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@ describe.concurrent("'wrangler dev' correctly renders pages", () => {
const text = await response.text();
expect(text).toContain(`http://${ip}:${port}/`);
});

it("uses `workerd` condition when bundling", async ({ expect }) => {
const response = await fetch(`http://${ip}:${port}/random`);
const text = await response.text();
expect(text).toMatch(/[0-9a-f]{16}/); // 8 hex bytes
});
});
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/wrangler/src/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ export async function bundleWorker(
sourceRoot: destination,
minify,
metafile: true,
conditions: ["worker", "browser"],
conditions: ["workerd", "worker", "browser"],
...(process.env.NODE_ENV && {
define: {
// use process.env["NODE_ENV" + ""] so that esbuild doesn't replace it
Expand Down

0 comments on commit 151733e

Please sign in to comment.