mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-23 14:15:13 +00:00
fest: add build.corssorgin (#4472)
This commit is contained in:
parent
9c15c18d1b
commit
e6808c57ef
@ -5,6 +5,7 @@ export default () => ({
|
||||
analyze: false,
|
||||
profile: process.argv.includes('--profile'),
|
||||
extractCSS: false,
|
||||
crossorigin: undefined,
|
||||
cssSourceMap: undefined,
|
||||
ssr: undefined,
|
||||
parallel: false,
|
||||
|
@ -52,7 +52,7 @@ export default ({ options, nuxt, renderRoute, resources }) => async function nux
|
||||
|
||||
const links = pushAssets
|
||||
? pushAssets(req, res, publicPath, preloadFiles)
|
||||
: defaultPushAssets(preloadFiles, shouldPush, publicPath, options.dev)
|
||||
: defaultPushAssets(preloadFiles, shouldPush, publicPath, options)
|
||||
|
||||
// Pass with single Link header
|
||||
// https://blog.cloudflare.com/http-2-server-push-with-multiple-assets-per-link-header
|
||||
@ -87,13 +87,13 @@ export default ({ options, nuxt, renderRoute, resources }) => async function nux
|
||||
}
|
||||
}
|
||||
|
||||
const defaultPushAssets = (preloadFiles, shouldPush, publicPath, isDev) => {
|
||||
if (shouldPush && isDev) {
|
||||
const defaultPushAssets = (preloadFiles, shouldPush, publicPath, options) => {
|
||||
if (shouldPush && options.dev) {
|
||||
consola.warn('http2.shouldPush is deprecated. Use http2.pushAssets function')
|
||||
}
|
||||
|
||||
const links = []
|
||||
preloadFiles.forEach(({ file, asType, fileWithoutQuery }) => {
|
||||
preloadFiles.forEach(({ file, asType, fileWithoutQuery, modern }) => {
|
||||
// By default, we only preload scripts or css
|
||||
/* istanbul ignore if */
|
||||
if (!shouldPush && asType !== 'script' && asType !== 'style') {
|
||||
@ -105,7 +105,11 @@ const defaultPushAssets = (preloadFiles, shouldPush, publicPath, isDev) => {
|
||||
return
|
||||
}
|
||||
|
||||
links.push(`<${publicPath}${file}>; rel=preload; as=${asType}`)
|
||||
const crossorigin = options.build.crossorigin
|
||||
const cors = `${crossorigin ? ` crossorigin=${crossorigin};` : ''}`
|
||||
const ref = modern ? 'modulepreload' : 'preload'
|
||||
|
||||
links.push(`<${publicPath}${file}>; rel=${ref};${cors} as=${asType}`)
|
||||
})
|
||||
return links
|
||||
}
|
||||
|
@ -55,8 +55,10 @@ export default class VueRenderer {
|
||||
return context.renderScripts().replace(scriptPattern, (scriptTag, jsFile) => {
|
||||
const legacyJsFile = jsFile.replace(publicPath, '')
|
||||
const modernJsFile = this.assetsMapping[legacyJsFile]
|
||||
const moduleTag = scriptTag.replace('<script', '<script type="module"').replace(legacyJsFile, modernJsFile)
|
||||
const noModuleTag = scriptTag.replace('<script', '<script nomodule')
|
||||
const crossorigin = this.context.options.build.crossorigin
|
||||
const cors = `${crossorigin ? ` crossorigin="${crossorigin}"` : ''}`
|
||||
const moduleTag = scriptTag.replace('<script', `<script type="module"${cors}`).replace(legacyJsFile, modernJsFile)
|
||||
const noModuleTag = scriptTag.replace('<script', `<script nomodule${cors}`)
|
||||
return noModuleTag + moduleTag
|
||||
})
|
||||
}
|
||||
@ -66,7 +68,7 @@ export default class VueRenderer {
|
||||
getModernFiles(legacyFiles = []) {
|
||||
const modernFiles = []
|
||||
for (const legacyJsFile of legacyFiles) {
|
||||
const modernFile = { ...legacyJsFile }
|
||||
const modernFile = { ...legacyJsFile, modern: true }
|
||||
if (modernFile.asType === 'script') {
|
||||
const file = this.assetsMapping[legacyJsFile.file]
|
||||
modernFile.file = file
|
||||
@ -91,7 +93,9 @@ export default class VueRenderer {
|
||||
return context.renderResourceHints().replace(linkPattern, (linkTag, jsFile) => {
|
||||
const legacyJsFile = jsFile.replace(publicPath, '')
|
||||
const modernJsFile = this.assetsMapping[legacyJsFile]
|
||||
return linkTag.replace('rel="preload"', 'rel="modulepreload"').replace(legacyJsFile, modernJsFile)
|
||||
const crossorigin = this.context.options.build.crossorigin
|
||||
const cors = `${crossorigin ? ` crossorigin="${crossorigin}"` : ''}`
|
||||
return linkTag.replace('rel="preload"', `rel="modulepreload"${cors}`).replace(legacyJsFile, modernJsFile)
|
||||
})
|
||||
}
|
||||
return context.renderResourceHints()
|
||||
|
@ -5,6 +5,7 @@ import BundleAnalyzer from 'webpack-bundle-analyzer'
|
||||
import OptimizeCSSAssetsPlugin from 'optimize-css-assets-webpack-plugin'
|
||||
import FriendlyErrorsWebpackPlugin from '@nuxt/friendly-errors-webpack-plugin'
|
||||
|
||||
import CorsPlugin from '../plugins/vue/cors'
|
||||
import ModernModePlugin from '../plugins/vue/modern'
|
||||
import VueSSRClientPlugin from '../plugins/vue/client'
|
||||
import WebpackBaseConfig from './base'
|
||||
@ -124,6 +125,12 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
|
||||
}))
|
||||
}
|
||||
|
||||
if (this.options.build.crossorigin) {
|
||||
plugins.push(new CorsPlugin({
|
||||
crossorigin: this.options.build.crossorigin
|
||||
}))
|
||||
}
|
||||
|
||||
return plugins
|
||||
}
|
||||
|
||||
|
22
packages/webpack/src/plugins/vue/cors.js
Normal file
22
packages/webpack/src/plugins/vue/cors.js
Normal file
@ -0,0 +1,22 @@
|
||||
export default class CorsPlugin {
|
||||
constructor({ crossorigin }) {
|
||||
this.crossorigin = crossorigin
|
||||
}
|
||||
|
||||
apply(compiler) {
|
||||
const ID = `vue-cors-plugin`
|
||||
compiler.hooks.compilation.tap(ID, (compilation) => {
|
||||
compilation.hooks.htmlWebpackPluginAlterAssetTags.tap(ID, (data) => {
|
||||
if (this.crossorigin != null) {
|
||||
[...data.head, ...data.body].forEach((tag) => {
|
||||
if (tag.tagName === 'script' || tag.tagName === 'link') {
|
||||
if (tag.attributes) {
|
||||
tag.attributes.crossorigin = this.crossorigin
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
1
test/fixtures/modern/nuxt.config.js
vendored
1
test/fixtures/modern/nuxt.config.js
vendored
@ -1,6 +1,7 @@
|
||||
export default {
|
||||
modern: true,
|
||||
build: {
|
||||
crossorigin: 'use-credentials',
|
||||
filenames: {
|
||||
app: ({ isModern }) => {
|
||||
return `${isModern ? 'modern-' : ''}[name].js`
|
||||
|
@ -13,29 +13,29 @@ describe('modern client mode (SSR)', () => {
|
||||
|
||||
test('should contain nomodule legacy resources', async () => {
|
||||
const response = await rp(url('/'))
|
||||
expect(response).toContain('script nomodule src="/_nuxt/app.js')
|
||||
expect(response).toContain('script nomodule src="/_nuxt/commons.app.js')
|
||||
expect(response).toContain('script nomodule crossorigin="use-credentials" src="/_nuxt/app.js')
|
||||
expect(response).toContain('script nomodule crossorigin="use-credentials" src="/_nuxt/commons.app.js')
|
||||
})
|
||||
|
||||
test('should contain module modern resources', async () => {
|
||||
const response = await rp(url('/'))
|
||||
expect(response).toContain('<script type="module" src="/_nuxt/modern-app.js"')
|
||||
expect(response).toContain('<script type="module" src="/_nuxt/modern-commons.app.js"')
|
||||
expect(response).toContain('<script type="module" crossorigin="use-credentials" src="/_nuxt/modern-app.js"')
|
||||
expect(response).toContain('<script type="module" crossorigin="use-credentials" src="/_nuxt/modern-commons.app.js"')
|
||||
})
|
||||
|
||||
test('should contain module preload resources', async () => {
|
||||
const response = await rp(url('/'))
|
||||
expect(response).toContain('<link rel="modulepreload" href="/_nuxt/modern-app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" href="/_nuxt/modern-commons.app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-commons.app.js" as="script">')
|
||||
})
|
||||
|
||||
test('should contain module http2 pushed resources', async () => {
|
||||
const { headers: { link } } = await rp(url('/'), { resolveWithFullResponse: true })
|
||||
expect(link).toEqual([
|
||||
'</_nuxt/modern-runtime.js>; rel=preload; as=script',
|
||||
'</_nuxt/modern-commons.app.js>; rel=preload; as=script',
|
||||
'</_nuxt/modern-app.js>; rel=preload; as=script',
|
||||
`</_nuxt/modern-${wChunk('pages/index.js')}>; rel=preload; as=script`
|
||||
'</_nuxt/modern-runtime.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-commons.app.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-app.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
`</_nuxt/modern-${wChunk('pages/index.js')}>; rel=modulepreload; crossorigin=use-credentials; as=script`
|
||||
].join(', '))
|
||||
})
|
||||
|
||||
|
@ -47,10 +47,10 @@ describe('modern server mode', () => {
|
||||
resolveWithFullResponse: true
|
||||
})
|
||||
expect(link).toEqual([
|
||||
'</_nuxt/runtime.js>; rel=preload; as=script',
|
||||
'</_nuxt/commons.app.js>; rel=preload; as=script',
|
||||
'</_nuxt/app.js>; rel=preload; as=script',
|
||||
`</_nuxt/${wChunk('pages/index.js')}>; rel=preload; as=script`
|
||||
'</_nuxt/runtime.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/commons.app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
`</_nuxt/${wChunk('pages/index.js')}>; rel=preload; crossorigin=use-credentials; as=script`
|
||||
].join(', '))
|
||||
})
|
||||
|
||||
@ -60,10 +60,10 @@ describe('modern server mode', () => {
|
||||
resolveWithFullResponse: true
|
||||
})
|
||||
expect(link).toEqual([
|
||||
'</_nuxt/modern-runtime.js>; rel=preload; as=script',
|
||||
'</_nuxt/modern-commons.app.js>; rel=preload; as=script',
|
||||
'</_nuxt/modern-app.js>; rel=preload; as=script',
|
||||
`</_nuxt/modern-${wChunk('pages/index.js')}>; rel=preload; as=script`
|
||||
'</_nuxt/modern-runtime.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-commons.app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
`</_nuxt/modern-${wChunk('pages/index.js')}>; rel=preload; crossorigin=use-credentials; as=script`
|
||||
].join(', '))
|
||||
})
|
||||
|
||||
|
@ -21,28 +21,28 @@ describe('modern client mode (SPA)', () => {
|
||||
|
||||
test('should contain nomodule legacy resources', async () => {
|
||||
const response = await rp(url('/'))
|
||||
expect(response).toContain('src="/_nuxt/app.js" nomodule')
|
||||
expect(response).toContain('src="/_nuxt/commons.app.js" nomodule')
|
||||
expect(response).toContain('src="/_nuxt/app.js" crossorigin="use-credentials" nomodule')
|
||||
expect(response).toContain('src="/_nuxt/commons.app.js" crossorigin="use-credentials" nomodule')
|
||||
})
|
||||
|
||||
test('should contain module modern resources', async () => {
|
||||
const response = await rp(url('/'))
|
||||
expect(response).toContain('<script type="module" src="/_nuxt/modern-app.js"')
|
||||
expect(response).toContain('<script type="module" src="/_nuxt/modern-commons.app.js"')
|
||||
expect(response).toContain('<script type="module" src="/_nuxt/modern-app.js" crossorigin="use-credentials"')
|
||||
expect(response).toContain('<script type="module" src="/_nuxt/modern-commons.app.js" crossorigin="use-credentials"')
|
||||
})
|
||||
|
||||
test.skip('should contain module preload resources', async () => {
|
||||
const response = await rp(url('/'))
|
||||
expect(response).toContain('<link rel="modulepreload" href="/_nuxt/modern-app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" href="/_nuxt/modern-commons.app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-commons.app.js" as="script">')
|
||||
})
|
||||
|
||||
test('should contain module http2 pushed resources', async () => {
|
||||
const { headers: { link } } = await rp(url('/'), { resolveWithFullResponse: true })
|
||||
expect(link).toEqual([
|
||||
'</_nuxt/modern-runtime.js>; rel=preload; as=script',
|
||||
'</_nuxt/modern-commons.app.js>; rel=preload; as=script',
|
||||
'</_nuxt/modern-app.js>; rel=preload; as=script'
|
||||
'</_nuxt/modern-runtime.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-commons.app.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-app.js>; rel=modulepreload; crossorigin=use-credentials; as=script'
|
||||
].join(', '))
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user