feat(modern): remove inlined safari fix in csp mode (#7306)

This commit is contained in:
Xin Du (Clark) 2020-05-03 19:15:24 +01:00 committed by GitHub
parent ab3ff4de00
commit 2bd2c3853d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 9 deletions

View File

@ -23,6 +23,14 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
return this.dev ? 'cheap-module-eval-source-map' : false return this.dev ? 'cheap-module-eval-source-map' : false
} }
getCspScriptPolicy () {
const { csp } = this.buildContext.options.render
if (csp) {
const { policies = {} } = csp
return policies['script-src'] || policies['default-src'] || []
}
}
getFileName (...args) { getFileName (...args) {
if (this.buildContext.buildOptions.analyze) { if (this.buildContext.buildOptions.analyze) {
const [key] = args const [key] = args
@ -144,9 +152,12 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
} }
if (modern) { if (modern) {
const scriptPolicy = this.getCspScriptPolicy()
const noUnsafeInline = scriptPolicy && !scriptPolicy.includes('\'unsafe-inline\'')
plugins.push(new ModernModePlugin({ plugins.push(new ModernModePlugin({
targetDir: path.resolve(buildDir, 'dist', 'client'), targetDir: path.resolve(buildDir, 'dist', 'client'),
isModernBuild: this.isModern isModernBuild: this.isModern,
noUnsafeInline
})) }))
} }

View File

@ -10,9 +10,10 @@ const assetsMap = {}
const watcher = new EventEmitter() const watcher = new EventEmitter()
export default class ModernModePlugin { export default class ModernModePlugin {
constructor ({ targetDir, isModernBuild }) { constructor ({ targetDir, isModernBuild, noUnsafeInline }) {
this.targetDir = targetDir this.targetDir = targetDir
this.isModernBuild = isModernBuild this.isModernBuild = isModernBuild
this.noUnsafeInline = noUnsafeInline
} }
apply (compiler) { apply (compiler) {
@ -83,18 +84,40 @@ export default class ModernModePlugin {
const legacyAssets = (await this.getAssets(fileName)) const legacyAssets = (await this.getAssets(fileName))
.filter(a => a.tagName === 'script' && a.attributes) .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) { for (const a of legacyAssets) {
a.attributes.nomodule = true a.attributes.nomodule = true
data.body.push(a) data.body.push(a)
} }
if (this.noUnsafeInline) {
// inject the fix as an external script
const safariFixFilename = 'safari-nomodule-fix.js'
const safariFixPath = legacyAssets[0].attributes.src
.split('/')
.slice(0, -1)
.concat([safariFixFilename])
.join('/')
compilation.assets[safariFixFilename] = {
source: () => Buffer.from(safariNoModuleFix),
size: () => Buffer.byteLength(safariNoModuleFix)
}
data.body.push({
tagName: 'script',
closeTag: true,
attributes: {
src: safariFixPath
}
})
} else {
// inject Safari 10 nomodule fix
data.body.push({
tagName: 'script',
closeTag: true,
innerHTML: safariNoModuleFix
})
}
delete assetsMap[fileName] delete assetsMap[fileName]
cb() cb()
}) })

View File

@ -54,6 +54,11 @@ describe('modern client mode (SPA)', () => {
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-commons.app.js" as="script">') expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-commons.app.js" as="script">')
}) })
test('should contain safari nomodule fix', async () => {
const { body: response } = await rp(url('/'), { headers: { 'user-agent': modernUA } })
expect(response).toContain('src="/_nuxt/safari-nomodule-fix.js" crossorigin="use-credentials"')
})
test('should contain modern http2 pushed resources', async () => { test('should contain modern http2 pushed resources', async () => {
const { headers: { link } } = await rp(url('/'), { headers: { 'user-agent': modernUA } }) const { headers: { link } } = await rp(url('/'), { headers: { 'user-agent': modernUA } })
expect(link).toEqual([ expect(link).toEqual([

View File

@ -11,6 +11,7 @@ export default {
} }
}, },
render: { render: {
csp: true,
crossorigin: 'use-credentials', crossorigin: 'use-credentials',
http2: { http2: {
push: true push: true