mirror of
https://github.com/alex8088/electron-vite.git
synced 2026-09-04 15:22:44 +08:00
Merge 70e59a0e4f50e0736b9472ffada5dcfc13e12028 into 608461c04cf74cbf27b47f9916e10e225cbfe8f1
This commit is contained in:
commit
3c09c8a270
@ -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
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user