Skip to content

Commit

Permalink
feat: update Wrangler to use the new Cloudflare unenv preset
Browse files Browse the repository at this point in the history
  • Loading branch information
petebacondarwin committed Feb 6, 2025
1 parent f345fe7 commit 18e7f84
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 47 deletions.
1 change: 1 addition & 0 deletions packages/wrangler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
},
"dependencies": {
"@cloudflare/kv-asset-handler": "workspace:*",
"@cloudflare/unenv-preset": "~1.1.1",
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
"@esbuild-plugins/node-modules-polyfill": "0.2.2",
"blake3-wasm": "2.1.5",
Expand Down
2 changes: 1 addition & 1 deletion packages/wrangler/src/__tests__/deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10136,7 +10136,7 @@ addEventListener('fetch', event => {});`
)
)
).resolves.toMatchInlineSnapshot(`
"X [ERROR] Unexpected external import of \\"node:net\\", \\"node:stream\\", \\"node:timers/promises\\", and \\"node:tty\\".
"X [ERROR] Unexpected external import of \\"node:net\\", \\"node:stream\\", and \\"node:tty\\".
Your worker has no default export, which means it is assumed to be a Service Worker format Worker.
Did you mean to create a ES Module format Worker?
If so, try adding \`export default { ... }\` in your entry-point.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
import { builtinModules } from "node:module";
import nodePath from "node:path";
import { cloudflare } from "@cloudflare/unenv-preset";
import dedent from "ts-dedent";
import { cloudflare, env, nodeless } from "unenv";
import { defineEnv } from "unenv";
import { getBasePath } from "../../paths";
import type { Plugin, PluginBuild } from "esbuild";

const REQUIRED_NODE_BUILT_IN_NAMESPACE = "node-built-in-modules";
const REQUIRED_UNENV_ALIAS_NAMESPACE = "required-unenv-alias";

const preset = defineEnv({
nodeCompat: true,
presets: [cloudflare],
});
const resolvedAliases = defineEnv({
nodeCompat: true,
presets: [cloudflare],
resolve: true,
}).env.alias;

/**
* ESBuild plugin to apply the unenv preset.
*
* @param _unenvResolvePaths Root paths used to resolve absolute paths.
* @returns ESBuild plugin
*/
export function nodejsHybridPlugin(_unenvResolvePaths?: string[]): Plugin {
const { alias, inject, external } = env(nodeless, cloudflare);
return {
name: "hybrid-nodejs_compat",
setup(build) {
errorOnServiceWorkerFormat(build);
handleRequireCallsToNodeJSBuiltins(build);
handleUnenvAliasedPackages(build, alias, external);
handleNodeJSGlobals(build, inject);
handleUnenvAliasedPackages(build, preset.env.alias, preset.env.external);
handleNodeJSGlobals(build, preset.env.inject);
},
};
}
Expand Down Expand Up @@ -105,20 +115,8 @@ function handleUnenvAliasedPackages(
alias: Record<string, string>,
external: string[]
) {
// esbuild expects alias paths to be absolute
const aliasAbsolute: Record<string, string> = {};
for (const [module, unresolvedAlias] of Object.entries(alias)) {
try {
aliasAbsolute[module] = require
.resolve(unresolvedAlias)
.replace(/\.cjs$/, ".mjs");
} catch (e) {
// this is an alias for package that is not installed in the current app => ignore
}
}

const UNENV_ALIAS_RE = new RegExp(
`^(${Object.keys(aliasAbsolute).join("|")})$`
`^(${Object.keys(resolvedAliases).join("|")})$`
);

build.onResolve({ filter: UNENV_ALIAS_RE }, (args) => {
Expand All @@ -138,7 +136,7 @@ function handleUnenvAliasedPackages(

// Resolve the alias to its absolute path and potentially mark it as external
return {
path: aliasAbsolute[args.path],
path: resolvedAliases[args.path],
external: external.includes(unresolvedAlias),
};
});
Expand Down
67 changes: 39 additions & 28 deletions pnpm-lock.yaml

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

0 comments on commit 18e7f84

Please sign in to comment.