@@ -562,6 +562,136 @@ it(
562562 CF_BUILD_TIMEOUT_MS ,
563563) ;
564564
565+ it (
566+ 'keeps framework Wasm, text and data imports as Worker modules' ,
567+ async ( ) => {
568+ const root = mkdtempSync ( join ( tmpdir ( ) , 'void-cf-framework-wasm-test-' ) ) ;
569+ roots . push ( root ) ;
570+ const output = join ( root , 'framework' ) ;
571+ mkdirSync ( join ( output , 'chunks' ) , { recursive : true } ) ;
572+ writeFileSync (
573+ join ( root , 'package.json' ) ,
574+ JSON . stringify ( { type : 'module' , imports : { '#plain' : './framework/plain.wasm' } } ) ,
575+ ) ;
576+ writeFileSync (
577+ join ( root , 'wrangler.json' ) ,
578+ JSON . stringify ( {
579+ name : 'void-framework-test' ,
580+ account_id : 'account-id' ,
581+ main : 'framework/_worker.js' ,
582+ compatibility_date : '2026-09-29' ,
583+ assets : { directory : 'framework' , binding : 'ASSETS' } ,
584+ } ) ,
585+ ) ;
586+ // Imports `wbg`, like wasm-bindgen output.
587+ const bindgenWasm = Buffer . from ( [
588+ 0 , 97 , 115 , 109 , 1 , 0 , 0 , 0 , 1 , 4 , 1 , 96 , 0 , 0 , 2 , 9 , 1 , 3 , 119 , 98 , 103 , 1 , 102 , 0 , 0 ,
589+ ] ) ;
590+ const plainWasm = Buffer . from ( [ 0 , 97 , 115 , 109 , 1 , 0 , 0 , 0 ] ) ;
591+ mkdirSync ( join ( root , 'node_modules/bindgen' ) , { recursive : true } ) ;
592+ writeFileSync ( join ( root , 'node_modules/bindgen/index_bg.wasm' ) , bindgenWasm ) ;
593+ writeFileSync ( join ( output , 'plain.wasm' ) , plainWasm ) ;
594+ writeFileSync ( join ( output , 'message.txt' ) , 'text module' ) ;
595+ writeFileSync ( join ( output , 'data.bin' ) , Buffer . from ( [ 0 , 255 ] ) ) ;
596+ writeFileSync (
597+ join ( output , '_worker.js' ) ,
598+ "import plain from './plain.wasm'; import message from './message.txt'; import data from './data.bin';\n" +
599+ "import { render } from './chunks/render.js';\n" +
600+ 'export default { async fetch() { return new Response(String([plain, message, data, await render()])) } };\n' ,
601+ ) ;
602+ writeFileSync (
603+ join ( output , 'chunks/render.js' ) ,
604+ "import plain from '#plain';\n" +
605+ "export async function render() { return String(plain) + String(await import('bindgen/index_bg.wasm')); }\n" ,
606+ ) ;
607+ writeFileSync ( join ( output , '.assetsignore' ) , '_worker.js\n' ) ;
608+
609+ await withPrepared (
610+ prepareCfFrameworkBuildOutput ( {
611+ projectRoot : root ,
612+ configPath : join ( root , 'wrangler.json' ) ,
613+ accountId : 'account-id' ,
614+ } ) ,
615+ async ( prepared ) => {
616+ const built = await readBuildOutput ( prepared . directory ) ;
617+ const { modules } = built . workers . default . config . manifest ! ;
618+ const bundle = getWorkerBundleDir ( prepared . directory ) ;
619+ const additional = Object . keys ( modules )
620+ . filter ( ( name ) => modules [ name ] . type !== 'esm' )
621+ . map ( ( name ) => [ modules [ name ] . type , readFileSync ( join ( bundle , name ) ) ] ) ;
622+ expect ( additional ) . toHaveLength ( 4 ) ;
623+ expect ( additional ) . toEqual (
624+ expect . arrayContaining ( [
625+ [ 'wasm' , bindgenWasm ] ,
626+ [ 'wasm' , plainWasm ] ,
627+ [ 'text' , Buffer . from ( 'text module' ) ] ,
628+ [ 'data' , Buffer . from ( [ 0 , 255 ] ) ] ,
629+ ] ) ,
630+ ) ;
631+ expectCfDryRun ( prepared . directory ) ;
632+ } ,
633+ ) ;
634+ } ,
635+ CF_BUILD_TIMEOUT_MS ,
636+ ) ;
637+
638+ it (
639+ 'resolves framework Worker dependencies with Worker conditions' ,
640+ async ( ) => {
641+ const root = mkdtempSync ( join ( tmpdir ( ) , 'void-cf-framework-conditions-test-' ) ) ;
642+ roots . push ( root ) ;
643+ const output = join ( root , 'framework' ) ;
644+ mkdirSync ( output ) ;
645+ writeFileSync ( join ( root , 'package.json' ) , JSON . stringify ( { type : 'module' } ) ) ;
646+ writeFileSync (
647+ join ( root , 'wrangler.json' ) ,
648+ JSON . stringify ( {
649+ name : 'void-framework-test' ,
650+ account_id : 'account-id' ,
651+ main : 'framework/_worker.js' ,
652+ compatibility_date : '2026-09-29' ,
653+ assets : { directory : 'framework' , binding : 'ASSETS' } ,
654+ } ) ,
655+ ) ;
656+ const dual = join ( root , 'node_modules/dual' ) ;
657+ mkdirSync ( dual , { recursive : true } ) ;
658+ writeFileSync (
659+ join ( dual , 'package.json' ) ,
660+ JSON . stringify ( {
661+ name : 'dual' ,
662+ type : 'module' ,
663+ exports : { workerd : './worker.js' , browser : './browser.js' , default : './node.js' } ,
664+ } ) ,
665+ ) ;
666+ writeFileSync ( join ( dual , 'worker.js' ) , "export const target = 'dual-workerd';\n" ) ;
667+ writeFileSync ( join ( dual , 'browser.js' ) , "export const target = 'dual-browser';\n" ) ;
668+ writeFileSync ( join ( dual , 'node.js' ) , "export const target = 'dual-node';\n" ) ;
669+ writeFileSync (
670+ join ( output , '_worker.js' ) ,
671+ "import { target } from 'dual';\n" +
672+ 'export default { fetch() { return new Response(target) } };\n' ,
673+ ) ;
674+ writeFileSync ( join ( output , '.assetsignore' ) , '_worker.js\n' ) ;
675+
676+ await withPrepared (
677+ prepareCfFrameworkBuildOutput ( {
678+ projectRoot : root ,
679+ configPath : join ( root , 'wrangler.json' ) ,
680+ accountId : 'account-id' ,
681+ } ) ,
682+ async ( prepared ) => {
683+ const bundle = readFileSync (
684+ join ( getWorkerBundleDir ( prepared . directory ) , 'index.js' ) ,
685+ 'utf8' ,
686+ ) ;
687+ expect ( bundle ) . toContain ( 'dual-workerd' ) ;
688+ expect ( bundle ) . not . toContain ( 'dual-browser' ) ;
689+ } ,
690+ ) ;
691+ } ,
692+ CF_BUILD_TIMEOUT_MS ,
693+ ) ;
694+
565695it (
566696 'accepts a nested hashed Worker entry with a relative module import' ,
567697 async ( ) => {
0 commit comments