Skip to content

Commit f0fc560

Browse files
authored
Merge pull request #1867 from DanielXMoore/unplugin-hash
2 parents 3b41b62 + 6a624d4 commit f0fc560

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

source/unplugin/unplugin.civet

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ type CacheEntry
5252
result?: TransformResult
5353
promise?: Promise<void>
5454

55-
postfixRE := /[?#].*$/s
55+
queryPostfixRE := /\?.*$/s
56+
escapedHashRE := /\0#/g
5657
isWindows := os.platform() is 'win32'
5758
windowsSlashRE := /\\/g
5859
civetSuffix := '.civet'
@@ -67,19 +68,33 @@ or needs an implicit .civet extension, or isn't Civet-related at all.
6768
*/
6869
function extractCivetFilename(id: string, outputExtension: string): {filename: string, postfix: string}
6970
postfix .= ''
70-
filename .= id.replace postfixRE, (match) =>
71+
// Webpack escapes literal `#` in `loaderContext.resource` as `\0#` so it
72+
// can distinguish path characters from fragment suffixes. Undo that first.
73+
id = id.replace escapedHashRE, '#'
74+
// `?` is always treated as a suffix. Raw `?` is impossible in Windows paths,
75+
// and we rely on query suffixes across bundlers.
76+
filename .= id.replace queryPostfixRE, (match) =>
7177
postfix = match
7278
''
7379
// Normally the outputExtension (.jsx/.tsx by default) should be present,
7480
// but sometimes (e.g. esbuild's alias feature) load directly without resolve
7581
if filename.endsWith outputExtension
7682
filename = filename[< -outputExtension#]
83+
// `#` may be either a literal path character or a fragment-like suffix.
84+
// Keep it when the file exists as written; otherwise strip one rightmost
85+
// `#...` suffix and let later resolution check whether file exists.
86+
hashIndex := filename.lastIndexOf '#'
87+
if hashIndex >= 0 and not tryStatSync filename
88+
postfix = filename[hashIndex..] + postfix
89+
filename = filename[..<hashIndex]
90+
if filename.endsWith outputExtension
91+
filename = filename[< -outputExtension#]
7792
{filename, postfix}
7893

7994
function tryStatSync(file: string): fs.Stats?
8095
try
8196
// The "throwIfNoEntry" is a performance optimization for cases where the file does not exist
82-
return fs.statSync(file, { throwIfNoEntry: false });
97+
return fs.statSync file, throwIfNoEntry: false
8398

8499
export function slash(p: string): string
85100
p.replace windowsSlashRE, '/'

0 commit comments

Comments
 (0)