Skip to content

Commit 713d18e

Browse files
committed
fix: handle inline scripts, relative paths, and edge cases in bundledDev entry detection
- Support inline <script type="module"> with import statements - Resolve relative src from the HTML file's directory, not Vite root - Strip query/hash from src and skip external URLs - Gracefully continue when HTML files are unreadable
1 parent 7b28780 commit 713d18e

1 file changed

Lines changed: 30 additions & 7 deletions

File tree

packages/core/src/index.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,18 +264,41 @@ function VitePluginInspector(options: VitePluginInspectorOptions = DEFAULT_INSPE
264264
if (htmlFiles.length === 0)
265265
htmlFiles = [path.resolve(config.root, 'index.html')]
266266

267-
// Parse <script type="module" src="..."> from each HTML file
268-
const scriptModuleRE = /<script\b(?=[^>]*\btype\s*=\s*["']module["'])(?=[^>]*\bsrc\s*=\s*["']([^"']+)["'])[^>]*>/gi
267+
// Parse <script type="module"> from each HTML file (both src and inline)
268+
const scriptModuleSrcRE = /<script\b(?=[^>]*\btype\s*=\s*["']module["'])(?=[^>]*\bsrc\s*=\s*["']([^"']+)["'])[^>]*>/gi
269+
const scriptModuleInlineRE = /<script\b(?=[^>]*\btype\s*=\s*["']module["'])(?!(?:[^>]*\bsrc\s*=))([^>]*)>([\s\S]*?)<\/script>/gi
270+
const importRE = /\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^'"]+)['"]/g
271+
const externalRE = /^(?:https?:)?\/\/|^data:/i
272+
function resolveEntryModule(src: string, htmlDir: string) {
273+
// Strip query/hash suffixes and skip external URLs
274+
const cleaned = src.replace(/[?#].*$/, '')
275+
if (externalRE.test(cleaned) || !cleaned)
276+
return
277+
const base = cleaned.startsWith('/') ? config.root : htmlDir
278+
htmlEntryModules.add(normalizePath(path.resolve(base, cleaned.replace(/^\//, ''))))
279+
}
280+
269281
for (const htmlFile of htmlFiles) {
270282
const resolved = path.isAbsolute(htmlFile) ? htmlFile : path.resolve(config.root, htmlFile)
271-
if (!fs.existsSync(resolved))
283+
let html: string
284+
try {
285+
html = fs.readFileSync(resolved, 'utf-8')
286+
}
287+
catch {
272288
continue
273-
const html = fs.readFileSync(resolved, 'utf-8')
289+
}
290+
const htmlDir = path.dirname(resolved)
274291
let match: RegExpExecArray | null
275292
// eslint-disable-next-line no-cond-assign
276-
while ((match = scriptModuleRE.exec(html)) !== null) {
277-
const absPath = normalizePath(path.resolve(config.root, match[1].replace(/^\//, '')))
278-
htmlEntryModules.add(absPath)
293+
while ((match = scriptModuleSrcRE.exec(html)) !== null)
294+
resolveEntryModule(match[1], htmlDir)
295+
// eslint-disable-next-line no-cond-assign
296+
while ((match = scriptModuleInlineRE.exec(html)) !== null) {
297+
const scriptContent = match[2]
298+
let importMatch: RegExpExecArray | null
299+
// eslint-disable-next-line no-cond-assign
300+
while ((importMatch = importRE.exec(scriptContent)) !== null)
301+
resolveEntryModule(importMatch[1], htmlDir)
279302
}
280303
}
281304
}

0 commit comments

Comments
 (0)