diff --git a/.changeset/cuddly-rules-rest.md b/.changeset/cuddly-rules-rest.md index 6d102be5778e3..2b61ef0d788d3 100644 --- a/.changeset/cuddly-rules-rest.md +++ b/.changeset/cuddly-rules-rest.md @@ -1,5 +1,5 @@ --- -"wrangler": patch +"wrangler": minor --- feat: Add support for the undocumented `_worker.js/` directory in Pages diff --git a/fixtures/local-mode-tests/package.json b/fixtures/local-mode-tests/package.json index 08c068ae8bf18..cb065cdd3b988 100644 --- a/fixtures/local-mode-tests/package.json +++ b/fixtures/local-mode-tests/package.json @@ -9,25 +9,8 @@ "main": "index.js", "scripts": { "check:type": "tsc && tsc -p tests/tsconfig.json", - "test": "cross-env NODE_ENV=local-testing NODE_OPTIONS=--experimental-vm-modules npx jest --forceExit", - "test:ci": "cross-env NODE_ENV=local-testing NODE_OPTIONS=--experimental-vm-modules npx jest --forceExit" - }, - "jest": { - "restoreMocks": true, - "testRegex": ".*.(test|spec)\\.[jt]sx?$", - "testTimeout": 30000, - "transform": { - "^.+\\.c?(t|j)sx?$": [ - "esbuild-jest", - { - "sourcemap": true - } - ] - }, - "transformIgnorePatterns": [ - "node_modules/(?!find-up|locate-path|p-locate|p-limit|p-timeout|p-queue|yocto-queue|path-exists|execa|strip-final-newline|npm-run-path|path-key|onetime|mimic-fn|human-signals|is-stream|get-port|supports-color|pretty-bytes)", - "wrangler-dist/cli.js" - ] + "test": "npx vitest", + "test:ci": "npx vitest" }, "devDependencies": { "@cloudflare/workers-types": "^4.20221111.1", diff --git a/fixtures/pages-workerjs-directory/public/_worker.js/add.wasm b/fixtures/pages-workerjs-directory/public/_worker.js/add.wasm new file mode 100644 index 0000000000000..357f72da7a0db Binary files /dev/null and b/fixtures/pages-workerjs-directory/public/_worker.js/add.wasm differ diff --git a/fixtures/pages-workerjs-directory/public/_worker.js/index.js b/fixtures/pages-workerjs-directory/public/_worker.js/index.js index 3380296683bc9..fb55bdb57c751 100644 --- a/fixtures/pages-workerjs-directory/public/_worker.js/index.js +++ b/fixtures/pages-workerjs-directory/public/_worker.js/index.js @@ -1,6 +1,19 @@ +import staticMod from "./static.js"; +import add from "./add.wasm"; + export default { async fetch(request, env) { const { pathname } = new URL(request.url); + + if (pathname === "/wasm") { + const addModule = await WebAssembly.instantiate(add); + return new Response(addModule.exports.add(1, 2).toString()); + } + + if (pathname === "/static") { + return new Response(staticMod); + } + if (pathname !== "/") { return new Response((await import(`./${pathname.slice(1)}`)).default); } diff --git a/fixtures/pages-workerjs-directory/public/_worker.js/static.js b/fixtures/pages-workerjs-directory/public/_worker.js/static.js new file mode 100644 index 0000000000000..dffa9ed5541b5 --- /dev/null +++ b/fixtures/pages-workerjs-directory/public/_worker.js/static.js @@ -0,0 +1 @@ +export default "static"; diff --git a/fixtures/pages-workerjs-directory/tests/index.test.ts b/fixtures/pages-workerjs-directory/tests/index.test.ts index 2db76f11382a2..d4446d65f562a 100644 --- a/fixtures/pages-workerjs-directory/tests/index.test.ts +++ b/fixtures/pages-workerjs-directory/tests/index.test.ts @@ -1,4 +1,7 @@ -import { resolve } from "node:path"; +import { execSync } from "node:child_process"; +import { readFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import path, { join, resolve } from "node:path"; import { fetch } from "undici"; import { describe, it } from "vitest"; import { runWranglerPagesDev } from "../../shared/src/run-wrangler-long-lived"; @@ -13,9 +16,30 @@ describe.concurrent("Pages _worker.js/ directory", () => { await expect( fetch(`http://${ip}:${port}/`).then((resp) => resp.text()) ).resolves.toContain("Hello, world!"); + await expect( + fetch(`http://${ip}:${port}/wasm`).then((resp) => resp.text()) + ).resolves.toContain("3"); + await expect( + fetch(`http://${ip}:${port}/static`).then((resp) => resp.text()) + ).resolves.toContain("static"); await expect( fetch(`http://${ip}:${port}/other-script`).then((resp) => resp.text()) ).resolves.toContain("test"); await stop(); }); + + it("should bundle", async ({ expect }) => { + const dir = tmpdir(); + const file = join(dir, "./_worker.bundle"); + + execSync( + `npx wrangler pages functions build --build-output-directory public --outfile ${file} --bindings="{\\"d1_databases\\":{\\"FOO\\":{}}}"`, + { + cwd: path.resolve(__dirname, ".."), + } + ); + + expect(readFileSync(file, "utf-8")).toContain("D1_ERROR"); + expect(readFileSync(file, "utf-8")).toContain('"static"'); + }); }); diff --git a/packages/wrangler/src/__tests__/pages/functions-build.test.ts b/packages/wrangler/src/__tests__/pages/functions-build.test.ts index 6076d44c2cfa9..01b8947eec7e6 100644 --- a/packages/wrangler/src/__tests__/pages/functions-build.test.ts +++ b/packages/wrangler/src/__tests__/pages/functions-build.test.ts @@ -470,9 +470,7 @@ export default { export const cat = "cat";` ); - await runWrangler( - `pages functions build --outfile=public/_worker.bundle --compatibility-flag=nodejs_compat` - ); + await runWrangler(`pages functions build --outfile=public/_worker.bundle`); expect(existsSync("public/_worker.bundle")).toBe(true); expect(std.out).toMatchInlineSnapshot(` @@ -485,7 +483,8 @@ export const cat = "cat";` workerBundleContents, [ [/------formdata-undici-0.[0-9]*/g, "------formdata-undici-0.test"], - [/functionsWorker-0.[0-9]*.js/g, "functionsWorker-0.test.js"], + [/bundledWorker-0.[0-9]*.mjs/g, "bundledWorker-0.test.mjs"], + [/bundledWorker-0.[0-9]*.map/g, "bundledWorker-0.test.map"], ] ); @@ -493,9 +492,9 @@ export const cat = "cat";` "------formdata-undici-0.test Content-Disposition: form-data; name=\\"metadata\\" - {\\"main_module\\":\\"functionsWorker-0.test.js\\"} + {\\"main_module\\":\\"bundledWorker-0.test.mjs\\"} ------formdata-undici-0.test - Content-Disposition: form-data; name=\\"functionsWorker-0.test.js\\"; filename=\\"functionsWorker-0.test.js\\" + Content-Disposition: form-data; name=\\"bundledWorker-0.test.mjs\\"; filename=\\"bundledWorker-0.test.mjs\\" Content-Type: application/javascript+module import { cat } from \\"./cat.js\\"; @@ -507,6 +506,7 @@ export const cat = "cat";` export { worker_default as default }; + //# sourceMappingURL=bundledWorker-0.test.mjs.map ------formdata-undici-0.test Content-Disposition: form-data; name=\\"cat.js\\"; filename=\\"cat.js\\" diff --git a/packages/wrangler/src/api/dev.ts b/packages/wrangler/src/api/dev.ts index 91edae6720746..27c1fbf1ad6ac 100644 --- a/packages/wrangler/src/api/dev.ts +++ b/packages/wrangler/src/api/dev.ts @@ -43,7 +43,7 @@ export interface UnstableDevOptions { bucket_name: string; preview_bucket_name?: string; }[]; - bundleEntrypoint?: boolean; + processEntrypoint?: boolean; moduleRoot?: string; rules?: Rule[]; logLevel?: "none" | "info" | "error" | "log" | "warn" | "debug"; // Specify logging level [choices: "debug", "info", "log", "warn", "error", "none"] [default: "log"] @@ -154,7 +154,7 @@ export async function unstable_dev( }, config: options?.config, env: options?.env, - bundleEntrypoint: !!options?.bundleEntrypoint, + processEntrypoint: !!options?.processEntrypoint, bundle: options?.bundle, compatibilityDate: options?.compatibilityDate, compatibilityFlags: options?.compatibilityFlags, diff --git a/packages/wrangler/src/api/pages/publish.tsx b/packages/wrangler/src/api/pages/publish.tsx index 922f6c00fbe0c..36efa2b7e0149 100644 --- a/packages/wrangler/src/api/pages/publish.tsx +++ b/packages/wrangler/src/api/pages/publish.tsx @@ -14,10 +14,10 @@ import { import { buildRawWorker, checkRawWorker, + traverseAndBuildWorkerJSDirectory, } from "../../pages/functions/buildWorker"; import { validateRoutes } from "../../pages/functions/routes-validation"; import { upload } from "../../pages/upload"; -import traverseModuleGraph from "../../traverse-module-graph"; import { createUploadWorkerBundleContents } from "./create-worker-bundle-contents"; import type { BundleResult } from "../../bundle"; import type { Project, Deployment } from "@cloudflare/types"; @@ -66,7 +66,7 @@ interface PagesPublishOptions { /** * Whether to run bundling on `_worker.js` before deploying. - * Default: false + * Default: true */ bundle?: boolean; @@ -96,9 +96,11 @@ export async function publish({ _redirects: string | undefined, _routesGenerated: string | undefined, _routesCustom: string | undefined, - _workerJSDirectory = false, + _workerJSIsDirectory = false, _workerJS: string | undefined; + bundle = bundle ?? true; + const _workerPath = resolvePath(directory, "_worker.js"); try { @@ -118,8 +120,8 @@ export async function publish({ } catch {} try { - _workerJSDirectory = lstatSync(_workerPath).isDirectory(); - if (!_workerJSDirectory) { + _workerJSIsDirectory = lstatSync(_workerPath).isDirectory(); + if (!_workerJSIsDirectory) { _workerJS = readFileSync(_workerPath, "utf-8"); } } catch {} @@ -245,51 +247,16 @@ export async function publish({ * Advanced Mode * https://developers.cloudflare.com/pages/platform/functions/#advanced-mode * - * When using a _worker.js file, the entire /functions directory is ignored + * When using a _worker.js file or _worker.js/ directory, the entire /functions directory is ignored * – this includes its routing and middleware characteristics. */ - if (_workerJSDirectory) { - const traverseModuleGraphResult = await traverseModuleGraph( - { - file: resolvePath(join(_workerPath, "index.js")), - directory: resolvePath(_workerPath), - format: "modules", - moduleRoot: resolvePath(_workerPath), - }, - [ - { - type: "ESModule", - globs: ["**/*.js"], - }, - ] - ); - - const outfile = join(tmpdir(), `./bundledWorker-${Math.random()}.mjs`); - const bundleResult = await buildRawWorker({ - workerScriptPath: _workerPath, - bundle: false, - outfile, - directory, - local: false, - sourcemap: true, - watch: false, - onEnd: () => {}, - betaD1Shims: d1Databases, + if (_workerJSIsDirectory) { + workerBundle = await traverseAndBuildWorkerJSDirectory({ + workerJSDirectory: _workerPath, + buildOutputDirectory: directory, + d1Databases, nodejsCompat, }); - - workerBundle = { - modules: (traverseModuleGraphResult?.modules ?? - bundleResult?.modules) as BundleResult["modules"], - dependencies: (bundleResult?.dependencies ?? - traverseModuleGraphResult?.dependencies) as BundleResult["dependencies"], - resolvedEntryPointPath: (bundleResult?.resolvedEntryPointPath ?? - traverseModuleGraphResult?.resolvedEntryPointPath) as BundleResult["resolvedEntryPointPath"], - bundleType: (bundleResult?.bundleType ?? - traverseModuleGraphResult?.bundleType) as BundleResult["bundleType"], - stop: bundleResult?.stop, - sourceMapPath: bundleResult?.sourceMapPath, - }; } else if (_workerJS) { if (bundle) { const outfile = join(tmpdir(), `./bundledWorker-${Math.random()}.mjs`); @@ -317,7 +284,7 @@ export async function publish({ } } - if (_workerJS || _workerJSDirectory) { + if (_workerJS || _workerJSIsDirectory) { const workerBundleContents = await createUploadWorkerBundleContents( workerBundle as BundleResult ); @@ -351,7 +318,7 @@ export async function publish({ * Pages Functions * https://developers.cloudflare.com/pages/platform/functions/ */ - if (builtFunctions && !_workerJS) { + if (builtFunctions && !_workerJS && !_workerJSIsDirectory) { const workerBundleContents = await createUploadWorkerBundleContents( workerBundle as BundleResult ); diff --git a/packages/wrangler/src/bundle.ts b/packages/wrangler/src/bundle.ts index 7719cd41101a1..c35f5b48bfe1b 100644 --- a/packages/wrangler/src/bundle.ts +++ b/packages/wrangler/src/bundle.ts @@ -117,6 +117,7 @@ export async function bundleWorker( entry: Entry, destination: string, options: { + // When `bundle` is set to false, we apply shims to the Worker, but won't pull in any imports bundle?: boolean; serveAssetsFromWorker: boolean; assets?: StaticAssetsConfig; diff --git a/packages/wrangler/src/dev.tsx b/packages/wrangler/src/dev.tsx index 5e1e52148100b..0173eb6812cb4 100644 --- a/packages/wrangler/src/dev.tsx +++ b/packages/wrangler/src/dev.tsx @@ -334,7 +334,7 @@ export type AdditionalDevProps = { preview_bucket_name?: string; }[]; d1Databases?: Environment["d1_databases"]; - bundleEntrypoint?: boolean; + processEntrypoint?: boolean; moduleRoot?: string; rules?: Rule[]; }; @@ -427,7 +427,7 @@ export async function startDev(args: StartDevOptions) { zone={zoneId} host={host} routes={routes} - bundleEntrypoint={!!args.bundleEntrypoint} + processEntrypoint={!!args.processEntrypoint} rules={args.rules ?? getRules(configParam)} legacyEnv={isLegacyEnv(configParam)} minify={args.minify ?? configParam.minify} @@ -564,7 +564,7 @@ export async function startApiDev(args: StartDevOptions) { zone: zoneId, host: host, routes: routes, - bundleEntrypoint: !!args.bundleEntrypoint, + processEntrypoint: !!args.processEntrypoint, rules: args.rules ?? getRules(configParam), legacyEnv: isLegacyEnv(configParam), minify: args.minify ?? configParam.minify, diff --git a/packages/wrangler/src/dev/dev.tsx b/packages/wrangler/src/dev/dev.tsx index fdb3a2e4c8246..29583a585daa7 100644 --- a/packages/wrangler/src/dev/dev.tsx +++ b/packages/wrangler/src/dev/dev.tsx @@ -116,7 +116,7 @@ export type DevProps = { initialPort: number; initialIp: string; inspectorPort: number; - bundleEntrypoint: boolean; + processEntrypoint: boolean; rules: Config["rules"]; accountId: string | undefined; initialMode: "local" | "remote"; @@ -272,7 +272,7 @@ function DevSession(props: DevSessionProps) { entry: props.entry, destination: directory, jsxFactory: props.jsxFactory, - bundleEntrypoint: props.bundleEntrypoint, + processEntrypoint: props.processEntrypoint, rules: props.rules, jsxFragment: props.jsxFragment, serveAssetsFromWorker: Boolean( diff --git a/packages/wrangler/src/dev/start-server.ts b/packages/wrangler/src/dev/start-server.ts index c0b111763b6e2..de010964a142a 100644 --- a/packages/wrangler/src/dev/start-server.ts +++ b/packages/wrangler/src/dev/start-server.ts @@ -92,7 +92,7 @@ export async function startDevServer( entry: props.entry, destination: directory.name, jsxFactory: props.jsxFactory, - bundleEntrypoint: props.bundleEntrypoint, + processEntrypoint: props.processEntrypoint, rules: props.rules, jsxFragment: props.jsxFragment, serveAssetsFromWorker: Boolean( @@ -206,7 +206,7 @@ async function runEsbuild({ destination, jsxFactory, jsxFragment, - bundleEntrypoint, + processEntrypoint, rules, assets, betaD1Shims, @@ -229,7 +229,7 @@ async function runEsbuild({ destination: string | undefined; jsxFactory: string | undefined; jsxFragment: string | undefined; - bundleEntrypoint: boolean; + processEntrypoint: boolean; rules: Config["rules"]; assets: Config["assets"]; betaD1Shims?: string[]; @@ -258,7 +258,7 @@ async function runEsbuild({ traverseModuleGraphResult = await traverseModuleGraph(entry, rules); } - if (bundleEntrypoint || !noBundle) { + if (processEntrypoint || !noBundle) { bundleResult = await bundleWorker(entry, destination, { bundle: !noBundle, disableModuleCollection: noBundle, @@ -289,41 +289,16 @@ async function runEsbuild({ }); } - const { - modules, - dependencies, - resolvedEntryPointPath, - bundleType, - sourceMapPath, - }: Awaited> = { - modules: (traverseModuleGraphResult?.modules ?? - bundleResult?.modules) as Awaited< - ReturnType - >["modules"], - dependencies: (bundleResult?.dependencies ?? - traverseModuleGraphResult?.dependencies) as Awaited< - ReturnType - >["dependencies"], - resolvedEntryPointPath: (bundleResult?.resolvedEntryPointPath ?? - traverseModuleGraphResult?.resolvedEntryPointPath) as Awaited< - ReturnType - >["resolvedEntryPointPath"], - bundleType: (bundleResult?.bundleType ?? - traverseModuleGraphResult?.bundleType) as Awaited< - ReturnType - >["bundleType"], - stop: bundleResult?.stop, - sourceMapPath: bundleResult?.sourceMapPath, - }; - return { id: 0, entry, - path: resolvedEntryPointPath, - type: bundleType, - modules, - dependencies, - sourceMapPath, + path: bundleResult?.resolvedEntryPointPath ?? entry.file, + type: + bundleResult?.bundleType ?? + (entry.format === "modules" ? "esm" : "commonjs"), + modules: traverseModuleGraphResult?.modules ?? bundleResult?.modules ?? [], + dependencies: bundleResult?.dependencies ?? {}, + sourceMapPath: bundleResult?.sourceMapPath, }; } diff --git a/packages/wrangler/src/dev/use-esbuild.ts b/packages/wrangler/src/dev/use-esbuild.ts index af2ec05a99a84..2285eb71676ef 100644 --- a/packages/wrangler/src/dev/use-esbuild.ts +++ b/packages/wrangler/src/dev/use-esbuild.ts @@ -26,7 +26,7 @@ export function useEsbuild({ destination, jsxFactory, jsxFragment, - bundleEntrypoint, + processEntrypoint, rules, assets, serveAssetsFromWorker, @@ -50,7 +50,7 @@ export function useEsbuild({ destination: string | undefined; jsxFactory: string | undefined; jsxFragment: string | undefined; - bundleEntrypoint: boolean; + processEntrypoint: boolean; rules: Config["rules"]; assets: Config["assets"]; define: Config["define"]; @@ -110,7 +110,7 @@ export function useEsbuild({ traverseModuleGraphResult = await traverseModuleGraph(entry, rules); } - if (bundleEntrypoint || !noBundle) { + if (processEntrypoint || !noBundle) { bundleResult = await bundleWorker(entry, destination, { bundle: !noBundle, disableModuleCollection: noBundle, @@ -142,36 +142,8 @@ export function useEsbuild({ }); } - const { - modules, - dependencies, - resolvedEntryPointPath, - bundleType, - stop, - sourceMapPath, - }: Awaited> = { - modules: (traverseModuleGraphResult?.modules ?? - bundleResult?.modules) as Awaited< - ReturnType - >["modules"], - dependencies: (bundleResult?.dependencies ?? - traverseModuleGraphResult?.dependencies) as Awaited< - ReturnType - >["dependencies"], - resolvedEntryPointPath: (bundleResult?.resolvedEntryPointPath ?? - traverseModuleGraphResult?.resolvedEntryPointPath) as Awaited< - ReturnType - >["resolvedEntryPointPath"], - bundleType: (bundleResult?.bundleType ?? - traverseModuleGraphResult?.bundleType) as Awaited< - ReturnType - >["bundleType"], - stop: bundleResult?.stop, - sourceMapPath: bundleResult?.sourceMapPath, - }; - // Capture the `stop()` method to use as the `useEffect()` destructor. - stopWatching = stop; + stopWatching = bundleResult?.stop; // if "noBundle" is true, then we need to manually watch the entry point and // trigger "builds" when it changes @@ -189,11 +161,14 @@ export function useEsbuild({ setBundle({ id: 0, entry, - path: resolvedEntryPointPath, - type: bundleType, - modules, - dependencies, - sourceMapPath, + path: bundleResult?.resolvedEntryPointPath ?? entry.file, + type: + bundleResult?.bundleType ?? + (entry.format === "modules" ? "esm" : "commonjs"), + modules: + traverseModuleGraphResult?.modules ?? bundleResult?.modules ?? [], + dependencies: bundleResult?.dependencies ?? {}, + sourceMapPath: bundleResult?.sourceMapPath, }); } @@ -213,7 +188,7 @@ export function useEsbuild({ jsxFactory, jsxFragment, serveAssetsFromWorker, - bundleEntrypoint, + processEntrypoint, rules, tsconfig, exit, diff --git a/packages/wrangler/src/pages/build.ts b/packages/wrangler/src/pages/build.ts index 7052c0c91ae39..af17e3b77115f 100644 --- a/packages/wrangler/src/pages/build.ts +++ b/packages/wrangler/src/pages/build.ts @@ -1,17 +1,9 @@ import { existsSync, lstatSync, mkdirSync, writeFileSync } from "node:fs"; -import { - basename, - dirname, - join, - relative, - resolve, - resolve as resolvePath, -} from "node:path"; +import { basename, dirname, relative, resolve as resolvePath } from "node:path"; import { createUploadWorkerBundleContents } from "../api/pages/create-worker-bundle-contents"; import { FatalError } from "../errors"; import { logger } from "../logger"; import * as metrics from "../metrics"; -import traverseModuleGraph from "../traverse-module-graph"; import { buildFunctions } from "./buildFunctions"; import { isInPagesCI } from "./constants"; import { @@ -20,7 +12,10 @@ import { FunctionsNoRoutesError, getFunctionsNoRoutesWarning, } from "./errors"; -import { buildRawWorker } from "./functions/buildWorker"; +import { + buildRawWorker, + traverseAndBuildWorkerJSDirectory, +} from "./functions/buildWorker"; import { pagesBetaWarning } from "./utils"; import type { BundleResult } from "../bundle"; import type { @@ -217,46 +212,12 @@ export const Handler = async (args: PagesBuildArgs) => { */ if (workerScriptPath) { if (lstatSync(workerScriptPath).isDirectory()) { - const entrypoint = resolve(join(workerScriptPath, "index.js")); - - const traverseModuleGraphResult = await traverseModuleGraph( - { - file: entrypoint, - directory: resolve(workerScriptPath), - format: "modules", - moduleRoot: resolve(workerScriptPath), - }, - [ - { - type: "ESModule", - globs: ["**/*.js"], - }, - ] - ); - - const bundleResult = await buildRawWorker({ - workerScriptPath: entrypoint, - bundle: false, - outdir, - directory: buildOutputDirectory, - local: false, - sourcemap, - watch, - betaD1Shims: d1Databases, + bundle = await traverseAndBuildWorkerJSDirectory({ + workerJSDirectory: workerScriptPath, + buildOutputDirectory, + d1Databases, + nodejsCompat, }); - - bundle = { - modules: (traverseModuleGraphResult?.modules ?? - bundleResult?.modules) as BundleResult["modules"], - dependencies: (bundleResult?.dependencies ?? - traverseModuleGraphResult?.dependencies) as BundleResult["dependencies"], - resolvedEntryPointPath: (bundleResult?.resolvedEntryPointPath ?? - traverseModuleGraphResult?.resolvedEntryPointPath) as BundleResult["resolvedEntryPointPath"], - bundleType: (bundleResult?.bundleType ?? - traverseModuleGraphResult?.bundleType) as BundleResult["bundleType"], - stop: bundleResult?.stop, - sourceMapPath: bundleResult?.sourceMapPath, - }; } else { /** * `buildRawWorker` builds `_worker.js`, but doesn't give us the bundle diff --git a/packages/wrangler/src/pages/dev.ts b/packages/wrangler/src/pages/dev.ts index 9e3dd658ca851..d4dc3afe80771 100644 --- a/packages/wrangler/src/pages/dev.ts +++ b/packages/wrangler/src/pages/dev.ts @@ -545,7 +545,7 @@ export const Handler = async ({ r2: r2s.map((binding) => { return { binding: binding.toString(), bucket_name: "" }; }), - bundleEntrypoint: true, + processEntrypoint: true, moduleRoot: workerScriptPath, rules: usingWorkerDirectory ? [ diff --git a/packages/wrangler/src/pages/functions/buildWorker.ts b/packages/wrangler/src/pages/functions/buildWorker.ts index 7bb3de201c748..dca341d081990 100644 --- a/packages/wrangler/src/pages/functions/buildWorker.ts +++ b/packages/wrangler/src/pages/functions/buildWorker.ts @@ -7,7 +7,9 @@ import { bundleWorker } from "../../bundle"; import { FatalError } from "../../errors"; import { logger } from "../../logger"; import { getBasePath } from "../../paths"; +import traverseModuleGraph from "../../traverse-module-graph"; import { D1_BETA_PREFIX } from "../../worker"; +import type { BundleResult } from "../../bundle"; import type { Plugin } from "esbuild"; export type Options = { @@ -237,6 +239,58 @@ export function buildRawWorker({ ); } +export async function traverseAndBuildWorkerJSDirectory({ + workerJSDirectory, + buildOutputDirectory, + d1Databases, + nodejsCompat, +}: { + workerJSDirectory: string; + buildOutputDirectory: string; + d1Databases?: string[]; + nodejsCompat?: boolean; +}): Promise { + const entrypoint = resolve(join(workerJSDirectory, "index.js")); + + const traverseModuleGraphResult = await traverseModuleGraph( + { + file: entrypoint, + directory: resolve(workerJSDirectory), + format: "modules", + moduleRoot: resolve(workerJSDirectory), + }, + [ + { + type: "ESModule", + globs: ["**/*.js"], + }, + ] + ); + + const outfile = join(tmpdir(), `./bundledWorker-${Math.random()}.mjs`); + const bundleResult = await buildRawWorker({ + workerScriptPath: entrypoint, + bundle: false, + outfile, + directory: buildOutputDirectory, + local: false, + sourcemap: true, + watch: false, + onEnd: () => {}, + betaD1Shims: d1Databases, + nodejsCompat, + }); + + return { + modules: traverseModuleGraphResult?.modules ?? bundleResult?.modules ?? [], + dependencies: bundleResult?.dependencies ?? {}, + resolvedEntryPointPath: bundleResult?.resolvedEntryPointPath ?? entrypoint, + bundleType: bundleResult?.bundleType ?? "esm", + stop: bundleResult?.stop, + sourceMapPath: bundleResult?.sourceMapPath, + }; +} + /** * Creates an esbuild plugin that can notify Wrangler (via the `onEnd()`) * when the build completes.