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
 |