diff --git a/.changeset/proud-toes-travel.md b/.changeset/proud-toes-travel.md new file mode 100644 index 000000000000..ed5fa3ddd564 --- /dev/null +++ b/.changeset/proud-toes-travel.md @@ -0,0 +1,8 @@ +--- +"wrangler": patch +--- + +fix: make sure Wrangler doesn't create a `.wrangler` tmp dir in the `functions/` folder of a Pages project + +This regression was introduced in https://github.com/cloudflare/workers-sdk/pull/7415 +and this change fixes it by reverting that change. diff --git a/fixtures/import-npm/package-lock.json b/fixtures/import-npm/package-lock.json index 4a7536533dc4..5a9e9df90d13 100644 --- a/fixtures/import-npm/package-lock.json +++ b/fixtures/import-npm/package-lock.json @@ -15,7 +15,7 @@ "dev": true }, "../../packages/wrangler": { - "version": "3.91.0", + "version": "3.92.0", "dev": true, "license": "MIT OR Apache-2.0", "dependencies": { @@ -34,8 +34,8 @@ "resolve": "^1.22.8", "selfsigned": "^2.0.1", "source-map": "^0.6.1", - "unenv": "npm:unenv-nightly@2.0.0-20241121-161142-806b5c0", - "workerd": "1.20241106.1", + "unenv": "npm:unenv-nightly@2.0.0-20241204-140205-a5d5190", + "workerd": "1.20241106.2", "xxhash-wasm": "^1.0.1" }, "bin": { diff --git a/packages/wrangler/e2e/pages-dev.test.ts b/packages/wrangler/e2e/pages-dev.test.ts index 48204315f365..6045bd0e1949 100644 --- a/packages/wrangler/e2e/pages-dev.test.ts +++ b/packages/wrangler/e2e/pages-dev.test.ts @@ -1,3 +1,5 @@ +import { existsSync } from "node:fs"; +import path from "node:path"; import { setTimeout } from "node:timers/promises"; import getPort from "get-port"; import dedent from "ts-dedent"; @@ -482,6 +484,11 @@ describe.each([{ cmd: "wrangler pages dev" }])("Pages $cmd", ({ cmd }) => { text = await fetchText(url); expect(text).toBe("Updated Worker!"); + + // Ensure Wrangler doesn't write tmp files in the functions directory—regression test for https://github.com/cloudflare/workers-sdk/issues/7440 + expect( + existsSync(path.join(helper.tmpPath, "functions/.wrangler")) + ).toBeFalsy(); }); it("should support modifying dependencies during dev session (Functions)", async () => { diff --git a/packages/wrangler/src/__tests__/api/startDevWorker/LocalRuntimeController.test.ts b/packages/wrangler/src/__tests__/api/startDevWorker/LocalRuntimeController.test.ts index 7b85f793f933..d9735954a1e7 100644 --- a/packages/wrangler/src/__tests__/api/startDevWorker/LocalRuntimeController.test.ts +++ b/packages/wrangler/src/__tests__/api/startDevWorker/LocalRuntimeController.test.ts @@ -88,6 +88,7 @@ function makeEsbuildBundle(testBundle: TestBundle): Bundle { entrypointSource: "", entry: { file: "index.mjs", + projectRoot: "/virtual/", format: "modules", moduleRoot: "/virtual", name: undefined, @@ -232,6 +233,7 @@ describe("LocalRuntimeController", () => { `, entry: { file: "esm/index.mjs", + projectRoot: "/virtual/", format: "modules", moduleRoot: "/virtual", name: undefined, @@ -345,6 +347,7 @@ describe("LocalRuntimeController", () => { path: "/virtual/index.js", entry: { file: "index.js", + projectRoot: "/virtual/", format: "service-worker", moduleRoot: "/virtual", name: undefined, diff --git a/packages/wrangler/src/__tests__/configuration.test.ts b/packages/wrangler/src/__tests__/configuration.test.ts index 38ba0bdf5c1c..665112d2d6c6 100644 --- a/packages/wrangler/src/__tests__/configuration.test.ts +++ b/packages/wrangler/src/__tests__/configuration.test.ts @@ -63,7 +63,6 @@ describe("normalizeAndValidateConfig()", () => { compatibility_date: undefined, compatibility_flags: [], configPath: undefined, - projectRoot: process.cwd(), d1_databases: [], vectorize: [], hyperdrive: [], diff --git a/packages/wrangler/src/__tests__/find-additional-modules.test.ts b/packages/wrangler/src/__tests__/find-additional-modules.test.ts index a3b436afc15a..dc9df03f2670 100644 --- a/packages/wrangler/src/__tests__/find-additional-modules.test.ts +++ b/packages/wrangler/src/__tests__/find-additional-modules.test.ts @@ -37,9 +37,9 @@ describe("traverse module graph", () => { ); const modules = await findAdditionalModules( - process.cwd(), { file: path.join(process.cwd(), "./index.js"), + projectRoot: process.cwd(), format: "modules", moduleRoot: process.cwd(), exports: [], @@ -73,9 +73,9 @@ describe("traverse module graph", () => { ); const modules = await findAdditionalModules( - process.cwd(), { file: path.join(process.cwd(), "./index.js"), + projectRoot: process.cwd(), format: "modules", moduleRoot: process.cwd(), exports: [], @@ -107,9 +107,9 @@ describe("traverse module graph", () => { ); const modules = await findAdditionalModules( - path.join(process.cwd(), "./src/nested"), { file: path.join(process.cwd(), "./src/nested/index.js"), + projectRoot: path.join(process.cwd(), "./src/nested"), format: "modules", // The default module root is dirname(file) moduleRoot: path.join(process.cwd(), "./src/nested"), @@ -142,9 +142,9 @@ describe("traverse module graph", () => { ); const modules = await findAdditionalModules( - path.join(process.cwd(), "./src/nested"), { file: path.join(process.cwd(), "./src/nested/index.js"), + projectRoot: path.join(process.cwd(), "./src/nested"), format: "modules", // The default module root is dirname(file) moduleRoot: path.join(process.cwd(), "./src"), @@ -177,9 +177,9 @@ describe("traverse module graph", () => { ); const modules = await findAdditionalModules( - path.join(process.cwd(), "./src/nested"), { file: path.join(process.cwd(), "./src/nested/index.js"), + projectRoot: path.join(process.cwd(), "./src/nested"), format: "modules", // The default module root is dirname(file) moduleRoot: path.join(process.cwd(), "./src"), @@ -212,9 +212,9 @@ describe("traverse module graph", () => { ); const modules = await findAdditionalModules( - path.join(process.cwd(), "./src"), { file: path.join(process.cwd(), "./src/index.js"), + projectRoot: path.join(process.cwd(), "./src"), format: "modules", // The default module root is dirname(file) moduleRoot: path.join(process.cwd(), "./src"), @@ -247,9 +247,9 @@ describe("traverse module graph", () => { await expect( findAdditionalModules( - path.join(process.cwd(), "./src"), { file: path.join(process.cwd(), "./src/index.js"), + projectRoot: path.join(process.cwd(), "./src"), format: "modules", // The default module root is dirname(file) moduleRoot: path.join(process.cwd(), "./src"), diff --git a/packages/wrangler/src/__tests__/get-entry.test.ts b/packages/wrangler/src/__tests__/get-entry.test.ts index ae2541712ea4..aa938d5054dc 100644 --- a/packages/wrangler/src/__tests__/get-entry.test.ts +++ b/packages/wrangler/src/__tests__/get-entry.test.ts @@ -1,17 +1,12 @@ import path from "path"; import dedent from "ts-dedent"; -import { normalizeAndValidateConfig } from "../config/validation"; +import { defaultWranglerConfig } from "../config/config"; import { getEntry } from "../deployment-bundle/entry"; import { mockConsoleMethods } from "./helpers/mock-console"; import { runInTempDir } from "./helpers/run-in-tmp"; import { seed } from "./helpers/seed"; -import type { Config, RawConfig } from "../config"; import type { Entry } from "../deployment-bundle/entry"; -function getConfig(raw: RawConfig = {}, configPath?: string): Config { - return normalizeAndValidateConfig(raw, configPath, {}).config; -} - function normalize(entry: Entry): Entry { const tmpDir = process.cwd(); const tmpDirName = path.basename(tmpDir); @@ -42,8 +37,13 @@ describe("getEntry()", () => { } `, }); - const entry = await getEntry({ script: "index.ts" }, getConfig(), "deploy"); + const entry = await getEntry( + { script: "index.ts" }, + defaultWranglerConfig, + "deploy" + ); expect(normalize(entry)).toMatchObject({ + projectRoot: "/tmp/dir", file: "/tmp/dir/index.ts", moduleRoot: "/tmp/dir", }); @@ -61,10 +61,11 @@ describe("getEntry()", () => { }); const entry = await getEntry( { script: "src/index.ts" }, - getConfig(), + defaultWranglerConfig, "deploy" ); expect(normalize(entry)).toMatchObject({ + projectRoot: "/tmp/dir", file: "/tmp/dir/src/index.ts", moduleRoot: "/tmp/dir/src", }); @@ -80,8 +81,13 @@ describe("getEntry()", () => { } `, }); - const entry = await getEntry({}, getConfig({ main: "index.ts" }), "deploy"); + const entry = await getEntry( + {}, + { ...defaultWranglerConfig, main: "index.ts" }, + "deploy" + ); expect(normalize(entry)).toMatchObject({ + projectRoot: "/tmp/dir", file: "/tmp/dir/index.ts", moduleRoot: "/tmp/dir", }); @@ -99,10 +105,11 @@ describe("getEntry()", () => { }); const entry = await getEntry( {}, - getConfig({ main: "src/index.ts" }), + { ...defaultWranglerConfig, main: "src/index.ts" }, "deploy" ); expect(normalize(entry)).toMatchObject({ + projectRoot: "/tmp/dir", file: "/tmp/dir/src/index.ts", moduleRoot: "/tmp/dir/src", }); @@ -120,15 +127,15 @@ describe("getEntry()", () => { }); const entry = await getEntry( {}, - getConfig( - { - main: "src/index.ts", - }, - "other-worker/wrangler.toml" - ), + { + ...defaultWranglerConfig, + main: "src/index.ts", + configPath: "other-worker/wrangler.toml", + }, "deploy" ); expect(normalize(entry)).toMatchObject({ + projectRoot: "/tmp/dir/other-worker", file: "/tmp/dir/other-worker/src/index.ts", moduleRoot: "/tmp/dir/other-worker/src", }); diff --git a/packages/wrangler/src/__tests__/navigator-user-agent.test.ts b/packages/wrangler/src/__tests__/navigator-user-agent.test.ts index 43d470ffef8a..6b66a311a9ab 100644 --- a/packages/wrangler/src/__tests__/navigator-user-agent.test.ts +++ b/packages/wrangler/src/__tests__/navigator-user-agent.test.ts @@ -104,6 +104,7 @@ describe("defineNavigatorUserAgent is respected", () => { await bundleWorker( { file: path.resolve("src/index.js"), + projectRoot: process.cwd(), format: "modules", moduleRoot: path.dirname(path.resolve("src/index.js")), exports: [], @@ -166,6 +167,7 @@ describe("defineNavigatorUserAgent is respected", () => { await bundleWorker( { file: path.resolve("src/index.js"), + projectRoot: process.cwd(), format: "modules", moduleRoot: path.dirname(path.resolve("src/index.js")), exports: [], diff --git a/packages/wrangler/src/__tests__/pages/deploy.test.ts b/packages/wrangler/src/__tests__/pages/deploy.test.ts index e60b27d57c65..806f69219560 100644 --- a/packages/wrangler/src/__tests__/pages/deploy.test.ts +++ b/packages/wrangler/src/__tests__/pages/deploy.test.ts @@ -2855,7 +2855,7 @@ Failed to publish your Function. Got error: Uncaught TypeError: a is not a funct }); }); - describe("in Advanced Mode [_worker.js]", () => { + describe("in Advanced Mode [_worker,js]", () => { it("should upload an Advanced Mode project", async () => { // set up the directory of static files to upload. mkdirSync("public"); diff --git a/packages/wrangler/src/api/startDevWorker/BundlerController.ts b/packages/wrangler/src/api/startDevWorker/BundlerController.ts index 830630495ad1..115690965f23 100644 --- a/packages/wrangler/src/api/startDevWorker/BundlerController.ts +++ b/packages/wrangler/src/api/startDevWorker/BundlerController.ts @@ -79,6 +79,7 @@ export class BundlerController extends Controller { const entry: Entry = { file: config.entrypoint, + projectRoot: config.projectRoot, format: config.build.format, moduleRoot: config.build.moduleRoot, exports: config.build.exports, @@ -86,7 +87,6 @@ export class BundlerController extends Controller { const entryDirectory = path.dirname(config.entrypoint); const moduleCollector = createModuleCollector({ - projectRoot: config.projectRoot, wrangler1xLegacyModuleReferences: getWrangler1xLegacyModuleReferences( entryDirectory, config.entrypoint @@ -103,7 +103,6 @@ export class BundlerController extends Controller { ).bindings; const bundleResult: Omit = !config.build?.bundle ? await noBundleWorker( - config.projectRoot, entry, config.build.moduleRules, this.#tmpDir.path @@ -235,6 +234,7 @@ export class BundlerController extends Controller { assert(this.#tmpDir); const entry: Entry = { file: config.entrypoint, + projectRoot: config.projectRoot, format: config.build.format, moduleRoot: config.build.moduleRoot, exports: config.build.exports, diff --git a/packages/wrangler/src/api/startDevWorker/ConfigController.ts b/packages/wrangler/src/api/startDevWorker/ConfigController.ts index 5b5239c42513..43f742642866 100644 --- a/packages/wrangler/src/api/startDevWorker/ConfigController.ts +++ b/packages/wrangler/src/api/startDevWorker/ConfigController.ts @@ -263,7 +263,7 @@ async function resolveConfig( compatibilityDate: getDevCompatibilityDate(config, input.compatibilityDate), compatibilityFlags: input.compatibilityFlags ?? config.compatibility_flags, entrypoint: entry.file, - projectRoot: config.projectRoot, + projectRoot: entry.projectRoot, bindings, migrations: input.migrations ?? config.migrations, sendMetrics: input.sendMetrics ?? config.send_metrics, diff --git a/packages/wrangler/src/config/config.ts b/packages/wrangler/src/config/config.ts index 55f825c02836..a0f7284b3aff 100644 --- a/packages/wrangler/src/config/config.ts +++ b/packages/wrangler/src/config/config.ts @@ -22,10 +22,7 @@ import type { CamelCaseKey } from "yargs"; * - `@breaking`: the deprecation/optionality is a breaking change from Wrangler v1. * - `@todo`: there's more work to be done (with details attached). */ -export type Config = ComputedConfigFields & - ConfigFields & - PagesConfigFields & - Environment; +export type Config = ConfigFields & PagesConfigFields & Environment; export type RawConfig = Partial> & PagesConfigFields & @@ -33,21 +30,9 @@ export type RawConfig = Partial> & DeprecatedConfigFields & EnvironmentMap & { $schema?: string }; -export interface ComputedConfigFields { - /** - * Path (relative to current working directory) of the configuration file (e.g. wrangler.toml/json), if one was provided. - */ +export interface ConfigFields { configPath: string | undefined; - /** - * Absolute path to the Worker's directory. - * - * Will be the directory containing the Wrangler configuration file, - * or the current working directory otherwise. - */ - projectRoot: string; -} -export interface ConfigFields { /** * A boolean to enable "legacy" style wrangler environments (from Wrangler v1). * These have been superseded by Services, but there may be projects that won't @@ -340,11 +325,8 @@ export const defaultWranglerConfig: Config = { /*====================================================*/ /* Fields supported by Workers only */ /*====================================================*/ - /* COMPUTED CONFIG FIELDS */ - configPath: undefined, - projectRoot: process.cwd(), - /* TOP-LEVEL ONLY FIELDS */ + configPath: undefined, legacy_env: true, site: undefined, legacy_assets: undefined, diff --git a/packages/wrangler/src/config/validation-pages.ts b/packages/wrangler/src/config/validation-pages.ts index 27c501843cfc..a948b7189695 100644 --- a/packages/wrangler/src/config/validation-pages.ts +++ b/packages/wrangler/src/config/validation-pages.ts @@ -36,10 +36,9 @@ const supportedPagesConfigFields = [ "dev", "mtls_certificates", "browser", - "upload_source_maps", - // normalizeAndValidateConfig() sets the following values + // normalizeAndValidateConfig() sets this value "configPath", - "projectRoot", + "upload_source_maps", ] as const; export function validatePagesConfig( diff --git a/packages/wrangler/src/config/validation.ts b/packages/wrangler/src/config/validation.ts index 8f62bfa22a39..df6c4744e5df 100644 --- a/packages/wrangler/src/config/validation.ts +++ b/packages/wrangler/src/config/validation.ts @@ -259,9 +259,6 @@ export function normalizeAndValidateConfig( // Process the top-level default environment configuration. const config: Config = { configPath, - projectRoot: path.resolve( - configPath !== undefined ? path.dirname(configPath) : process.cwd() - ), pages_build_output_dir: normalizeAndValidatePagesBuildOutputDir( configPath, rawConfig.pages_build_output_dir diff --git a/packages/wrangler/src/d1/execute.ts b/packages/wrangler/src/d1/execute.ts index aca0aac306f4..bea1bd4fe49d 100644 --- a/packages/wrangler/src/d1/execute.ts +++ b/packages/wrangler/src/d1/execute.ts @@ -19,7 +19,7 @@ import { requireAuth } from "../user"; import * as options from "./options"; import splitSqlQuery from "./splitter"; import { getDatabaseByNameOrBinding, getDatabaseInfoFromConfig } from "./utils"; -import type { Config } from "../config"; +import type { Config, ConfigFields, DevConfig, Environment } from "../config"; import type { CommonYargsArgv, StrictYargsOptionsToInterface, @@ -197,7 +197,7 @@ export async function executeSql({ }: { local: boolean | undefined; remote: boolean | undefined; - config: Config; + config: ConfigFields & Environment; name: string; shouldPrompt: boolean | undefined; persistTo: string | undefined; diff --git a/packages/wrangler/src/d1/migrations/helpers.ts b/packages/wrangler/src/d1/migrations/helpers.ts index bfaca5f78355..8b4399fec691 100644 --- a/packages/wrangler/src/d1/migrations/helpers.ts +++ b/packages/wrangler/src/d1/migrations/helpers.ts @@ -7,7 +7,7 @@ import { isNonInteractiveOrCI } from "../../is-interactive"; import { logger } from "../../logger"; import { DEFAULT_MIGRATION_PATH } from "../constants"; import { executeSql } from "../execute"; -import type { Config } from "../../config"; +import type { ConfigFields, DevConfig, Environment } from "../../config"; import type { QueryResult } from "../execute"; import type { Migration } from "../types"; @@ -57,7 +57,7 @@ export async function getUnappliedMigrations({ migrationsPath: string; local: boolean | undefined; remote: boolean | undefined; - config: Config; + config: ConfigFields & Environment; name: string; persistTo: string | undefined; preview: boolean | undefined; @@ -92,7 +92,7 @@ type ListAppliedMigrationsProps = { migrationsTableName: string; local: boolean | undefined; remote: boolean | undefined; - config: Config; + config: ConfigFields & Environment; name: string; persistTo: string | undefined; preview: boolean | undefined; @@ -170,7 +170,7 @@ export const initMigrationsTable = async ({ migrationsTableName: string; local: boolean | undefined; remote: boolean | undefined; - config: Config; + config: ConfigFields & Environment; name: string; persistTo: string | undefined; preview: boolean | undefined; diff --git a/packages/wrangler/src/deploy/deploy.ts b/packages/wrangler/src/deploy/deploy.ts index 001ceeccba07..b95fa38feaaa 100644 --- a/packages/wrangler/src/deploy/deploy.ts +++ b/packages/wrangler/src/deploy/deploy.ts @@ -104,7 +104,7 @@ type Props = { logpush: boolean | undefined; uploadSourceMaps: boolean | undefined; oldAssetTtl: number | undefined; - projectRoot: string; + projectRoot: string | undefined; dispatchNamespace: string | undefined; experimentalVersions: boolean | undefined; }; @@ -549,7 +549,6 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m const entryDirectory = path.dirname(props.entry.file); const moduleCollector = createModuleCollector({ - projectRoot: config.projectRoot, wrangler1xLegacyModuleReferences: getWrangler1xLegacyModuleReferences( entryDirectory, props.entry.file @@ -571,12 +570,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m bundleType, ...bundle } = props.noBundle - ? await noBundleWorker( - props.projectRoot, - props.entry, - props.rules, - props.outDir - ) + ? await noBundleWorker(props.entry, props.rules, props.outDir) : await bundleWorker( props.entry, typeof destination === "string" ? destination : destination.path, @@ -1287,12 +1281,11 @@ export async function updateQueueConsumers( } export async function noBundleWorker( - projectRoot: string, entry: Entry, rules: Rule[], outDir: string | undefined ) { - const modules = await findAdditionalModules(projectRoot, entry, rules); + const modules = await findAdditionalModules(entry, rules); if (outDir) { await writeAdditionalModules(modules, outDir); } diff --git a/packages/wrangler/src/deploy/index.ts b/packages/wrangler/src/deploy/index.ts index 24b8519c37fa..5189e39c74d6 100644 --- a/packages/wrangler/src/deploy/index.ts +++ b/packages/wrangler/src/deploy/index.ts @@ -265,6 +265,7 @@ async function deployWorker(args: DeployArgs) { const configPath = args.config || (args.script && findWranglerConfig(path.dirname(args.script))); + const projectRoot = configPath && path.dirname(configPath); const config = readConfig(configPath, args); if (config.pages_build_output_dir) { throw new UserError( @@ -341,7 +342,7 @@ async function deployWorker(args: DeployArgs) { await verifyWorkerMatchesCITag( accountId, name, - path.relative(config.projectRoot, config.configPath ?? "wrangler.toml") + path.relative(entry.projectRoot, config.configPath ?? "wrangler.toml") ); } const { sourceMapSize, versionId, workerTag, targets } = await deploy({ @@ -376,7 +377,7 @@ async function deployWorker(args: DeployArgs) { logpush: args.logpush, uploadSourceMaps: args.uploadSourceMaps, oldAssetTtl: args.oldAssetTtl, - projectRoot: config.projectRoot, + projectRoot, dispatchNamespace: args.dispatchNamespace, experimentalVersions: args.experimentalVersions, }); diff --git a/packages/wrangler/src/deployment-bundle/bundle.ts b/packages/wrangler/src/deployment-bundle/bundle.ts index dd6bce6e555a..c5f920d03d0a 100644 --- a/packages/wrangler/src/deployment-bundle/bundle.ts +++ b/packages/wrangler/src/deployment-bundle/bundle.ts @@ -134,7 +134,7 @@ export type BundleOptions = { plugins: esbuild.Plugin[] | undefined; isOutfile: boolean | undefined; local: boolean; - projectRoot: string; + projectRoot: string | undefined; defineNavigatorUserAgent: boolean; external: string[] | undefined; }; @@ -382,7 +382,7 @@ export async function bundleWorker( path: require.resolve(aliasPath, { // From the esbuild alias docs: "Note that when an import path is substituted using an alias, the resulting import path is resolved in the working directory instead of in the directory containing the source file with the import path." // https://esbuild.github.io/api/#alias:~:text=Note%20that%20when%20an%20import%20path%20is%20substituted%20using%20an%20alias%2C%20the%20resulting%20import%20path%20is%20resolved%20in%20the%20working%20directory%20instead%20of%20in%20the%20directory%20containing%20the%20source%20file%20with%20the%20import%20path. - paths: [projectRoot], + paths: [entry.projectRoot], }), }; } @@ -394,7 +394,7 @@ export async function bundleWorker( // Don't use entryFile here as the file may have been changed when applying the middleware entryPoints: [entry.file], bundle, - absWorkingDir: projectRoot, + absWorkingDir: entry.projectRoot, outdir: destination, keepNames: true, entryNames: entryName || path.parse(entryFile).name, @@ -522,7 +522,7 @@ export async function bundleWorker( )[0]; const resolvedEntryPointPath = path.resolve( - projectRoot, + entry.projectRoot, entryPoint.relativePath ); @@ -544,7 +544,7 @@ export async function bundleWorker( sourceMapPath, sourceMapMetadata: { tmpDir: tmpDir.path, - entryDirectory: projectRoot, + entryDirectory: entry.projectRoot, }, }; } diff --git a/packages/wrangler/src/deployment-bundle/entry.ts b/packages/wrangler/src/deployment-bundle/entry.ts index ab3ad5d668d5..23ff0dce5661 100644 --- a/packages/wrangler/src/deployment-bundle/entry.ts +++ b/packages/wrangler/src/deployment-bundle/entry.ts @@ -22,6 +22,8 @@ import type { CfScriptFormat } from "./worker"; export type Entry = { /** A worker's entrypoint */ file: string; + /** A worker's directory. Usually where the Wrangler configuration file is located */ + projectRoot: string; /** Is this a module worker or a service worker? */ format: CfScriptFormat; /** The directory that contains all of a `--no-bundle` worker's modules. Usually `${directory}/src`. Defaults to path.dirname(file) */ @@ -51,14 +53,16 @@ export async function getEntry( ): Promise { const entryPoint = config.site?.["entry-point"]; - let paths: { absolutePath: string; relativePath: string } | undefined; + let paths: + | { absolutePath: string; relativePath: string; projectRoot?: string } + | undefined; if (args.script) { paths = resolveEntryWithScript(args.script); } else if (config.main !== undefined) { - paths = resolveEntryWithMain(config.main, config.projectRoot); + paths = resolveEntryWithMain(config.main, config.configPath); } else if (entryPoint) { - paths = resolveEntryWithEntryPoint(entryPoint, config.projectRoot); + paths = resolveEntryWithEntryPoint(entryPoint, config.configPath); } else if ( args.legacyAssets || config.legacy_assets || @@ -84,9 +88,10 @@ export async function getEntry( config.configPath ); + const projectRoot = paths.projectRoot ?? process.cwd(); const { format, exports } = await guessWorkerFormat( paths.absolutePath, - config.projectRoot, + projectRoot, args.format ?? config.build?.upload?.format, config.tsconfig ); @@ -119,6 +124,7 @@ export async function getEntry( return { file: paths.absolutePath, + projectRoot, format, moduleRoot: args.moduleRoot ?? config.base_dir ?? path.dirname(paths.absolutePath), diff --git a/packages/wrangler/src/deployment-bundle/find-additional-modules.ts b/packages/wrangler/src/deployment-bundle/find-additional-modules.ts index eb8cd66a242d..55ee98d2ba2c 100644 --- a/packages/wrangler/src/deployment-bundle/find-additional-modules.ts +++ b/packages/wrangler/src/deployment-bundle/find-additional-modules.ts @@ -45,7 +45,6 @@ function isValidPythonPackageName(name: string): boolean { * that match the given `rules`. */ export async function findAdditionalModules( - projectRoot: string, entry: Entry, rules: Rule[] | ParsedRules, attachSourcemaps = false @@ -73,7 +72,7 @@ export async function findAdditionalModules( let pythonRequirements = ""; try { pythonRequirements = await readFile( - path.resolve(projectRoot, "requirements.txt"), + path.resolve(entry.projectRoot, "requirements.txt"), "utf-8" ); } catch (e) { diff --git a/packages/wrangler/src/deployment-bundle/module-collection.ts b/packages/wrangler/src/deployment-bundle/module-collection.ts index 1fd051b4cfbf..8087d0ac8a62 100644 --- a/packages/wrangler/src/deployment-bundle/module-collection.ts +++ b/packages/wrangler/src/deployment-bundle/module-collection.ts @@ -70,7 +70,6 @@ export const noopModuleCollector: ModuleCollector = { }; export function createModuleCollector(props: { - projectRoot: string; entry: Entry; findAdditionalModules: boolean; rules?: Config["rules"]; @@ -107,11 +106,7 @@ export function createModuleCollector(props: { return { errors: [{ text: error }] }; } - const found = await findAdditionalModules( - props.projectRoot, - props.entry, - parsedRules - ); + const found = await findAdditionalModules(props.entry, parsedRules); foundModulePaths = found.map(({ name }) => path.resolve(props.entry.moduleRoot, name) ); diff --git a/packages/wrangler/src/deployment-bundle/resolve-entry.ts b/packages/wrangler/src/deployment-bundle/resolve-entry.ts index 1568bfd1464a..2da92e262709 100644 --- a/packages/wrangler/src/deployment-bundle/resolve-entry.ts +++ b/packages/wrangler/src/deployment-bundle/resolve-entry.ts @@ -12,28 +12,32 @@ export function resolveEntryWithScript(script: string): { export function resolveEntryWithMain( main: string, - projectRoot: string + configPath?: string ): { absolutePath: string; relativePath: string; + projectRoot: string; } { + const projectRoot = path.resolve(path.dirname(configPath ?? ".")); const file = path.resolve(projectRoot, main); const relativePath = path.relative(projectRoot, file) || "."; - return { absolutePath: file, relativePath }; + return { absolutePath: file, relativePath, projectRoot }; } export function resolveEntryWithEntryPoint( entryPoint: string, - projectRoot: string + configPath?: string ): { absolutePath: string; relativePath: string; + projectRoot: string; } { + const projectRoot = path.resolve(path.dirname(configPath ?? ".")); const file = path.extname(entryPoint) ? path.resolve(entryPoint) : path.resolve(entryPoint, "index.js"); const relativePath = path.relative(projectRoot, file) || "."; - return { absolutePath: file, relativePath }; + return { absolutePath: file, relativePath, projectRoot }; } export function resolveEntryWithAssets(): { diff --git a/packages/wrangler/src/dev/use-esbuild.ts b/packages/wrangler/src/dev/use-esbuild.ts index 406230239653..0e2bdad78008 100644 --- a/packages/wrangler/src/dev/use-esbuild.ts +++ b/packages/wrangler/src/dev/use-esbuild.ts @@ -82,7 +82,7 @@ export function runBuild( local: boolean; targetConsumer: "dev" | "deploy"; testScheduled: boolean; - projectRoot: string; + projectRoot: string | undefined; onStart: () => void; defineNavigatorUserAgent: boolean; checkFetch: boolean; @@ -98,7 +98,6 @@ export function runBuild( const moduleCollector = noBundle ? noopModuleCollector : createModuleCollector({ - projectRoot: projectRoot, wrangler1xLegacyModuleReferences: getWrangler1xLegacyModuleReferences( entryDirectory, entry.file @@ -111,7 +110,7 @@ export function runBuild( async function getAdditionalModules() { return noBundle ? dedupeModulesByName([ - ...((await doFindAdditionalModules(projectRoot, entry, rules)) ?? []), + ...((await doFindAdditionalModules(entry, rules)) ?? []), ...additionalModules, ]) : additionalModules; @@ -194,7 +193,7 @@ export function runBuild( // Check whether we need to watch a Python requirements.txt file. const watchPythonRequirements = getBundleType(entry.format, entry.file) === "python" - ? path.resolve(projectRoot, "requirements.txt") + ? path.resolve(entry.projectRoot, "requirements.txt") : undefined; if (watchPythonRequirements) { diff --git a/packages/wrangler/src/pages/functions/buildPlugin.ts b/packages/wrangler/src/pages/functions/buildPlugin.ts index 4c5f5deb84c6..2ac907f29ae0 100644 --- a/packages/wrangler/src/pages/functions/buildPlugin.ts +++ b/packages/wrangler/src/pages/functions/buildPlugin.ts @@ -29,12 +29,12 @@ export function buildPluginFromFunctions({ }: Options) { const entry: Entry = { file: resolve(getBasePath(), "templates/pages-template-plugin.ts"), + projectRoot: functionsDirectory, format: "modules", moduleRoot: functionsDirectory, exports: [], }; const moduleCollector = createModuleCollector({ - projectRoot: functionsDirectory, entry, findAdditionalModules: false, }); diff --git a/packages/wrangler/src/pages/functions/buildWorker.ts b/packages/wrangler/src/pages/functions/buildWorker.ts index 1856191f08fb..95c9e4cc4b5b 100644 --- a/packages/wrangler/src/pages/functions/buildWorker.ts +++ b/packages/wrangler/src/pages/functions/buildWorker.ts @@ -11,7 +11,7 @@ import { import { FatalError } from "../../errors"; import { logBuildFailure, logger } from "../../logger"; import { getBasePath } from "../../paths"; -import { getPagesTmpDir } from "../utils"; +import { getPagesProjectRoot, getPagesTmpDir } from "../utils"; import type { BundleResult } from "../../deployment-bundle/bundle"; import type { Entry } from "../../deployment-bundle/entry"; import type { CfModule } from "../../deployment-bundle/worker"; @@ -55,12 +55,12 @@ export function buildWorkerFromFunctions({ }: Options) { const entry: Entry = { file: resolve(getBasePath(), "templates/pages-template-worker.ts"), + projectRoot: functionsDirectory, format: "modules", moduleRoot: functionsDirectory, exports: [], }; const moduleCollector = createModuleCollector({ - projectRoot: functionsDirectory, entry, findAdditionalModules: false, }); @@ -90,7 +90,7 @@ export function buildWorkerFromFunctions({ checkFetch: local && checkFetch, targetConsumer: local ? "dev" : "deploy", local, - projectRoot: functionsDirectory, + projectRoot: getPagesProjectRoot(), defineNavigatorUserAgent, legacyAssets: undefined, @@ -151,17 +151,14 @@ export function buildRawWorker({ }: RawOptions) { const entry: Entry = { file: workerScriptPath, + projectRoot: resolve(directory), format: "modules", moduleRoot: resolve(directory), exports: [], }; const moduleCollector = externalModules ? noopModuleCollector - : createModuleCollector({ - projectRoot: resolve(directory), - entry, - findAdditionalModules: false, - }); + : createModuleCollector({ entry, findAdditionalModules: false }); return bundleWorker(entry, outdir ? resolve(outdir) : resolve(outfile), { bundle, @@ -207,7 +204,7 @@ export function buildRawWorker({ checkFetch: local && checkFetch, targetConsumer: local ? "dev" : "deploy", local, - projectRoot: resolve(directory), + projectRoot: getPagesProjectRoot(), defineNavigatorUserAgent, legacyAssets: undefined, @@ -241,9 +238,9 @@ export async function produceWorkerBundleForWorkerJSDirectory({ const entrypoint = resolve(join(workerJSDirectory, "index.js")); const additionalModules = await findAdditionalModules( - resolve(workerJSDirectory), { file: entrypoint, + projectRoot: resolve(workerJSDirectory), format: "modules", moduleRoot: resolve(workerJSDirectory), exports: [], diff --git a/packages/wrangler/src/versions/upload.ts b/packages/wrangler/src/versions/upload.ts index 791b33afd875..5bee1b4049cc 100644 --- a/packages/wrangler/src/versions/upload.ts +++ b/packages/wrangler/src/versions/upload.ts @@ -89,6 +89,7 @@ type Props = { dryRun: boolean | undefined; noBundle: boolean | undefined; keepVars: boolean | undefined; + projectRoot: string | undefined; tag: string | undefined; message: string | undefined; @@ -357,7 +358,7 @@ export const versionsUploadCommand = createCommand({ await verifyWorkerMatchesCITag( accountId, name, - path.relative(config.projectRoot, config.configPath ?? "wrangler.toml") + path.relative(entry.projectRoot, config.configPath ?? "wrangler.toml") ); } @@ -391,6 +392,7 @@ export const versionsUploadCommand = createCommand({ dryRun: args.dryRun, noBundle: !(args.bundle ?? !config.no_bundle), keepVars: false, + projectRoot: entry.projectRoot, tag: args.tag, message: args.message, }); @@ -531,7 +533,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m } const destination = - props.outDir ?? getWranglerTmpDir(props.config.projectRoot, "deploy"); + props.outDir ?? getWranglerTmpDir(props.projectRoot, "deploy"); const start = Date.now(); const workerName = scriptName; @@ -573,7 +575,6 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m const entryDirectory = path.dirname(props.entry.file); const moduleCollector = createModuleCollector({ - projectRoot: props.config.projectRoot, wrangler1xLegacyModuleReferences: getWrangler1xLegacyModuleReferences( entryDirectory, props.entry.file @@ -594,12 +595,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m bundleType, ...bundle } = props.noBundle - ? await noBundleWorker( - props.config.projectRoot, - props.entry, - props.rules, - props.outDir - ) + ? await noBundleWorker(props.entry, props.rules, props.outDir) : await bundleWorker( props.entry, typeof destination === "string" ? destination : destination.path, @@ -627,7 +623,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m // This could potentially cause issues as we no longer have identical behaviour between dev and deploy? targetConsumer: "deploy", local: false, - projectRoot: props.config.projectRoot, + projectRoot: props.projectRoot, defineNavigatorUserAgent: isNavigatorDefined( props.compatibilityDate ?? config.compatibility_date, props.compatibilityFlags ?? config.compatibility_flags @@ -899,12 +895,11 @@ function formatTime(duration: number) { } async function noBundleWorker( - projectRoot: string, entry: Entry, rules: Rule[], outDir: string | undefined ) { - const modules = await findAdditionalModules(projectRoot, entry, rules); + const modules = await findAdditionalModules(entry, rules); if (outDir) { await writeAdditionalModules(modules, outDir); }