A lightweight TypeScript utility for parsing Vite's manifest.json files to extract necessary HTML tags for scripts, CSS, and preloaded assets.
yarn add use-vite-manifest-parser
or
npm install use-vite-manifest-parser
- 🔍 Efficiently parses Vite's manifest.json files
- 🏷️ Extracts essential HTML tags for your application
- 📝 Generates lists of links, preloads, and scripts
- 🔄 Handles complex dependency chains
- ⚡ Type-safe with full TypeScript support
- 📦 Minimal dependencies (only uses lodash/forEach)
import parse from 'use-vite-manifest-parser';
import fs from 'fs';
// Load the manifest file generated by Vite
const manifestJson = JSON.parse(fs.readFileSync('./dist/manifest.json', 'utf-8'));
// Parse the manifest to get HTML tags
const tags = parse(manifestJson);
// Result structure:
// {
// links: ['assets/style.css', ...],
// preloads: ['assets/chunk.js', ...],
// scripts: ['assets/main.js', ...]
// }
// Use these tags to generate HTML or inject in your server-side rendering
The parser expects a Vite manifest structure which typically looks like:
{
"app/index.tsx": {
"file": "assets/index-abc123.js",
"css": ["assets/index-xyz789.css"],
"isEntry": true,
"src": "app/index.tsx",
"imports": ["app/shared.ts"],
"dynamicImports": ["app/dynamic.tsx"]
},
"app/shared.ts": {
"file": "assets/shared-def456.js",
"src": "app/shared.ts"
},
"app/dynamic.tsx": {
"file": "assets/dynamic-ghi789.js",
"isDynamicEntry": true,
"src": "app/dynamic.tsx"
}
}
function parse(input: Manifest): Tags;
Processes a Vite manifest to extract HTML tags for scripts, styles, and preloads.
type Manifest = Record<string, ManifestChunk>;
type ManifestChunk = {
assets?: string[];
css?: string[];
dynamicImports?: string[];
file: string;
imports?: string[];
isDynamicEntry?: boolean;
isEntry?: boolean;
name?: string;
src?: string;
};
type Tags = {
links: string[];
preloads: string[];
scripts: string[];
};
import parse from 'use-vite-manifest-parser';
// Load the manifest file during build and create a JSON string
// This is typically done in your build process
const manifestJson = JSON.stringify({
'app/index.tsx': {
file: 'assets/index-abc123.js',
css: ['assets/index-xyz789.css'],
isEntry: true
}
});
export default {
async fetch(request, env) {
// Parse the manifest string in the worker
const manifest = JSON.parse(manifestJson);
const tags = parse(manifest);
const html = `<!DOCTYPE html>
<html>
<head>
${tags.links.map(css => `<link rel="stylesheet" href="/${css}">`).join('\n ')}
${tags.preloads.map(js => `<link rel="modulepreload" href="/${js}">`).join('\n ')}
</head>
<body>
<div id="app"></div>
${tags.scripts.map(js => `<script type="module" src="/${js}"></script>`).join('\n ')}
</body>
</html>`;
return new Response(html, {
headers: {
'Content-Type': 'text/html'
}
});
}
};
The library includes comprehensive test coverage. Run tests with:
yarn test
Tests cover various scenarios including:
- Multiple entry points
- Multiple CSS files
- Complex import chains
- Dynamic imports
- Missing optional properties
- Circular dependencies
- Missing chunk references
Felipe Rohde
- Twitter: @felipe_rohde
- Github: @feliperohdee
- Email: feliperohdee@gmail.com
MIT © Felipe Rohde