fix(webpack): no module scripts in spa modern client mode (#7967)

[release]
This commit is contained in:
Xin Du (Clark) 2020-08-25 20:26:04 +01:00 committed by GitHub
parent e72d03a49a
commit 11646ba2f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -7,8 +7,8 @@ import EventEmitter from 'events'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import { safariNoModuleFix } from '@nuxt/utils'
const assetsMap = {}
const watcher = new EventEmitter()
const legacyTemplateTags = {}
const legacyTemplateWatcher = new EventEmitter()
export default class ModernModePlugin {
constructor ({ targetDir, isModernBuild, noUnsafeInline }) {
@ -25,24 +25,15 @@ export default class ModernModePlugin {
}
}
get assets () {
return assetsMap
}
set assets ({ name, content }) {
assetsMap[name] = content
watcher.emit(name)
}
getAssets (name) {
getLegacyTemplateTags (name) {
return new Promise((resolve) => {
const asset = this.assets[name]
if (asset) {
return resolve(asset)
const tags = legacyTemplateTags[name]
if (tags) {
return resolve(tags)
}
return watcher.once(name, () => {
const asset = this.assets[name]
return asset && resolve(asset)
return legacyTemplateWatcher.once(name, () => {
const tags = legacyTemplateTags[name]
return tags && resolve(tags)
})
})
}
@ -50,14 +41,13 @@ export default class ModernModePlugin {
applyLegacy (compiler) {
const ID = 'nuxt-legacy-bundle'
compiler.hooks.compilation.tap(ID, (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync(ID, (data, cb) => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tap(ID, (data) => {
HtmlWebpackPlugin.getHooks(compilation).afterEmit.tap(ID, ({ outputName }) => {
// get stats, write to disk
this.assets = {
name: data.plugin.options.filename,
content: data.bodyTags
}
cb()
legacyTemplateTags[data.plugin.options.filename] = data.bodyTags
legacyTemplateWatcher.emit(outputName)
})
return data
})
})
}
@ -65,7 +55,7 @@ export default class ModernModePlugin {
applyModern (compiler) {
const ID = 'nuxt-modern-bundle'
compiler.hooks.compilation.tap(ID, (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync(ID, async (data, cb) => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapPromise(ID, async (data) => {
// use <script type="module"> for modern assets
data.bodyTags.forEach((tag) => {
if (tag.tagName === 'script' && tag.attributes) {
@ -85,10 +75,10 @@ export default class ModernModePlugin {
// inject links for legacy assets as <script nomodule>
const fileName = data.plugin.options.filename
const legacyAssets = (await this.getAssets(fileName))
const legacyScriptTags = (await this.getLegacyTemplateTags(fileName))
.filter(a => a.tagName === 'script' && a.attributes)
for (const a of legacyAssets) {
for (const a of legacyScriptTags) {
a.attributes.nomodule = true
data.bodyTags.push(a)
}
@ -96,7 +86,7 @@ export default class ModernModePlugin {
if (this.noUnsafeInline) {
// inject the fix as an external script
const safariFixFilename = 'safari-nomodule-fix.js'
const safariFixPath = legacyAssets[0].attributes.src
const safariFixPath = legacyScriptTags[0].attributes.src
.split('/')
.slice(0, -1)
.concat([safariFixFilename])
@ -122,8 +112,9 @@ export default class ModernModePlugin {
})
}
delete assetsMap[fileName]
cb()
delete legacyTemplateTags[fileName]
return data
})
})
}