8000 feat!: turn on modern mode by default, and provide a `--no-module` option by haoqunjiang · Pull Request #6416 · vuejs/vue-cli · GitHub
[go: up one dir, main page]

Skip to content

feat!: turn on modern mode by default, and provide a --no-module option #6416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 14, 2021
Merged
Prev Previous commit
Next Next commit
feat: only inject safari-nomodule-fix when necessary
  • Loading branch information
haoqunjiang committed Apr 8, 2021
commit 1b21eb271cec98aee25551a535ed700ddfe44ae9
50 changes: 50 additions & 0 deletions packages/@vue/cli-service/lib/util/targets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// copied from @vue/babel-preset-app

const { semver } = require('@vue/cli-shared-utils')
const { default: getTargets } = require('@babel/helper-compilation-targets')

const allModernTargets = getTargets(
{ esmodules: true },
{ ignoreBrowserslistConfig: true }
)

function getIntersectionTargets (targets, constraintTargets) {
const intersection = Object.keys(constraintTargets).reduce(
(results, browser) => {
// exclude the browsers that the user does not need
if (!targets[browser]) {
return results
}

// if the user-specified version is higher the minimum version that supports esmodule, than use it
results[browser] = semver.gt(
semver.coerce(constraintTargets[browser]),
semver.coerce(targets[browser])
)
? constraintTargets[browser]
: targets[browser]

return results
},
{}
)

return intersection
}

function getModernTargets (targets) {
// use the intersection of modern mode browsers and user defined targets config
return getIntersectionTargets(targets, allModernTargets)
}

const projectTargets = getTargets()
const projectModernTargets = getModernTargets(projectTargets)

module.exports = {
getTargets,
getModernTargets,
getIntersectionTargets,

projectTargets,
projectModernTargets
}
60 changes: 36 additions & 24 deletions packages/@vue/cli-service/lib/webpack/ModernModePlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ const fs = require('fs-extra')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

const { semver } = require('@vue/cli-shared-utils')
const { projectModernTargets } = require('../util/targets')

const minSafariVersion = projectModernTargets.safari
const minIOSVersion = projectModernTargets.ios
const supportsSafari10 =
(minSafariVersion && semver.lt(semver.coerce(minSafariVersion), '11.0.0')) ||
(minIOSVersion && semver.lt(semver.coerce(minIOSVersion), '11.0.0'))
const needsSafariFix = supportsSafari10

// 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()}}();`

Expand Down Expand Up @@ -77,32 +87,34 @@ class ModernModePlugin {
.filter(a => a.tagName === 'script' && a.attributes)
legacyAssets.forEach(a => { a.attributes.nomodule = '' })

if (this.unsafeInline) {
// inject inline Safari 10 nomodule fix
tags.push({
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] = {
source: function () {
return Buffer.from(safariFix)
},
size: function () {
return Buffer.byteLength(safariFix)
if (needsSafariFix) {
if (this.unsafeInline) {
// inject inline Safari 10 nomodule fix
tags.push({
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] = {
source: function () {
return Buffer.from(safariFix)
},
size: function () {
return Buffer.byteLength(safariFix)
}
}
tags.push({
tagName: 'script',
closeTag: true,
attributes: {
src: fullSafariFixPath
}
})
}
tags.push({
tagName: 'script',
closeTag: true,
attributes: {
src: fullSafariFixPath
}
})
}

tags.push(...legacyAssets)
Expand Down
1 change: 1 addition & 0 deletions packages/@vue/cli-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
},
"homepage": "https://cli.vuejs.org/",
"dependencies": {
"@babel/helper-compilation-targets": "^7.12.16",
"@soda/friendly-errors-webpack-plugin": "^1.8.0",
"@soda/get-current-script": "^1.0.2",
"@types/minimist": "^1.2.0",
Expand Down
0