Path-based Imports
Your src/ directory structure directly maps to URL paths. Each file becomes its own importable module.
File → URL mapping
src/
├── index.ts → https://worker.dev/
├── greet.ts → https://worker.dev/greet
├── Counter.ts → https://worker.dev/Counter
└── utils/
└── math.ts → https://worker.dev/utils/mathImporting a module
javascript
// Import all exports from src/utils/math.ts
import { multiply, divide, PI } from "https://worker.dev/utils/math";
await multiply(6, 7); // 42Importing a specific export
You can append the export name to the module path:
javascript
// Just the multiply function from src/utils/math.ts
import multiply from "https://worker.dev/utils/math/multiply";
await multiply(6, 7); // 42Root module
src/index.ts maps to the root URL /:
javascript
import { greet } from "https://worker.dev/";If no file module matches a path, it falls back to looking up exports from the root module. So if src/greet.ts doesn't exist but src/index.ts exports greet, then /greet still works.
Priority
File modules take priority over root exports. If both src/greet.ts and an export named greet in src/index.ts exist, /greet serves the file module.
How it works
At build time, generate-export-types scans src/ and produces a module map:
javascript
// .export-module-map.js (generated)
import * as _0 from "./src/index.ts";
import * as _1 from "./src/greet.ts";
import * as _2 from "./src/utils/math.ts";
export default { "": _0, "greet": _1, "utils/math": _2 };Wrangler bundles all source files in one pass. The handler uses the map to route requests.
Type definitions
Each module has its own types:
bash
curl "https://worker.dev/?types" # types for src/index.ts
curl "https://worker.dev/utils/math?types" # types for src/utils/math.ts