fix: set scripts imported by HTML moduleSideEffects=true (#18411)

This commit is contained in:
翠 / green 2024-10-26 17:53:23 +09:00 committed by GitHub
parent 409fa5c9de
commit 2ebe4b4443
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 9 deletions

View File

@ -108,7 +108,8 @@ export function htmlInlineProxyPlugin(config: ResolvedConfig): Plugin {
const url = file.replace(normalizePath(config.root), '')
const result = htmlProxyMap.get(config)!.get(url)?.[index]
if (result) {
return result
// set moduleSideEffects to keep the module even if `treeshake.moduleSideEffects=false` is set
return { ...result, moduleSideEffects: true }
} else {
throw new Error(`No matching HTML proxy module found from ${id}`)
}
@ -426,6 +427,7 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
return url
}
const setModuleSideEffectPromises: Promise<void>[] = []
await traverseHtml(html, id, (node) => {
if (!nodeIsElement(node)) {
return
@ -452,6 +454,19 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
if (isModule) {
inlineModuleIndex++
if (url && !isExcludedUrl(url) && !isPublicFile) {
setModuleSideEffectPromises.push(
this.resolve(url, id)
.then((resolved) => {
if (!resolved) {
return Promise.reject()
}
return this.load(resolved)
})
.then((mod) => {
// set this to keep the module even if `treeshake.moduleSideEffects=false` is set
mod.moduleSideEffects = true
}),
)
// <script type="module" src="..."/>
// add it as an import
js += `\nimport ${JSON.stringify(url)}`
@ -687,6 +702,8 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
js = `import "${modulePreloadPolyfillId}";\n${js}`
}
await Promise.all(setModuleSideEffectPromises)
// Force rollup to keep this module from being shared between other entry points.
// If the resulting chunk is empty, it will be removed in generateBundle.
return { code: js, moduleSideEffects: 'no-treeshake' }

View File

@ -348,14 +348,7 @@ export function resolvePlugin(
res = ensureVersionQuery(res, id, options, ssr, depsOptimizer)
debug?.(`[relative] ${colors.cyan(id)} -> ${colors.dim(res)}`)
// If this isn't a script imported from a .html file, include side effects
// hints so the non-used code is properly tree-shaken during build time.
if (
!options.idOnly &&
!options.scan &&
options.isBuild &&
!importer?.endsWith('.html')
) {
if (!options.idOnly && !options.scan && options.isBuild) {
const resPkg = findNearestPackageData(
path.dirname(res),
options.packageCache,