mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-14 18:13:54 +00:00
113 lines
3.5 KiB
JavaScript
113 lines
3.5 KiB
JavaScript
|
import invert from 'lodash/invert'
|
||
|
import { isUrl, urlJoin } from '@nuxt/utils'
|
||
|
import SSRRenderer from './ssr'
|
||
|
|
||
|
export default class ModernRenderer extends SSRRenderer {
|
||
|
constructor(serverContext) {
|
||
|
super(serverContext)
|
||
|
|
||
|
const { build: { publicPath }, router: { base } } = this.options
|
||
|
this.publicPath = isUrl(publicPath) ? publicPath : urlJoin(base, publicPath)
|
||
|
}
|
||
|
|
||
|
get assetsMapping() {
|
||
|
if (this._assetsMapping) {
|
||
|
return this._assetsMapping
|
||
|
}
|
||
|
|
||
|
const { clientManifest, modernManifest } = this.serverContext.resources
|
||
|
const legacyAssets = clientManifest.assetsMapping
|
||
|
const modernAssets = invert(modernManifest.assetsMapping)
|
||
|
const mapping = {}
|
||
|
|
||
|
for (const legacyJsFile in legacyAssets) {
|
||
|
const chunkNamesHash = legacyAssets[legacyJsFile]
|
||
|
mapping[legacyJsFile] = modernAssets[chunkNamesHash]
|
||
|
}
|
||
|
delete clientManifest.assetsMapping
|
||
|
delete modernManifest.assetsMapping
|
||
|
this._assetsMapping = mapping
|
||
|
|
||
|
return mapping
|
||
|
}
|
||
|
|
||
|
get isServerMode() {
|
||
|
return this.options.modern === 'server'
|
||
|
}
|
||
|
|
||
|
get rendererOptions() {
|
||
|
const rendererOptions = super.rendererOptions
|
||
|
if (this.isServerMode) {
|
||
|
rendererOptions.clientManifest = this.serverContext.resources.modernManifest
|
||
|
}
|
||
|
return rendererOptions
|
||
|
}
|
||
|
|
||
|
renderScripts(renderContext) {
|
||
|
const scripts = super.renderScripts(renderContext)
|
||
|
|
||
|
if (this.isServerMode) {
|
||
|
return scripts
|
||
|
}
|
||
|
|
||
|
const scriptPattern = /<script[^>]*?src="([^"]*?)"[^>]*?>[^<]*?<\/script>/g
|
||
|
|
||
|
return scripts.replace(scriptPattern, (scriptTag, jsFile) => {
|
||
|
const legacyJsFile = jsFile.replace(this.publicPath, '')
|
||
|
const modernJsFile = this.assetsMapping[legacyJsFile]
|
||
|
const { build: { crossorigin } } = this.options
|
||
|
const cors = `${crossorigin ? ` crossorigin="${crossorigin}"` : ''}`
|
||
|
const moduleTag = modernJsFile
|
||
|
? scriptTag
|
||
|
.replace('<script', `<script type="module"${cors}`)
|
||
|
.replace(legacyJsFile, modernJsFile)
|
||
|
: ''
|
||
|
const noModuleTag = scriptTag.replace('<script', `<script nomodule${cors}`)
|
||
|
|
||
|
return noModuleTag + moduleTag
|
||
|
})
|
||
|
}
|
||
|
|
||
|
getModernFiles(legacyFiles = []) {
|
||
|
const modernFiles = []
|
||
|
|
||
|
for (const legacyJsFile of legacyFiles) {
|
||
|
const modernFile = { ...legacyJsFile, modern: true }
|
||
|
if (modernFile.asType === 'script') {
|
||
|
const file = this.assetsMapping[legacyJsFile.file]
|
||
|
modernFile.file = file
|
||
|
modernFile.fileWithoutQuery = file.replace(/\?.*/, '')
|
||
|
}
|
||
|
modernFiles.push(modernFile)
|
||
|
}
|
||
|
|
||
|
return modernFiles
|
||
|
}
|
||
|
|
||
|
getPreloadFiles(renderContext) {
|
||
|
const preloadFiles = super.getPreloadFiles(renderContext)
|
||
|
// In eligible server modern mode, preloadFiles are modern bundles from modern renderer
|
||
|
return this.isServerMode ? preloadFiles : this.getModernFiles(preloadFiles)
|
||
|
}
|
||
|
|
||
|
renderResourceHints(renderContext) {
|
||
|
const resourceHints = super.renderResourceHints(renderContext)
|
||
|
if (this.isServerMode) {
|
||
|
return resourceHints
|
||
|
}
|
||
|
|
||
|
const linkPattern = /<link[^>]*?href="([^"]*?)"[^>]*?as="script"[^>]*?>/g
|
||
|
|
||
|
return resourceHints.replace(linkPattern, (linkTag, jsFile) => {
|
||
|
const legacyJsFile = jsFile.replace(this.publicPath, '')
|
||
|
const modernJsFile = this.assetsMapping[legacyJsFile]
|
||
|
if (!modernJsFile) {
|
||
|
return ''
|
||
|
}
|
||
|
const { crossorigin } = this.options.build
|
||
|
const cors = `${crossorigin ? ` crossorigin="${crossorigin}"` : ''}`
|
||
|
return linkTag.replace('rel="preload"', `rel="modulepreload"${cors}`).replace(legacyJsFile, modernJsFile)
|
||
|
})
|
||
|
}
|
||
|
}
|