@@ -44,6 +44,13 @@ export const RuleTypeToModuleType: Record<ConfigModuleRuleType, CfModuleType> =
4444
4545export const ModuleTypeToRuleType = flipObject ( RuleTypeToModuleType ) ;
4646
47+ // Strip query string suffixes (e.g. `?module`) from module paths so that
48+ // file paths and module names don't contain characters invalid on Windows.
49+ function stripQueryString ( modulePath : string ) : string {
50+ const queryIndex = modulePath . indexOf ( "?" ) ;
51+ return queryIndex !== - 1 ? modulePath . slice ( 0 , queryIndex ) : modulePath ;
52+ }
53+
4754// This is a combination of an esbuild plugin and a mutable array
4855// that we use to collect module references from source code.
4956// There will be modules that _shouldn't_ be inlined directly into
@@ -202,10 +209,11 @@ export function createModuleCollector(props: {
202209
203210 // take the file and massage it to a
204211 // transportable/manageable format
212+ const cleanedPath = stripQueryString ( args . path ) ;
205213 const filePath = path . join (
206214 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
207215 props . wrangler1xLegacyModuleReferences ! . rootDirectory ,
208- args . path
216+ cleanedPath
209217 ) ;
210218 const fileContent = ( await readFile (
211219 filePath
@@ -215,8 +223,8 @@ export function createModuleCollector(props: {
215223 . update ( fileContent )
216224 . digest ( "hex" ) ;
217225 const fileName = props . preserveFileNames
218- ? args . path
219- : `./${ fileHash } -${ path . basename ( args . path ) } ` ;
226+ ? cleanedPath
227+ : `./${ fileHash } -${ path . basename ( cleanedPath ) } ` ;
220228
221229 const { rule } =
222230 rulesMatchers . find ( ( { regex } ) => regex . test ( fileName ) ) || { } ;
@@ -257,13 +265,17 @@ export function createModuleCollector(props: {
257265 // take the file and massage it to a
258266 // transportable/manageable format
259267
260- let filePath = path . join ( args . resolveDir , args . path ) ;
268+ // Strip query string suffixes (e.g. `?module`) from the import
269+ // path. The `?` character is not valid in filenames on Windows
270+ // and would cause ENOENT errors when writing modules to disk.
271+ const cleanedPath = stripQueryString ( args . path ) ;
272+ let filePath = path . join ( args . resolveDir , cleanedPath ) ;
261273
262274 // If this was a found additional module, mark it as external.
263275 // Note, there's no need to watch the file here as we already
264276 // watch all `foundModulePaths` with `wrangler:modules-watch`.
265277 if ( foundModulePaths . includes ( filePath ) ) {
266- return { path : args . path , external : true } ;
278+ return { path : cleanedPath , external : true } ;
267279 }
268280 // For JavaScript module rules, we only register this onResolve
269281 // callback if `findAdditionalModules` is true. If we didn't
@@ -277,7 +289,7 @@ export function createModuleCollector(props: {
277289 // and if so, validate the import against the package.json exports
278290 // and resolve the file path to the correct file.
279291 try {
280- const resolved = await build . resolve ( args . path , {
292+ const resolved = await build . resolve ( cleanedPath , {
281293 kind : args . kind ,
282294 importer : args . importer ,
283295 resolveDir : args . resolveDir ,
@@ -295,7 +307,7 @@ export function createModuleCollector(props: {
295307
296308 // Next try to resolve using the node module resolution algorithm
297309 try {
298- const resolved = resolveSync ( args . path , {
310+ const resolved = resolveSync ( cleanedPath , {
299311 basedir : args . resolveDir ,
300312 } ) ;
301313 filePath = resolved ;
@@ -314,8 +326,8 @@ export function createModuleCollector(props: {
314326 . update ( fileContent )
315327 . digest ( "hex" ) ;
316328 const fileName = props . preserveFileNames
317- ? args . path
318- : `./${ fileHash } -${ path . basename ( args . path ) } ` ;
329+ ? cleanedPath
330+ : `./${ fileHash } -${ path . basename ( cleanedPath ) } ` ;
319331
320332 // add the module to the array
321333 modules . push ( {
0 commit comments