mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-04-24 22:09:54 -05:00
@@ -76,6 +76,21 @@ test('modern mode', async () => {
|
||||
expect(await getH1Text()).toMatch('Welcome to Your Vue.js App')
|
||||
})
|
||||
|
||||
test('no-unsafe-inline', async () => {
|
||||
const project = await create('no-unsafe-inline', defaultPreset)
|
||||
|
||||
const { stdout } = await project.run('vue-cli-service build --modern --no-unsafe-inline')
|
||||
expect(stdout).toMatch('Build complete.')
|
||||
|
||||
// should output a seperate safari-nomodule-fix bundle
|
||||
const files = await fs.readdir(path.join(project.dir, 'dist/js'))
|
||||
expect(files.some(f => /^safari-nomodule-fix\.js$/.test(f))).toBe(true)
|
||||
|
||||
// should contain no inline scripts in the output html
|
||||
const index = await project.read('dist/index.html')
|
||||
expect(index).not.toMatch(/[^>]\s*<\/script>/)
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
if (browser) {
|
||||
await browser.close()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const defaults = {
|
||||
clean: true,
|
||||
target: 'app'
|
||||
target: 'app',
|
||||
'unsafe-inline': true
|
||||
}
|
||||
|
||||
const buildModes = {
|
||||
@@ -25,6 +26,7 @@ module.exports = (api, options) => {
|
||||
'--mode': `specify env mode (default: production)`,
|
||||
'--dest': `specify output directory (default: ${options.outputDir})`,
|
||||
'--modern': `build app targeting modern browsers with auto fallback`,
|
||||
'--no-unsafe-inline': `build app without introducing inline scripts`,
|
||||
'--target': `app | lib | wc | wc-async (default: ${defaults.target})`,
|
||||
'--name': `name for lib or web-component mode (default: "name" in package.json or entry filename)`,
|
||||
'--no-clean': `do not remove the dist directory before building the project`,
|
||||
|
||||
@@ -18,7 +18,8 @@ module.exports = (api, args, options) => {
|
||||
.plugin('modern-mode-legacy')
|
||||
.use(ModernModePlugin, [{
|
||||
targetDir,
|
||||
isModernBuild: false
|
||||
isModernBuild: false,
|
||||
unsafeInline: args['unsafe-inline']
|
||||
}])
|
||||
} else {
|
||||
// Inject plugin to read non-modern build stats and inject HTML
|
||||
@@ -26,7 +27,8 @@ module.exports = (api, args, options) => {
|
||||
.plugin('modern-mode-modern')
|
||||
.use(ModernModePlugin, [{
|
||||
targetDir,
|
||||
isModernBuild: true
|
||||
isModernBuild: true,
|
||||
unsafeInline: args['unsafe-inline']
|
||||
}])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ const path = require('path')
|
||||
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()}}();`
|
||||
|
||||
class ModernModePlugin {
|
||||
constructor ({ targetDir, isModernBuild }) {
|
||||
constructor ({ targetDir, isModernBuild, unsafeInline }) {
|
||||
this.targetDir = targetDir
|
||||
this.isModernBuild = isModernBuild
|
||||
this.unsafeInline = unsafeInline
|
||||
}
|
||||
|
||||
apply (compiler) {
|
||||
@@ -56,13 +57,6 @@ class ModernModePlugin {
|
||||
}
|
||||
})
|
||||
|
||||
// inject Safari 10 nomodule fix
|
||||
data.body.push({
|
||||
tagName: 'script',
|
||||
closeTag: true,
|
||||
innerHTML: safariFix
|
||||
})
|
||||
|
||||
// inject links for legacy assets as <script nomodule>
|
||||
const htmlName = path.basename(data.plugin.options.filename)
|
||||
// Watch out for output files in sub directories
|
||||
@@ -71,6 +65,38 @@ class ModernModePlugin {
|
||||
const legacyAssets = JSON.parse(await fs.readFile(tempFilename, 'utf-8'))
|
||||
.filter(a => a.tagName === 'script' && a.attributes)
|
||||
legacyAssets.forEach(a => { a.attributes.nomodule = '' })
|
||||
|
||||
if (this.unsafeInline) {
|
||||
// inject inline Safari 10 nomodule fix
|
||||
data.body.push({
|
||||
tagName: 'script',
|
||||
closeTag: true,
|
||||
innerHTML: safariFix
|
||||
})
|
||||
} else {
|
||||
// inject the fix as an external script
|
||||
const safariFixPath = legacyAssets[0].attributes.src
|
||||
.split('/')
|
||||
.slice(0, -1)
|
||||
.concat(['safari-nomodule-fix.js'])
|
||||
.join('/')
|
||||
compilation.assets[safariFixPath] = {
|
||||
source: function () {
|
||||
return new Buffer(safariFix)
|
||||
},
|
||||
size: function () {
|
||||
return Buffer.byteLength(safariFix)
|
||||
}
|
||||
}
|
||||
data.body.push({
|
||||
tagName: 'script',
|
||||
closeTag: true,
|
||||
attributes: {
|
||||
src: safariFixPath
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
data.body.push(...legacyAssets)
|
||||
await fs.remove(tempFilename)
|
||||
cb()
|
||||
|
||||
Reference in New Issue
Block a user