Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tidy-ravens-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": minor
---

Include exact raw and gzip-compressed Worker bundle sizes in structured `deploy` and `version-upload` output.
18 changes: 11 additions & 7 deletions packages/deploy-helpers/src/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import {
syncAssets,
} from "./helpers/assets";
import { getBindings } from "./helpers/binding-utils";
import { printBundleSize } from "./helpers/bundle-reporter";
import {
getSize,
printBundleSize,
type BundleSize,
} from "./helpers/bundle-reporter";
import { confirmLatestDeploymentOverwrite } from "./helpers/confirm-latest-deployment-overwrite";
import { createWorkerUploadForm } from "./helpers/create-worker-upload-form";
import { deployWfpUserWorker } from "./helpers/deploy-wfp";
Expand Down Expand Up @@ -144,6 +148,7 @@ export default async function deploy(
workerTag: string | null;
assetUploadStats?: AssetUploadStats;
targets?: string[];
bundleSize?: BundleSize;
}> {
const { entry, compatibilityDate, compatibilityFlags, keepVars, accountId } =
props;
Expand Down Expand Up @@ -340,10 +345,8 @@ export default async function deploy(
0
);

await printBundleSize(
{ name: path.basename(resolvedEntryPointPath), content: content },
modules
);
const bundleSize = await getSize([...modules, { content }]);
printBundleSize(bundleSize);

// We can use the new versions/deployments APIs if we:
// * are uploading a worker that already exists
Expand Down Expand Up @@ -719,7 +722,7 @@ export default async function deploy(

if (isDryRun) {
logger.log(`--dry-run: exiting now.`);
return { versionId, workerTag };
return { versionId, workerTag, bundleSize };
}

const uploadMs = Date.now() - start;
Expand All @@ -742,7 +745,7 @@ export default async function deploy(
// Early exit for WfP since it doesn't need the below code
if (props.dispatchNamespace !== undefined) {
deployWfpUserWorker(props.dispatchNamespace, versionId);
return { versionId, workerTag, assetUploadStats };
return { versionId, workerTag, assetUploadStats, bundleSize };
}
assert(accountId);
// deploy triggers
Expand All @@ -765,5 +768,6 @@ export default async function deploy(
workerTag,
assetUploadStats,
targets: targets ?? [],
bundleSize,
};
}
19 changes: 9 additions & 10 deletions packages/deploy-helpers/src/deploy/helpers/bundle-reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ const ONE_KIB_BYTES = 1024;
// See https://developers.cloudflare.com/workers/platform/limits/#worker-size
const MAX_GZIP_SIZE_BYTES = 3 * ONE_KIB_BYTES * ONE_KIB_BYTES;

async function getSize(modules: Pick<CfModule, "content">[]) {
export interface BundleSize {
size: number;
gzipSize: number;
}

export async function getSize(
modules: Pick<CfModule, "content">[]
): Promise<BundleSize> {
const gzipSize = gzipSync(
await new Blob(modules.map((file) => file.content)).arrayBuffer()
).byteLength;
Expand All @@ -18,15 +25,7 @@ async function getSize(modules: Pick<CfModule, "content">[]) {
return { size: aggregateSize, gzipSize };
}

export async function printBundleSize(
main: {
name: string;
content: string;
},
modules: CfModule[]
) {
const { size, gzipSize } = await getSize([...modules, main]);

export function printBundleSize({ size, gzipSize }: BundleSize) {
const bundleReport = `${(size / ONE_KIB_BYTES).toFixed(2)} KiB / gzip: ${(
gzipSize / ONE_KIB_BYTES
).toFixed(2)} KiB`;
Expand Down
16 changes: 10 additions & 6 deletions packages/deploy-helpers/src/deploy/versions-upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import { getWorkersDevSubdomain } from "../triggers/subdomain";
import { resolveAssetOptions, syncAssets } from "./helpers/assets";
import { renderBindingDependsOnExportError } from "./helpers/binding-depends-on-export";
import { getBindings } from "./helpers/binding-utils";
import { printBundleSize } from "./helpers/bundle-reporter";
import {
getSize,
printBundleSize,
type BundleSize,
} from "./helpers/bundle-reporter";
import { createWorkerUploadForm } from "./helpers/create-worker-upload-form";
import {
applyServiceAndEnvironmentTags,
Expand Down Expand Up @@ -63,6 +67,7 @@ export default async function versionsUpload(
assetUploadStats?: AssetUploadStats;
versionPreviewUrl?: string | undefined;
versionPreviewAliasUrl?: string | undefined;
bundleSize?: BundleSize;
}> {
const { entry, compatibilityDate, compatibilityFlags, keepVars, accountId } =
props;
Expand Down Expand Up @@ -199,10 +204,8 @@ export default async function versionsUpload(
: undefined,
};

await printBundleSize(
{ name: path.basename(resolvedEntryPointPath), content: content },
modules
);
const bundleSize = await getSize([...modules, { content }]);
printBundleSize(bundleSize);

let workerBundle: FormData;

Expand Down Expand Up @@ -382,7 +385,7 @@ export default async function versionsUpload(

if (props.dryRun) {
logger.log(`--dry-run: exiting now.`);
return { versionId, workerTag };
return { versionId, workerTag, bundleSize };
}
assert(accountId);

Expand Down Expand Up @@ -433,5 +436,6 @@ Changes to triggers (routes, custom domains, cron schedules, etc) must be applie
assetUploadStats: assetsUploadResult?.assetUploadStats,
versionPreviewUrl,
versionPreviewAliasUrl,
bundleSize,
};
}
25 changes: 15 additions & 10 deletions packages/wrangler/src/__tests__/deploy/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import {
import * as esbuild from "esbuild";
import { http, HttpResponse } from "msw";
import { afterEach, beforeEach, describe, it, test, vi } from "vitest";
import { printBundleSize } from "../../deployment-bundle/bundle-reporter";
import {
getSize,
printBundleSize,
} from "../../deployment-bundle/bundle-reporter";
import { clearOutputFilePath } from "../../output";
import { diagnoseScriptSizeError } from "../../utils/friendly-validator-errors";
import { mockAccountId, mockApiToken } from "../helpers/mock-account-id";
Expand Down Expand Up @@ -1117,17 +1120,19 @@ export default { fetch() { return new Response(foo); } }`
// keeping these as unit tests to try and keep them snappy, as they often deal with
// big files that would take a while to deal with in a full wrangler test

test("should print the bundle size", async ({ expect }) => {
test("should calculate the bundle size", async ({ expect }) => {
const bigModule = Buffer.alloc(10_000_000);
randomFillSync(bigModule);
await printBundleSize({ name: "index.js", content: "" }, [
{
name: "index.js",
filePath: undefined,
content: bigModule,
type: "buffer",
},
]);
const bundleSize = await getSize([{ content: bigModule }]);

expect(bundleSize).toEqual({
size: 10_000_000,
gzipSize: expect.any(Number),
});
});

test("should print the bundle size", ({ expect }) => {
printBundleSize({ size: 10_000_000, gzipSize: 10_000_000 });

expect(std).toMatchInlineSnapshot(`
{
Expand Down
8 changes: 7 additions & 1 deletion packages/wrangler/src/__tests__/deploy/core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,13 @@ describe("deploy", () => {
.map((line) => JSON.parse(line)) as OutputEntry[];

expect(outputEntries).toContainEqual(
expect.objectContaining({ type: "deploy" })
expect.objectContaining({
type: "deploy",
bundle_size: {
raw_bytes: expect.any(Number),
gzip_bytes: expect.any(Number),
},
})
);

const autoconfigOutputEntry = outputEntries.find(
Expand Down
25 changes: 16 additions & 9 deletions packages/wrangler/src/deploy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
import { experimentalNewConfigArg } from "../experimental-config/cli-flag";
import { logger } from "../logger";
import * as metrics from "../metrics";
import { writeOutput } from "../output";
import { formatBundleSizeOutput, writeOutput } from "../output";
import { syncWorkersSite } from "../sites";
import { detectAgent } from "../utils/detect-agent";
import { getScriptName } from "../utils/getScriptName";
Expand Down Expand Up @@ -195,14 +195,20 @@ export async function runDeployCommandHandler(

const buildResult = await buildWorker(buildProps, config);

const { sourceMapSize, versionId, workerTag, assetUploadStats, targets } =
await deploy(props, config, buildResult, {
syncWorkersSite,
getNormalizedContainerOptions,
buildContainer,
deployContainers,
analyseBundle,
});
const {
sourceMapSize,
versionId,
workerTag,
assetUploadStats,
targets,
bundleSize,
} = await deploy(props, config, buildResult, {
syncWorkersSite,
getNormalizedContainerOptions,
buildContainer,
deployContainers,
analyseBundle,
});

writeOutput({
type: "deploy",
Expand All @@ -213,6 +219,7 @@ export async function runDeployCommandHandler(
targets,
wrangler_environment: args.env,
worker_name_overridden: workerNameOverridden,
bundle_size: formatBundleSizeOutput(bundleSize),
});

metrics.sendMetricsEvent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { printBundleSize } from "@cloudflare/deploy-helpers";
export { getSize, printBundleSize } from "@cloudflare/deploy-helpers";
10 changes: 2 additions & 8 deletions packages/wrangler/src/dev/remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from "node:path";
import { syncAssets } from "@cloudflare/deploy-helpers";
import { APIError, UserError } from "@cloudflare/workers-utils";
import { isAuthenticationError } from "../core/handle-errors";
import { printBundleSize } from "../deployment-bundle/bundle-reporter";
import { getSize, printBundleSize } from "../deployment-bundle/bundle-reporter";
import { getBundleType } from "../deployment-bundle/bundle-type";
import { withSourceURLs } from "../deployment-bundle/source-url";
import { getInferredHost } from "../dev";
Expand Down Expand Up @@ -164,13 +164,7 @@ export async function createRemoteWorkerInit(props: {
);

// TODO: For Dev we could show the reporter message in the interactive box.
void printBundleSize(
{
name: path.basename(props.bundle.path),
content,
},
props.modules
);
void getSize([...props.modules, { content }]).then(printBundleSize);

const workersSitesAssets = await syncWorkersSite(
props.complianceConfig,
Expand Down
21 changes: 21 additions & 0 deletions packages/wrangler/src/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from "@cloudflare/workers-utils";
import { ensureDirectoryExistsSync } from "./utils/filesystem";
import type { AutoConfigSummary } from "@cloudflare/autoconfig";
import type { BundleSize } from "@cloudflare/deploy-helpers";

/**
* Write an entry to the output file.
Expand All @@ -33,6 +34,15 @@ export function clearOutputFilePath() {
outputFilePath = undefined;
}

export function formatBundleSizeOutput(bundleSize: BundleSize | undefined) {
return bundleSize
? {
raw_bytes: bundleSize.size,
gzip_bytes: bundleSize.gzipSize,
}
: undefined;
}

let outputFilePath: string | null | undefined = undefined;
function getOutputFilePath() {
const outputFilePathFromEnv = getOutputFilePathFromEnv();
Expand Down Expand Up @@ -63,6 +73,13 @@ interface OutputEntryBase<T extends string> {
type: T;
}

interface OutputEntryBundleSize {
/** The uncompressed size of the Worker bundle. */
raw_bytes: number;
/** The gzip-compressed size of the Worker bundle. */
gzip_bytes: number;
}

/**
* All the different types of entry you can output.
*/
Expand Down Expand Up @@ -101,6 +118,8 @@ interface OutputEntryDeployment extends OutputEntryBase<"deploy"> {
worker_name_overridden: boolean;
/** wrangler environment used */
wrangler_environment: string | undefined;
/** Exact Worker bundle sizes in bytes. */
bundle_size?: OutputEntryBundleSize;
}

interface OutputEntryPreview extends OutputEntryBase<"preview"> {
Expand Down Expand Up @@ -177,6 +196,8 @@ interface OutputEntryVersionUpload extends OutputEntryBase<"version-upload"> {
worker_name_overridden: boolean;
/** wrangler environment used */
wrangler_environment: string | undefined;
/** Exact Worker bundle sizes in bytes. */
bundle_size?: OutputEntryBundleSize;
}

interface OutputEntryVersionDeployment extends OutputEntryBase<"version-deploy"> {
Expand Down
4 changes: 3 additions & 1 deletion packages/wrangler/src/versions/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from "../deployment-bundle/merge-config-args";
import { experimentalNewConfigArg } from "../experimental-config/cli-flag";
import * as metrics from "../metrics";
import { writeOutput } from "../output";
import { formatBundleSizeOutput, writeOutput } from "../output";
import { getScriptName } from "../utils/getScriptName";

export const versionsUploadCommand = createCommand({
Expand Down Expand Up @@ -70,6 +70,7 @@ export const versionsUploadCommand = createCommand({
assetUploadStats: uploadStats,
versionPreviewUrl,
versionPreviewAliasUrl,
bundleSize,
} = await versionsUpload(props, config, buildResult, {
analyseBundle: analyseBundle,
});
Expand All @@ -85,6 +86,7 @@ export const versionsUploadCommand = createCommand({
preview_alias_url: versionPreviewAliasUrl,
wrangler_environment: args.env,
worker_name_overridden: workerNameOverridden,
bundle_size: formatBundleSizeOutput(bundleSize),
});
} finally {
metrics.sendMetricsEvent(
Expand Down