72 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // 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()}}();`
 | |
| 
 | |
| const path = require('path')
 | |
| const HtmlWebpackPlugin = require('html-webpack-plugin')
 | |
| const { semver } = require('@vue/cli-shared-utils')
 | |
| const { projectModuleTargets } = require('../util/targets')
 | |
| 
 | |
| const minSafariVersion = projectModuleTargets.safari
 | |
| const minIOSVersion = projectModuleTargets.ios
 | |
| const supportsSafari10 =
 | |
|   (minSafariVersion && semver.lt(semver.coerce(minSafariVersion), '11.0.0')) ||
 | |
|   (minIOSVersion && semver.lt(semver.coerce(minIOSVersion), '11.0.0'))
 | |
| const needsSafariFix = supportsSafari10
 | |
| 
 | |
| class SafariNomoduleFixPlugin {
 | |
|   constructor ({ unsafeInline, jsDirectory }) {
 | |
|     this.unsafeInline = unsafeInline
 | |
|     this.jsDirectory = jsDirectory
 | |
|   }
 | |
| 
 | |
|   apply (compiler) {
 | |
|     if (!needsSafariFix) {
 | |
|       return
 | |
|     }
 | |
|     const { RawSource } = compiler.webpack
 | |
|       ? compiler.webpack.sources
 | |
|       : require('webpack-sources')
 | |
| 
 | |
|     const ID = 'SafariNomoduleFixPlugin'
 | |
|     compiler.hooks.compilation.tap(ID, compilation => {
 | |
|       HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tap(ID, data => {
 | |
|         let scriptTag
 | |
| 
 | |
|         if (this.unsafeInline) {
 | |
|           // inject inline Safari 10 nomodule fix
 | |
|           scriptTag = {
 | |
|             tagName: 'script',
 | |
|             closeTag: true,
 | |
|             innerHTML: safariFix
 | |
|           }
 | |
|         } else {
 | |
|           // inject the fix as an external script
 | |
|           const safariFixPath = path.join(this.jsDirectory, 'safari-nomodule-fix.js')
 | |
|           const fullSafariFixPath = path.join(compilation.options.output.publicPath, safariFixPath)
 | |
|           compilation.assets[safariFixPath] = new RawSource(safariFix)
 | |
|           scriptTag = {
 | |
|             tagName: 'script',
 | |
|             closeTag: true,
 | |
|             attributes: {
 | |
|               src: fullSafariFixPath
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         let tags = data.bodyTags
 | |
|         if (data.plugin.options.scriptLoading === 'defer') {
 | |
|           tags = data.headTags
 | |
|         }
 | |
| 
 | |
|         // insert just before the first actual script tag,
 | |
|         // and after all other tags such as `meta`
 | |
|         const firstScriptIndex = tags.findIndex(tag => tag.tagName === 'script')
 | |
|         tags.splice(firstScriptIndex, 0, scriptTag)
 | |
|       })
 | |
|     })
 | |
|   }
 | |
| }
 | |
| 
 | |
| SafariNomoduleFixPlugin.safariFix = safariFix
 | |
| module.exports = SafariNomoduleFixPlugin
 |