Workers SDK Issue Reports

← Back to Dashboard

#8893 wrangler types should include module declarations for default rules

Download Reproduction
Recommendation:KEEP OPEN
Difficulty:easy
Reasoning:

Bug confirmed on wrangler 4.60.0: type-generation only processes config.rules, ignoring DEFAULT_MODULE_RULES (*.html, *.txt, *.sql, *.bin, *.wasm) applied during bundling.

Suggested Action:

Implement fix to use parseRules() in type-generation to include defaults

Analysis Report

Issue Review: cloudflare/workers-sdk#8893

Summary

wrangler types does not generate module declarations for default rules (*.html, *.txt, *.sql, *.bin, *.wasm) - only generates them when rules are explicitly added to wrangler.toml.

Findings

  • Created: 2025-04-10
  • Updated: 2025-04-10
  • Version: 4.10.0 → 4.60.0
  • Component: wrangler (type-generation)
  • Labels: bug
  • Comments: 0

Key Evidence

  • Issue clearly describes expected vs actual behavior
  • Reproduction confirmed on wrangler 4.60.0:
    • Without explicit rules: No module declarations generated
    • With explicit rules: Module declarations ARE generated (e.g., declare module "*.html")
  • No PRs found that explicitly fix this issue (#8893 not referenced in any merged PRs)
  • Changelog does not mention this fix
  • Root cause identified in source code

Recommendation

Status: KEEP OPEN

Reasoning: The bug is reproducible on the latest wrangler version (4.60.0). The type generation code only processes config.rules from user configuration, but does not include the DEFAULT_MODULE_RULES that are automatically applied during deployment bundling.

Action: Implement fix to include default module rules in type generation.


Root Cause Analysis

The issue is in packages/wrangler/src/type-generation/index.ts. The type generation code at lines 631-652 only generates module declarations when config.rules is defined:

// packages/wrangler/src/type-generation/index.ts:631-652
const modulesTypeStructure = new Array<string>();
if (config.rules) {  // <-- Only processes user-defined rules
    const moduleTypeMap = {
        CompiledWasm: "WebAssembly.Module",
        Data: "ArrayBuffer",
        Text: "string",
    };
    for (const ruleObject of config.rules) {
        const typeScriptType =
            moduleTypeMap[ruleObject.type as keyof typeof moduleTypeMap];
        if (typeScriptType === undefined) {
            continue;
        }

        for (const glob of ruleObject.globs) {
            modulesTypeStructure.push(`declare module "${constructTSModuleGlob(glob)}" {
\tconst value: ${typeScriptType};
\texport default value;
}`);
        }
    }
}

However, the DEFAULT_MODULE_RULES are defined in packages/wrangler/src/deployment-bundle/rules.ts:

// packages/wrangler/src/deployment-bundle/rules.ts:8-12
export const DEFAULT_MODULE_RULES: Rule[] = [
    { type: "Text", globs: ["**/*.txt", "**/*.html", "**/*.sql"] },
    { type: "Data", globs: ["**/*.bin"] },
    { type: "CompiledWasm", globs: ["**/*.wasm", "**/*.wasm?module"] },
];

These default rules are applied during bundling via parseRules(), but the type generation code does not include them.

Proposed Solution

Modify the type generation code to include DEFAULT_MODULE_RULES when generating module declarations. The fix should use parseRules() to combine user rules with default rules (matching deployment behavior).

// In packages/wrangler/src/type-generation/index.ts

// Add import at top of file
import { parseRules, DEFAULT_MODULE_RULES } from "../deployment-bundle/rules";

// Modify the rules processing section (around line 631)
const modulesTypeStructure = new Array<string>();

// Use parseRules to get the effective rules (user + defaults)
const effectiveRules = parseRules(config.rules).rules;

if (effectiveRules.length > 0) {
    const moduleTypeMap = {
        CompiledWasm: "WebAssembly.Module",
        Data: "ArrayBuffer",
        Text: "string",
    };
    for (const ruleObject of effectiveRules) {
        const typeScriptType =
            moduleTypeMap[ruleObject.type as keyof typeof moduleTypeMap];
        if (typeScriptType === undefined) {
            continue;
        }

        for (const glob of ruleObject.globs) {
            modulesTypeStructure.push(`declare module "${constructTSModuleGlob(glob)}" {
\tconst value: ${typeScriptType};
\texport default value;
}`);
        }
    }
}

Note: The same fix pattern should be applied in two places in the file:

  1. Lines 631-652 (first occurrence)
  2. Lines 1038-1053 (second occurrence, likely for environment-specific handling)

Implementation Difficulty: Easy

Justification:

  • Clear root cause identified
  • Existing parseRules() function already handles combining user rules with defaults
  • Straightforward code change - import existing function and use it
  • Low risk of regressions since this adds behavior rather than changing existing
  • Similar pattern already used in deployment bundling

Files to Modify

  1. packages/wrangler/src/type-generation/index.ts
    • Import parseRules from ../deployment-bundle/rules
    • Replace config.rules with parseRules(config.rules).rules in two locations (lines ~631 and ~1038)

Testing Recommendations

  1. Unit Tests (add to existing type-generation tests):

    • Test that default module rules generate declarations when no user rules specified
    • Test that user rules + default rules are both included
    • Test that user rules properly override default rules (when fallthrough=false)
    • Test that duplicate rules are properly deduplicated
  2. E2E Test:

    • Create a worker without explicit rules
    • Run wrangler types
    • Verify output includes:
      declare module "*.txt" { const value: string; export default value; }
      declare module "*.html" { const value: string; export default value; }
      declare module "*.sql" { const value: string; export default value; }
      declare module "*.bin" { const value: ArrayBuffer; export default value; }
      declare module "*.wasm" { const value: WebAssembly.Module; export default value; }
      
  3. Regression Test:

    • Ensure existing tests with explicit rules still pass
    • Verify that user rules can still override defaults

Notes & Feedback (0)

No notes yet.

Add Note