-
Notifications
You must be signed in to change notification settings - Fork 127
/
Copy pathmanifest.ts
64 lines (52 loc) · 2.21 KB
/
manifest.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
54
55
56
57
58
59
60
61
62
63
64
import path from 'path'
import { promises as fsp } from 'fs'
import createDebugger from 'debug'
import type { Plugin, ResolvedConfig } from 'vite'
import type { OutputBundle, PluginContext } from 'rollup'
import { UnifiedConfig } from './types'
import { filterEntrypointAssets } from './config'
const debug = createDebugger('vite-plugin-ruby:assets-manifest')
interface AssetsManifestChunk {
src?: string
file: string
}
type AssetsManifest = Map<string, AssetsManifestChunk>
// Internal: Writes a manifest file that allows to map an entrypoint asset file
// name to the corresponding output file name.
export function assetsManifestPlugin (): Plugin {
let config: ResolvedConfig
let viteRubyConfig: UnifiedConfig
// Internal: Vite ignores some entrypoint assets, so we need to manually
// fingerprint the files and move them to the output directory.
async function fingerprintRemainingAssets (ctx: PluginContext, bundle: OutputBundle, manifest: AssetsManifest) {
const remainingAssets = filterEntrypointAssets(viteRubyConfig.entrypoints)
for (const [filename, absoluteFilename] of remainingAssets) {
const content = await fsp.readFile(absoluteFilename)
const ref = ctx.emitFile({ name: path.basename(filename), type: 'asset', source: content })
const hashedFilename = ctx.getFileName(ref)
manifest.set(path.relative(config.root, absoluteFilename), { file: hashedFilename, src: filename })
}
}
return {
name: 'vite-plugin-ruby:assets-manifest',
apply: 'build',
enforce: 'post',
configResolved (resolvedConfig: ResolvedConfig) {
config = resolvedConfig
viteRubyConfig = (config as any).viteRuby
},
async generateBundle (_options, bundle) {
if (!config.build.manifest) return
const manifestDir = typeof config.build.manifest === 'string' ? path.dirname(config.build.manifest) : '.vite'
const fileName = `${manifestDir}/manifest-assets.json`
const manifest: AssetsManifest = new Map()
await fingerprintRemainingAssets(this, bundle, manifest)
debug({ manifest, fileName })
this.emitFile({
fileName,
type: 'asset',
source: JSON.stringify(Object.fromEntries(manifest), null, 2),
})
},
}
}