Skip to content

Commit

Permalink
Allow --experimental-local to be used with module workers (#1934)
Browse files Browse the repository at this point in the history
Previously, Miniflare 3 was automatically collecting modules.
These collected modules were given names relative to the current
working directory. Because Wrangler puts scripts in a temporary
directory, these names started with `..`, which `workerd` was not
happy with.

This change avoids the redundant automatic collection in Miniflare,
and ensures module names are resolved relative to the temporary
directory.
  • Loading branch information
mrbbot committed Sep 27, 2022
1 parent 452b84b commit 7ebaec1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/curvy-laws-develop.md
@@ -0,0 +1,5 @@
---
"wrangler": patch
---

Allow `--experimental-local` to be used with module workers
34 changes: 32 additions & 2 deletions packages/wrangler/src/dev/local.tsx
@@ -1,14 +1,18 @@
import assert from "node:assert";
import { fork } from "node:child_process";
import { realpathSync } from "node:fs";
import { writeFile } from "node:fs/promises";
import { readFile, writeFile } from "node:fs/promises";
import path from "node:path";
import { npxImport } from "npx-import";
import { useState, useEffect, useRef } from "react";
import onExit from "signal-exit";
import { registerWorker } from "../dev-registry";
import useInspector from "../inspect";
import { logger } from "../logger";
import { DEFAULT_MODULE_RULES } from "../module-collection";
import {
DEFAULT_MODULE_RULES,
ModuleTypeToRuleType,
} from "../module-collection";
import { getBasePath } from "../paths";
import { waitForPortToBeAvailable } from "../proxy";
import type { Config } from "../config";
Expand Down Expand Up @@ -218,6 +222,32 @@ function useLocalWorker({
// to collect them again
};

if (format === "modules") {
// Manually specify all modules from the bundle. If we didn't do this,
// Miniflare 3 would try collect them automatically again itself.

// Resolve entrypoint relative to the temporary directory, ensuring
// path doesn't start with `..`, which causes issues in `workerd`.
// Also ensures other modules with relative names can be resolved.
const root = path.dirname(bundle.path);

assert.strictEqual(bundle.type, "esm");
options.modules = [
// Entrypoint
{
type: "ESModule",
path: path.relative(root, bundle.path),
contents: await readFile(bundle.path, "utf-8"),
},
// Misc (WebAssembly, etc, ...)
...bundle.modules.map((module) => ({
type: ModuleTypeToRuleType[module.type ?? "esm"],
path: module.name,
contents: module.content,
})),
];
}

logger.log("⎔ Starting an experimental local server...");

if (Miniflare === undefined) {
Expand Down
9 changes: 9 additions & 0 deletions packages/wrangler/src/module-collection.ts
Expand Up @@ -7,6 +7,13 @@ import type { Config, ConfigModuleRuleType } from "./config";
import type { CfModule, CfModuleType, CfScriptFormat } from "./worker";
import type esbuild from "esbuild";

function flipObject<
K extends string | number | symbol,
V extends string | number | symbol
>(obj: Record<K, V>): Record<V, K> {
return Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));
}

const RuleTypeToModuleType: Record<ConfigModuleRuleType, CfModuleType> = {
ESModule: "esm",
CommonJS: "commonjs",
Expand All @@ -15,6 +22,8 @@ const RuleTypeToModuleType: Record<ConfigModuleRuleType, CfModuleType> = {
Text: "text",
};

export const ModuleTypeToRuleType = flipObject(RuleTypeToModuleType);

// This is a combination of an esbuild plugin and a mutable array
// that we use to collect module references from source code.
// There will be modules that _shouldn't_ be inlined directly into
Expand Down

0 comments on commit 7ebaec1

Please sign in to comment.