fix(renderer): correctly load nomodule scripts in safari 10 (#6033)

This commit is contained in:
Xin Du (Clark) 2019-07-06 16:22:50 +01:00 committed by GitHub
parent 9014251c1f
commit a1124d2fff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 16 deletions

View File

@ -46,3 +46,6 @@ export const isModernRequest = (req, modernMode = false) => {
return socket._modern
}
// https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc
export const safariNoModuleFix = `!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()},!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();`

View File

@ -1,5 +1,5 @@
import invert from 'lodash/invert'
import { isUrl, urlJoin } from '@nuxt/utils'
import { isUrl, urlJoin, safariNoModuleFix } from '@nuxt/utils'
import SSRRenderer from './ssr'
export default class ModernRenderer extends SSRRenderer {
@ -52,7 +52,7 @@ export default class ModernRenderer extends SSRRenderer {
const scriptPattern = /<script[^>]*?src="([^"]*?)"[^>]*?>[^<]*?<\/script>/g
return scripts.replace(scriptPattern, (scriptTag, jsFile) => {
const modernScripts = scripts.replace(scriptPattern, (scriptTag, jsFile) => {
const legacyJsFile = jsFile.replace(this.publicPath, '')
const modernJsFile = this.assetsMapping[legacyJsFile]
const { build: { crossorigin } } = this.options
@ -66,6 +66,10 @@ export default class ModernRenderer extends SSRRenderer {
return noModuleTag + moduleTag
})
const safariNoModuleFixScript = `<script>${safariNoModuleFix}</script>`
return safariNoModuleFixScript + modernScripts
}
getModernFiles(legacyFiles = []) {

View File

@ -4,13 +4,11 @@
*/
import EventEmitter from 'events'
import { safariNoModuleFix } from '@nuxt/utils'
const assetsMap = {}
const watcher = new EventEmitter()
// https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc
const safariFix = `!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()},!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();`
export default class ModernModePlugin {
constructor({ targetDir, isModernBuild }) {
this.targetDir = targetDir
@ -85,24 +83,21 @@ export default class ModernModePlugin {
const legacyAssets = (await this.getAssets(fileName))
.filter(a => a.tagName === 'script' && a.attributes)
// inject Safari 10 nomodule fix
data.body.push({
tagName: 'script',
closeTag: true,
innerHTML: safariNoModuleFix
})
for (const a of legacyAssets) {
a.attributes.nomodule = ''
a.attributes.nomodule = true
data.body.push(a)
}
delete assetsMap[fileName]
cb()
})
compilation.hooks.htmlWebpackPluginAfterHtmlProcessing.tap(ID, (data) => {
data.html = data.html.replace(/\snomodule="">/g, ' nomodule>')
// inject Safari 10 nomodule fix
data.html = data.html.replace(
/(<\/body\s*>)/i,
match => `<script>${safariFix}</script>${match}`
)
})
})
}
}