/
ssrManifestPlugin.ts
53 lines (50 loc) · 1.76 KB
/
ssrManifestPlugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import { relative } from 'path'
import { normalizePath } from '@rollup/pluginutils'
import { ResolvedConfig } from '..'
import { Plugin } from '../plugin'
import { chunkToEmittedCssFileMap } from '../plugins/css'
import { chunkToEmittedAssetsMap } from '../plugins/asset'
export function ssrManifestPlugin(config: ResolvedConfig): Plugin {
// module id => preload assets mapping
const ssrManifest: Record<string, string[]> = {}
const base = config.base
return {
name: 'vite:manifest',
generateBundle(_options, bundle) {
for (const file in bundle) {
const chunk = bundle[file]
if (chunk.type === 'chunk') {
// links for certain entry chunks are already generated in static HTML
// in those cases we only need to record info for non-entry chunks
const cssFiles = chunk.isEntry
? null
: chunkToEmittedCssFileMap.get(chunk)
const assetFiles = chunkToEmittedAssetsMap.get(chunk)
for (const id in chunk.modules) {
const normalizedId = normalizePath(relative(config.root, id))
const mappedChunks =
ssrManifest[normalizedId] || (ssrManifest[normalizedId] = [])
if (!chunk.isEntry) {
mappedChunks.push(base + chunk.fileName)
}
if (cssFiles) {
cssFiles.forEach((file) => {
mappedChunks.push(base + file)
})
}
if (assetFiles) {
assetFiles.forEach((file) => {
mappedChunks.push(base + file)
})
}
}
}
}
this.emitFile({
fileName: 'ssr-manifest.json',
type: 'asset',
source: JSON.stringify(ssrManifest, null, 2)
})
}
}
}