Skip to content

Commit 2f5c272

Browse files
committed
allow __STATIC_CONTENT_MANIFEST to be imported from any module
1 parent bef4e56 commit 2f5c272

File tree

3 files changed

+86
-7
lines changed

3 files changed

+86
-7
lines changed

.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,

packages/wrangler/src/__tests__/deploy.test.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,8 +2182,10 @@ addEventListener('fetch', event => {});`
21822182

21832183
it("when using a module worker type, it should add an asset manifest module, and bind to a namespace", async () => {
21842184
const assets = [
2185-
{ filePath: "file-1.txt", content: "Content of file-1" },
2186-
{ filePath: "file-2.txt", content: "Content of file-2" },
2185+
// Using `.text` extension instead of `.txt` means files won't be
2186+
// treated as additional modules
2187+
{ filePath: "file-1.text", content: "Content of file-1" },
2188+
{ filePath: "file-2.text", content: "Content of file-2" },
21872189
];
21882190
const kvNamespace = {
21892191
title: "__test-name-workers_sites_assets",
@@ -2194,8 +2196,27 @@ addEventListener('fetch', event => {});`
21942196
site: {
21952197
bucket: "assets",
21962198
},
2199+
find_additional_modules: true,
2200+
rules: [{ type: "ESModule", globs: ["**/*.mjs"] }],
21972201
});
21982202
writeWorkerSource({ type: "esm" });
2203+
fs.mkdirSync("a/b/c", { recursive: true });
2204+
fs.writeFileSync(
2205+
"a/1.mjs",
2206+
'export { default } from "__STATIC_CONTENT_MANIFEST";'
2207+
);
2208+
fs.writeFileSync(
2209+
"a/b/2.mjs",
2210+
'export { default } from "__STATIC_CONTENT_MANIFEST";'
2211+
);
2212+
fs.writeFileSync(
2213+
"a/b/3.mjs",
2214+
'export { default } from "__STATIC_CONTENT_MANIFEST";'
2215+
);
2216+
fs.writeFileSync(
2217+
"a/b/c/4.mjs",
2218+
'export { default } from "__STATIC_CONTENT_MANIFEST";'
2219+
);
21992220
writeAssets(assets);
22002221
mockUploadWorkerRequest({
22012222
expectedBindings: [
@@ -2207,7 +2228,13 @@ addEventListener('fetch', event => {});`
22072228
],
22082229
expectedModules: {
22092230
__STATIC_CONTENT_MANIFEST:
2210-
'{"file-1.txt":"file-1.2ca234f380.txt","file-2.txt":"file-2.5938485188.txt"}',
2231+
'{"file-1.text":"file-1.2ca234f380.text","file-2.text":"file-2.5938485188.text"}',
2232+
"a/__STATIC_CONTENT_MANIFEST":
2233+
'export { default } from "../__STATIC_CONTENT_MANIFEST";',
2234+
"a/b/__STATIC_CONTENT_MANIFEST":
2235+
'export { default } from "../../__STATIC_CONTENT_MANIFEST";',
2236+
"a/b/c/__STATIC_CONTENT_MANIFEST":
2237+
'export { default } from "../../../__STATIC_CONTENT_MANIFEST";',
22112238
},
22122239
});
22132240
mockSubDomainRequest();
@@ -2218,10 +2245,15 @@ addEventListener('fetch', event => {});`
22182245
await runWrangler("deploy");
22192246

22202247
expect(std.info).toMatchInlineSnapshot(`
2221-
"Fetching list of already uploaded assets...
2248+
"Attaching additional modules:
2249+
- a/1.mjs (esm)
2250+
- a/b/2.mjs (esm)
2251+
- a/b/3.mjs (esm)
2252+
- a/b/c/4.mjs (esm)
2253+
Fetching list of already uploaded assets...
22222254
Building list of assets to upload...
2223-
+ file-1.2ca234f380.txt (uploading new version of file-1.txt)
2224-
+ file-2.5938485188.txt (uploading new version of file-2.txt)
2255+
+ file-1.2ca234f380.text (uploading new version of file-1.text)
2256+
+ file-2.5938485188.text (uploading new version of file-2.text)
22252257
Uploading 2 new assets...
22262258
Uploaded 100% [2 out of 2]"
22272259
`);

packages/wrangler/src/deploy/deploy.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,11 +569,50 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
569569
};
570570

571571
if (assets.manifest) {
572+
const manifestModuleName = "__STATIC_CONTENT_MANIFEST";
572573
modules.push({
573-
name: "__STATIC_CONTENT_MANIFEST",
574+
name: manifestModuleName,
574575
content: JSON.stringify(assets.manifest),
575576
type: "text",
576577
});
578+
579+
// Each modules-format worker has a virtual file system for module
580+
// resolution. For example, uploading modules with names `1.mjs`,
581+
// `a/2.mjs` and `a/b/3.mjs`, creates virtual directories `a` and `a/b`.
582+
// `1.mjs` is in the virtual root directory.
583+
//
584+
// The above code adds the `__STATIC_CONTENT_MANIFEST` module to the root
585+
// directory. This means `import manifest from "__STATIC_CONTENT_MANIFEST"`
586+
// will only work if the importing module is also in the root. If the
587+
// importing module was `a/b/3.mjs` for example, the import would need to
588+
// be `import manifest from "../../__STATIC_CONTENT_MANIFEST"`.
589+
//
590+
// When Wrangler bundles all user code, this isn't a problem, as code is
591+
// only ever uploaded to the root. However, once `--no-bundle` or
592+
// `find_additional_modules` is enabled, the user controls the directory
593+
// structure.
594+
//
595+
// To fix this, if we've got a modules-format worker, we add stub modules
596+
// in each subdirectory that re-export the manifest module from the root.
597+
// This allows the manifest to be imported as `__STATIC_CONTENT_MANIFEST`
598+
// in every directory, whilst avoiding duplication of the manifest.
599+
if (format === "modules") {
600+
// Collect unique subdirectories
601+
const subDirs = new Set(
602+
modules.map((module) => path.posix.dirname(module.name))
603+
);
604+
for (const subDir of subDirs) {
605+
// Ignore `.` as it's not a subdirectory, and we don't want to
606+
// register the manifest module in the root twice.
607+
if (subDir === ".") continue;
608+
const relativePath = path.posix.relative(subDir, manifestModuleName);
609+
modules.push({
610+
name: path.posix.join(subDir, manifestModuleName),
611+
content: `export { default } from ${JSON.stringify(relativePath)};`,
612+
type: "esm",
613+
});
614+
}
615+
}
577616
}
578617

579618
// The upload API only accepts an empty string or no specified placement for the "off" mode.

0 commit comments

Comments
 (0)