Skip to content

Commit 2ebe4b4

Browse files
authored
fix: set scripts imported by HTML moduleSideEffects=true (#18411)
1 parent 409fa5c commit 2ebe4b4

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

packages/vite/src/node/plugins/html.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ export function htmlInlineProxyPlugin(config: ResolvedConfig): Plugin {
108108
const url = file.replace(normalizePath(config.root), '')
109109
const result = htmlProxyMap.get(config)!.get(url)?.[index]
110110
if (result) {
111-
return result
111+
// set moduleSideEffects to keep the module even if `treeshake.moduleSideEffects=false` is set
112+
return { ...result, moduleSideEffects: true }
112113
} else {
113114
throw new Error(`No matching HTML proxy module found from ${id}`)
114115
}
@@ -426,6 +427,7 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
426427
return url
427428
}
428429

430+
const setModuleSideEffectPromises: Promise<void>[] = []
429431
await traverseHtml(html, id, (node) => {
430432
if (!nodeIsElement(node)) {
431433
return
@@ -452,6 +454,19 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
452454
if (isModule) {
453455
inlineModuleIndex++
454456
if (url && !isExcludedUrl(url) && !isPublicFile) {
457+
setModuleSideEffectPromises.push(
458+
this.resolve(url, id)
459+
.then((resolved) => {
460+
if (!resolved) {
461+
return Promise.reject()
462+
}
463+
return this.load(resolved)
464+
})
465+
.then((mod) => {
466+
// set this to keep the module even if `treeshake.moduleSideEffects=false` is set
467+
mod.moduleSideEffects = true
468+
}),
469+
)
455470
// <script type="module" src="..."/>
456471
// add it as an import
457472
js += `\nimport ${JSON.stringify(url)}`
@@ -687,6 +702,8 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
687702
js = `import "${modulePreloadPolyfillId}";\n${js}`
688703
}
689704

705+
await Promise.all(setModuleSideEffectPromises)
706+
690707
// Force rollup to keep this module from being shared between other entry points.
691708
// If the resulting chunk is empty, it will be removed in generateBundle.
692709
return { code: js, moduleSideEffects: 'no-treeshake' }

packages/vite/src/node/plugins/resolve.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,14 +348,7 @@ export function resolvePlugin(
348348
res = ensureVersionQuery(res, id, options, ssr, depsOptimizer)
349349
debug?.(`[relative] ${colors.cyan(id)} -> ${colors.dim(res)}`)
350350

351-
// If this isn't a script imported from a .html file, include side effects
352-
// hints so the non-used code is properly tree-shaken during build time.
353-
if (
354-
!options.idOnly &&
355-
!options.scan &&
356-
options.isBuild &&
357-
!importer?.endsWith('.html')
358-
) {
351+
if (!options.idOnly && !options.scan && options.isBuild) {
359352
const resPkg = findNearestPackageData(
360353
path.dirname(res),
361354
options.packageCache,

0 commit comments

Comments
 (0)