From 6403e41b809a20db59ecfd55362368926750c62d Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Tue, 17 Dec 2024 13:08:09 +0100 Subject: [PATCH] feat: add support for custom unenv resolve path (#7522) feat(wrangler): add support for custom unenv resolve path Introduce `WRANGLER_UNENV_RESOLVE_PATHS` to specify resolve paths for unenv. Co-authored-by: Pete Bacon Darwin --- .changeset/fluffy-eggs-film.md | 11 +++++++++++ packages/wrangler/src/deployment-bundle/bundle.ts | 8 +++++++- .../esbuild-plugins/hybrid-nodejs-compat.ts | 14 +++++++++++--- .../esbuild-plugins/nodejs-plugins.ts | 10 ++++++++-- .../wrangler/src/environment-variables/factory.ts | 1 + .../src/environment-variables/misc-variables.ts | 13 +++++++++++++ 6 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 .changeset/fluffy-eggs-film.md diff --git a/.changeset/fluffy-eggs-film.md b/.changeset/fluffy-eggs-film.md new file mode 100644 index 000000000000..d246cce13bb7 --- /dev/null +++ b/.changeset/fluffy-eggs-film.md @@ -0,0 +1,11 @@ +--- +"wrangler": minor +--- + +feat(wrangler): allow overriding the unenv preset. + +By default wrangler uses the bundled unenv preset. + +Setting `WRANGLER_UNENV_RESOLVE_PATHS` allow to use another version of the preset. +Those paths are used when resolving the unenv module identifiers to absolute paths. +This can be used to test a development version. diff --git a/packages/wrangler/src/deployment-bundle/bundle.ts b/packages/wrangler/src/deployment-bundle/bundle.ts index c5f920d03d0a..bb35d4519de8 100644 --- a/packages/wrangler/src/deployment-bundle/bundle.ts +++ b/packages/wrangler/src/deployment-bundle/bundle.ts @@ -5,6 +5,7 @@ import * as esbuild from "esbuild"; import { getBuildConditionsFromEnv, getBuildPlatformFromEnv, + getUnenvResolvePathsFromEnv, } from "../environment-variables/misc-variables"; import { UserError } from "../errors"; import { getFlag } from "../experimental-flags"; @@ -390,6 +391,8 @@ export async function bundleWorker( }, }; + const unenvResolvePaths = getUnenvResolvePathsFromEnv()?.split(","); + const buildOptions: esbuild.BuildOptions & { metafile: true } = { // Don't use entryFile here as the file may have been changed when applying the middleware entryPoints: [entry.file], @@ -435,7 +438,10 @@ export async function bundleWorker( plugins: [ aliasPlugin, moduleCollector.plugin, - ...getNodeJSCompatPlugins(nodejsCompatMode ?? null), + ...getNodeJSCompatPlugins({ + mode: nodejsCompatMode ?? null, + unenvResolvePaths, + }), cloudflareInternalPlugin, buildResultPlugin, ...(plugins || []), diff --git a/packages/wrangler/src/deployment-bundle/esbuild-plugins/hybrid-nodejs-compat.ts b/packages/wrangler/src/deployment-bundle/esbuild-plugins/hybrid-nodejs-compat.ts index 55a2fbcea2c7..052039086953 100644 --- a/packages/wrangler/src/deployment-bundle/esbuild-plugins/hybrid-nodejs-compat.ts +++ b/packages/wrangler/src/deployment-bundle/esbuild-plugins/hybrid-nodejs-compat.ts @@ -8,12 +8,20 @@ import type { Plugin, PluginBuild } from "esbuild"; const REQUIRED_NODE_BUILT_IN_NAMESPACE = "node-built-in-modules"; const REQUIRED_UNENV_ALIAS_NAMESPACE = "required-unenv-alias"; -export const nodejsHybridPlugin: () => Plugin = () => { +/** + * 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 { // Get the resolved environment. const { env } = defineEnv({ nodeCompat: true, presets: [cloudflare], - resolve: true, + resolve: { + paths: unenvResolvePaths, + }, }); const { alias, inject, external } = env; // Get the unresolved alias. @@ -31,7 +39,7 @@ export const nodejsHybridPlugin: () => Plugin = () => { handleNodeJSGlobals(build, inject); }, }; -}; +} const NODEJS_MODULES_RE = new RegExp(`^(node:)?(${builtinModules.join("|")})$`); diff --git a/packages/wrangler/src/deployment-bundle/esbuild-plugins/nodejs-plugins.ts b/packages/wrangler/src/deployment-bundle/esbuild-plugins/nodejs-plugins.ts index b59d8fa190d7..30448b347f9f 100644 --- a/packages/wrangler/src/deployment-bundle/esbuild-plugins/nodejs-plugins.ts +++ b/packages/wrangler/src/deployment-bundle/esbuild-plugins/nodejs-plugins.ts @@ -10,7 +10,13 @@ import type { NodeJSCompatMode } from "miniflare"; /** * Returns the list of ESBuild plugins to use for a given compat mode. */ -export function getNodeJSCompatPlugins(mode: NodeJSCompatMode): Plugin[] { +export function getNodeJSCompatPlugins({ + mode, + unenvResolvePaths, +}: { + mode: NodeJSCompatMode; + unenvResolvePaths?: string[]; +}): Plugin[] { switch (mode) { case "als": return [asyncLocalStoragePlugin, nodejsCompatPlugin(mode)]; @@ -24,7 +30,7 @@ export function getNodeJSCompatPlugins(mode: NodeJSCompatMode): Plugin[] { case "v1": return [nodejsCompatPlugin(mode)]; case "v2": - return [nodejsHybridPlugin()]; + return [nodejsHybridPlugin(unenvResolvePaths)]; case null: return [nodejsCompatPlugin(mode)]; } diff --git a/packages/wrangler/src/environment-variables/factory.ts b/packages/wrangler/src/environment-variables/factory.ts index 91d481ed3a6f..8a2124386ff7 100644 --- a/packages/wrangler/src/environment-variables/factory.ts +++ b/packages/wrangler/src/environment-variables/factory.ts @@ -25,6 +25,7 @@ type VariableNames = | "WRANGLER_CI_MATCH_TAG" | "WRANGLER_BUILD_CONDITIONS" | "WRANGLER_BUILD_PLATFORM" + | "WRANGLER_UNENV_RESOLVE_PATHS" | "WRANGLER_REGISTRY_PATH"; type DeprecatedNames = diff --git a/packages/wrangler/src/environment-variables/misc-variables.ts b/packages/wrangler/src/environment-variables/misc-variables.ts index a19426a316c0..3af8754f4664 100644 --- a/packages/wrangler/src/environment-variables/misc-variables.ts +++ b/packages/wrangler/src/environment-variables/misc-variables.ts @@ -126,6 +126,19 @@ export const getBuildPlatformFromEnv = getEnvironmentVariableFactory({ variableName: "WRANGLER_BUILD_PLATFORM", }); +/** + * `WRANGLER_UNENV_RESOLVE_PATHS` lists the paths used to resolve unenv. + * + * Note: multiple comma separated paths can be specified. + * + * By default wrangler uses the unenv preset version installed from the package.json. + * + * Setting root paths allow to use a different version of the preset. + */ +export const getUnenvResolvePathsFromEnv = getEnvironmentVariableFactory({ + variableName: "WRANGLER_UNENV_RESOLVE_PATHS", +}); + /** * `WRANGLER_REGISTRY_PATH` specifies the file based dev registry folder */