Merge 70e59a0e4f50e0736b9472ffada5dcfc13e12028 into 608461c04cf74cbf27b47f9916e10e225cbfe8f1

This commit is contained in:
edenbuilds 2026-08-27 07:03:55 +05:30 committed by GitHub
commit 3c09c8a270
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -37,14 +37,108 @@ interface StaticImport {
end: number
}
/**
* Replace string/template contents and comments with spaces of the same length.
* Indices stay aligned with the original source so import-end offsets still apply
* when injecting the CJS shim.
*
* Without this, `import ... from '...'` text embedded in string literals (common
* in large app bundles that ship schema/SQL/source snippets) is treated as a real
* static import. Injecting the shim after that false match mid-string corrupts
* the chunk and can cause bundlers (e.g. Rolldown / Vite 8) to emit an empty entry
* see https://github.com/alex8088/electron-vite/issues/906
*/
export function maskNonCode(code: string): string {
let out = ''
let i = 0
const n = code.length
const spaces = (len: number): string => ' '.repeat(len)
while (i < n) {
const c = code[i]!
const c2 = code[i + 1]
// line comment
if (c === '/' && c2 === '/') {
let j = i + 2
while (j < n && code[j] !== '\n' && code[j] !== '\r') j++
out += spaces(j - i)
i = j
continue
}
// block comment
if (c === '/' && c2 === '*') {
let j = i + 2
while (j + 1 < n && !(code[j] === '*' && code[j + 1] === '/')) j++
j = Math.min(j + 2, n)
out += spaces(j - i)
i = j
continue
}
// single- and double-quoted strings
if (c === '"' || c === "'") {
const q = c
let j = i + 1
while (j < n) {
if (code[j] === '\\') {
j += 2
continue
}
if (code[j] === q) {
j++
break
}
j++
}
out += spaces(j - i)
i = j
continue
}
// template literals (mask whole span, including ${...} expressions —
// rare real top-level imports inside interpolations, and safer than
// re-matching import-like SQL/source embedded in templates)
if (c === '`') {
let j = i + 1
while (j < n) {
if (code[j] === '\\') {
j += 2
continue
}
if (code[j] === '`') {
j++
break
}
j++
}
out += spaces(j - i)
i = j
continue
}
out += c
i++
}
return out
}
function findStaticImports(code: string): StaticImport[] {
const searchable = maskNonCode(code)
const matches: StaticImport[] = []
for (const match of code.matchAll(ESMStaticImportRe)) {
for (const match of searchable.matchAll(ESMStaticImportRe)) {
matches.push({ end: (match.index || 0) + match[0].length })
}
return matches
}
function hasCjsSyntax(code: string): boolean {
// Ignore CJS markers that only appear inside strings/comments
return CJSyntaxRe.test(maskNonCode(code))
}
export default function esmShimPlugin(): Plugin {
const CJSShim = supportImportMetaPaths() ? CJSShim_node_20_11 : CJSShim_normal
@ -54,7 +148,7 @@ export default function esmShimPlugin(): Plugin {
enforce: 'post',
renderChunk(code, _chunk, { format, sourcemap }): { code: string; map?: SourceMapInput } | null {
if (format === 'es') {
if (code.includes(CJSShim) || !CJSyntaxRe.test(code)) {
if (code.includes(CJSShim) || !hasCjsSyntax(code)) {
return null
}