-
-
Notifications
You must be signed in to change notification settings - Fork 105
/
vite-plugin-rsc-index.ts
95 lines (92 loc) · 2.34 KB
/
vite-plugin-rsc-index.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import type { Plugin } from 'vite';
// HACK Depending on a different plugin isn't ideal.
// Maybe we could put in vite config object?
import { SRC_MAIN } from './vite-plugin-rsc-managed.js';
import { codeToInject } from '../renderers/utils.js';
export function rscIndexPlugin(opts: {
basePath: string;
srcDir: string;
htmlAttrs: string;
htmlHead: string;
cssAssets?: string[];
}): Plugin {
const indexHtml = 'index.html';
const html = `
<!doctype html>
<html${opts.htmlAttrs ? ' ' + opts.htmlAttrs : ''}>
<head>
${opts.htmlHead}
</head>
<body>
<script src="${opts.basePath}${opts.srcDir}/${SRC_MAIN}" async type="module"></script>
</body>
</html>
`;
return {
name: 'rsc-index-plugin',
config() {
return {
optimizeDeps: {
entries: [`${opts.srcDir}/${SRC_MAIN}.*`],
},
};
},
options(options) {
if (typeof options.input === 'string') {
throw new Error('string input is unsupported');
}
if (Array.isArray(options.input)) {
throw new Error('array input is unsupported');
}
return {
...options,
input: {
indexHtml,
...options.input,
},
};
},
configureServer(server) {
return () => {
server.middlewares.use((req, res) => {
server
.transformIndexHtml(req.url || '', html)
.then((content) => {
res.statusCode = 200;
res.setHeader('content-type', 'text/html; charset=utf-8');
res.end(content);
})
.catch((err) => {
console.error('Error transforming index.html', err);
res.statusCode = 500;
res.end('Internal Server Error');
});
});
};
},
resolveId(id) {
if (id === indexHtml) {
return { id: indexHtml, moduleSideEffects: true };
}
},
load(id) {
if (id === indexHtml) {
return html;
}
},
transformIndexHtml() {
return [
{
tag: 'script',
attrs: { type: 'module', async: true },
children: codeToInject,
},
...(opts.cssAssets || []).map((href) => ({
tag: 'link',
attrs: { rel: 'stylesheet', href: `${opts.basePath}${href}` },
injectTo: 'head' as const,
})),
];
},
};
}