Skip to content

Commit

Permalink
fix(wrangler): use require.resolve to resolve unenv path (#7804)
Browse files Browse the repository at this point in the history
vicb authored Jan 17, 2025
1 parent facb3ff commit 16a9460
Showing 2 changed files with 30 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/little-pugs-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": patch
---

fix(wrangler): use require.resolve to resolve unenv path
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { builtinModules } from "node:module";
import nodePath from "node:path";
import dedent from "ts-dedent";
import { cloudflare, defineEnv } from "unenv";
import { cloudflare, env, nodeless } from "unenv";
import { getBasePath } from "../../paths";
import type { Plugin, PluginBuild } from "esbuild";

@@ -11,31 +11,17 @@ const REQUIRED_UNENV_ALIAS_NAMESPACE = "required-unenv-alias";
/**
* ESBuild plugin to apply the unenv preset.
*
* @param unenvResolvePaths Root paths used to resolve absolute paths.
* @param _unenvResolvePaths Root paths used to resolve absolute paths.
* @returns ESBuild plugin
*/
export function nodejsHybridPlugin(unenvResolvePaths?: string[]): Plugin {
// Get the resolved environment.
const { env } = defineEnv({
nodeCompat: true,
presets: [cloudflare],
resolve: {
paths: unenvResolvePaths,
},
});
const { alias, inject, external } = env;
// Get the unresolved alias.
const unresolvedAlias = defineEnv({
nodeCompat: true,
presets: [cloudflare],
resolve: false,
}).env.alias;
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, unresolvedAlias, alias, external);
handleUnenvAliasedPackages(build, alias, external);
handleNodeJSGlobals(build, inject);
},
};
@@ -111,26 +97,38 @@ function handleRequireCallsToNodeJSBuiltins(build: PluginBuild) {
* Handles aliased NPM packages.
*
* @param build ESBuild PluginBuild.
* @param unresolvedAlias Unresolved aliases from the presets.
* @param alias Aliases resolved to absolute paths.
* @param external external modules.
*/
function handleUnenvAliasedPackages(
build: PluginBuild,
unresolvedAlias: Record<string, string>,
alias: Record<string, string>,
external: string[]
) {
const UNENV_ALIAS_RE = new RegExp(`^(${Object.keys(alias).join("|")})$`);
// 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("|")})$`
);

build.onResolve({ filter: UNENV_ALIAS_RE }, (args) => {
const unresolved = unresolvedAlias[args.path];
const unresolvedAlias = alias[args.path];
// Convert `require()` calls for NPM packages to a virtual ES Module that can be imported avoiding the require calls.
// Note: Does not apply to Node.js packages that are handled in `handleRequireCallsToNodeJSBuiltins`
if (
args.kind === "require-call" &&
(unresolved.startsWith("unenv/runtime/npm/") ||
unresolved.startsWith("unenv/runtime/mock/"))
(unresolvedAlias.startsWith("unenv/runtime/npm/") ||
unresolvedAlias.startsWith("unenv/runtime/mock/"))
) {
return {
path: args.path,
@@ -140,8 +138,8 @@ function handleUnenvAliasedPackages(

// Resolve the alias to its absolute path and potentially mark it as external
return {
path: alias[args.path],
external: external.includes(unresolved),
path: aliasAbsolute[args.path],
external: external.includes(unresolvedAlias),
};
});

0 comments on commit 16a9460

Please sign in to comment.