Skip to content

Commit

Permalink
Allow __STATIC_CONTENT_MANIFEST to be imported from any directory
Browse files Browse the repository at this point in the history
Previously, `import manifest from "__STATIC_CONTENT_MANIFEST"` was
only allowed in the "root" directory of the modules virtual
file-system. This change adds stub modules for each additional module
in each subdirectory, that re-export the module. This allows the
manifest to be imported in any directory.
  • Loading branch information
mrbbot committed Aug 21, 2023
1 parent 195a900 commit 0e73c59
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 6 deletions.
33 changes: 28 additions & 5 deletions packages/miniflare/src/plugins/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import assert from "assert";
import { readFileSync } from "fs";
import fs from "fs/promises";
import path from "path";
import tls from "tls";
import { TextEncoder } from "util";
import { bold } from "kleur/colors";
Expand Down Expand Up @@ -374,10 +375,7 @@ export const CORE_PLUGIN: Plugin<
sourceMapRegistry,
}) {
// Define regular user worker
const additionalModuleNames = additionalModules.map(({ name }) => {
assert(name !== undefined);
return name;
});
const additionalModuleNames = additionalModules.map(({ name }) => name);
const workerScript = getWorkerScript(
sourceMapRegistry,
options,
Expand All @@ -386,7 +384,32 @@ export const CORE_PLUGIN: Plugin<
);
// Add additional modules (e.g. "__STATIC_CONTENT_MANIFEST") if any
if ("modules" in workerScript) {
workerScript.modules.push(...additionalModules);
const subDirs = new Set(
workerScript.modules.map(({ name }) => path.posix.dirname(name))
);
// Ignore `.` as it's not a subdirectory, and we don't want to register
// additional modules in the root twice.
subDirs.delete(".");

for (const module of additionalModules) {
workerScript.modules.push(module);
// In addition to adding the module, we add stub modules in each
// subdirectory re-exporting each additional module. These allow
// additional modules to be imported in every directory.
for (const subDir of subDirs) {
const relativePath = path.posix.relative(subDir, module.name);
const relativePathString = JSON.stringify(relativePath);
workerScript.modules.push({
name: path.posix.join(subDir, module.name),
// TODO(someday): if we ever have additional modules without
// default exports, this may be a problem. For now, our only
// additional module is `__STATIC_CONTENT_MANIFEST` so it's fine.
// If needed, we could look for instances of `export default` or
// `as default` in the module's code as a heuristic.
esModule: `export * from ${relativePathString}; export { default } from ${relativePathString};`,
});
}
}
}

const name = getUserServiceName(options.name);
Expand Down
2 changes: 1 addition & 1 deletion packages/miniflare/src/runtime/config/workerd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export type Worker_DurableObjectStorage =
| { localDisk?: string };

export type Worker_Module = {
name?: string;
name: string;
} & (
| { esModule?: string }
| { commonJsModule?: string }
Expand Down
56 changes: 56 additions & 0 deletions packages/miniflare/test/plugins/kv/sites.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,62 @@ test("gets assets with module worker", async (t) => {
t.is(await res.text(), "nested");
});

test("can import manifest from any directory", async (t) => {
const tmp = await useTmp(t);
const testPath = path.join(tmp, "test.txt");
await fs.writeFile(testPath, "test", "utf8");
const mf = new Miniflare({
modules: [
{
type: "ESModule",
path: "index.mjs",
contents: `
import root from "__STATIC_CONTENT_MANIFEST";
import a1 from "./a/1.mjs";
import ab2 from "./a/b/2.mjs";
import ab3 from "./a/b/3.mjs";
import abc4 from "./a/b/c/4.mjs";
export default {
async fetch() {
return Response.json({
a1: a1 === root,
ab2: ab2 === root,
ab3: ab3 === root,
abc4: abc4 === root,
});
}
}
`,
},
{
type: "ESModule",
path: "a/1.mjs",
contents: 'export { default } from "__STATIC_CONTENT_MANIFEST";',
},
{
type: "ESModule",
path: "a/b/2.mjs",
contents: 'export { default } from "__STATIC_CONTENT_MANIFEST";',
},
{
type: "ESModule",
path: "a/b/3.mjs",
contents: 'export { default } from "__STATIC_CONTENT_MANIFEST";',
},
{
type: "ESModule",
path: "a/b/c/4.mjs",
contents: 'export { default } from "__STATIC_CONTENT_MANIFEST";',
},
],
sitePath: tmp,
});
t.teardown(() => mf.dispose());
const res = await mf.dispatchFetch("http://localhost:8787/test.txt");
t.deepEqual(await res.json(), { a1: true, ab2: true, ab3: true, abc4: true });
});

test("gets assets with percent-encoded paths", async (t) => {
// https://github.com/cloudflare/miniflare/issues/326
const tmp = await useTmp(t);
Expand Down

0 comments on commit 0e73c59

Please sign in to comment.