#8893 wrangler types should include module declarations for default rules
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.
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:
- Lines 631-652 (first occurrence)
- 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
- packages/wrangler/src/type-generation/index.ts
- Import
parseRulesfrom../deployment-bundle/rules - Replace
config.ruleswithparseRules(config.rules).rulesin two locations (lines ~631 and ~1038)
- Import
Testing Recommendations
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
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; }
Regression Test:
- Ensure existing tests with explicit rules still pass
- Verify that user rules can still override defaults
Notes & Feedback (0)
No notes yet.