Skip to content

Commit 7d20bdb

Browse files
Add find_additional_modules option to support partial bundling with externals (#3726)
* typo * move stuff * remove unnecessary typing * remove unnecessary `active` property from middleware loader config * more refactorings * rename traverseModuleGraph as this is not what it does * refactor to simplify findAdditionalModules() * Rename the functions build helpers to make it more clear what their role is. * invert module collector config - no longer need to return it as it is passed in * implement module finding in normal bundling if the find_additional_modules flag is on * allow `__STATIC_CONTENT_MANIFEST` to be imported from any module * test: improve no-bundle-import tests The no-bundle-import tests would actually pass if Wrangler actually bundled the code, since it would identify and inline all the dynamic imports that were being tested. This change adds a test that would not pass if we are not capturing the additional modules. It also moves the declaration of no-bundle to the wrangler.toml to ensure that normal use of `wrangler dev` will get this behavior. * refactor: convert additional file finding to a generator function This has a few of benefits: - we don't risk creating too many file reads in a single go (using up all the available file handles); previously file reads were all done in parallel - we don't read the files over and over for each rule - the code is a bit easier to follow as we don't have to create `Promise.all()` objects * fix: ensure that additional modules appear in the out-dir When using `find_additional_modules` (or `no_bundle`) we find files that will be uploaded to be deployed alongside the Worker. Previously, if an `outDir` was specified, only the Worker code was output to this directory. Now all additional modules are also output there too. * pnpm fixups * test: ignore failure to remove tmp dir on Windows * test: do not show output in d1 time-travel tests * refactor: consolidate writing additional modules * test: add CommonJS lazy import to additional-modules fixture * test: rename spec to test * Add debug logging when writing additional modules * Test additional module failure case and fix message typo * Display build warnings before updating the bundle --------- Co-authored-by: bcoll <[email protected]>
1 parent 5fc7a88 commit 7d20bdb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1834
-1080
lines changed

.changeset/blue-donkeys-pretend.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
fix: ensure that additional modules appear in the out-dir
6+
7+
When using `find_additional_modules` (or `no_bundle`) we find files that
8+
will be uploaded to be deployed alongside the Worker.
9+
10+
Previously, if an `outDir` was specified, only the Worker code was output
11+
to this directory. Now all additional modules are also output there too.

.changeset/clever-turkeys-leave.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
"wrangler": minor
3+
---
4+
5+
feat: support partial bundling with configurable external modules
6+
7+
Setting `find_additional_modules` to `true` in your configuration file will now instruct Wrangler to look for files in
8+
your `base_dir` that match your configured `rules`, and deploy them as unbundled, external modules with your Worker.
9+
`base_dir` defaults to the directory containing your `main` entrypoint.
10+
11+
Wrangler can operate in two modes: the default bundling mode and `--no-bundle` mode. In bundling mode, dynamic imports
12+
(e.g. `await import("./large-dep.mjs")`) would be bundled into your entrypoint, making lazy loading less effective.
13+
Additionally, variable dynamic imports (e.g. `` await import(`./lang/${language}.mjs`) ``) would always fail at runtime,
14+
as Wrangler would have no way of knowing which modules to upload. The `--no-bundle` mode sought to address these issues
15+
by disabling Wrangler's bundling entirely, and just deploying code as is. Unfortunately, this also disabled Wrangler's
16+
code transformations (e.g. TypeScript compilation, `--assets`, `--test-scheduled`, etc).
17+
18+
With this change, we now additionally support _partial bundling_. Files are bundled into a single Worker entry-point file
19+
unless `find_additional_modules` is `true`, and the file matches one of the configured `rules`. See
20+
https://developers.cloudflare.com/workers/wrangler/bundling/ for more details and examples.

.changeset/hot-deers-return.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
fix: allow `__STATIC_CONTENT_MANIFEST` module to be imported anywhere
6+
7+
`__STATIC_CONTENT_MANIFEST` can now be imported in subdirectories when
8+
`--no-bundle` or `find_additional_modules` are enabled.

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ packages/wrangler/CHANGELOG.md
77
packages/jest-environment-wrangler/CHANGELOG.md
88
packages/wranglerjs-compat-webpack-plugin/lib
99
packages/wrangler-devtools/built-devtools
10+
packages/wrangler-devtools/.cipd
11+
packages/wrangler-devtools/depot
12+
packages/wrangler-devtools/devtools-frontend
1013
packages/edge-preview-authenticated-proxy/package.json
1114
packages/format-errors/package.json
1215
packages/**/dist/**
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "additional-modules",
3+
"version": "0.0.1",
4+
"private": true,
5+
"scripts": {
6+
"build": "wrangler deploy --dry-run --outdir=dist",
7+
"check:type": "tsc",
8+
"deploy": "wrangler deploy",
9+
"start": "wrangler dev",
10+
"test": "vitest run",
11+
"test:ci": "vitest run",
12+
"test:watch": "vitest",
13+
"type:tests": "tsc -p ./test/tsconfig.json"
14+
},
15+
"devDependencies": {
16+
"@cloudflare/workers-tsconfig": "workspace:*",
17+
"@cloudflare/workers-types": "^4.20230724.0",
18+
"undici": "^5.9.1",
19+
"wrangler": "workspace:*"
20+
}
21+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = "common";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default "bundled";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default "dynamic";
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import dep from "./dep";
2+
import text from "./text.txt";
3+
import common from "./common.cjs";
4+
5+
export default <ExportedHandler>{
6+
async fetch(request) {
7+
const url = new URL(request.url);
8+
if (url.pathname === "/dep") {
9+
return new Response(dep);
10+
}
11+
if (url.pathname === "/text") {
12+
return new Response(text);
13+
}
14+
if (url.pathname === "/common") {
15+
return new Response(common);
16+
}
17+
if (url.pathname === "/dynamic") {
18+
return new Response((await import("./dynamic.js")).default);
19+
}
20+
if (url.pathname.startsWith("/lang/")) {
21+
// Build the path dynamically to ensure esbuild doesn't inline the import.
22+
const language =
23+
"./lang/" + url.pathname.substring("/lang/".length) + ".js";
24+
return new Response((await import(language)).default.hello);
25+
}
26+
return new Response("Not Found", { status: 404 });
27+
},
28+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default { hello: "hello" };

0 commit comments

Comments
 (0)