Skip to content

Commit 3edecb6

Browse files
committed
borrow send() method from vite
1 parent f84bc4a commit 3edecb6

File tree

5 files changed

+110
-6
lines changed

5 files changed

+110
-6
lines changed

packages/preview/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@
3232
"author": "Rahul Kadyan <[email protected]>",
3333
"license": "MIT",
3434
"devDependencies": {
35-
"@vuedx/analyze": "^0.6.0",
3635
"@rollup/plugin-json": "^4.1.0",
3736
"@types/debug": "^4.1.5",
37+
"@types/etag": "^1.8.1",
38+
"@vuedx/analyze": "^0.6.0",
3839
"typescript": "^4.1.3",
3940
"vue": "^3.1.1"
4041
},
@@ -47,6 +48,7 @@
4748
"@vuedx/preview-shell": "workspace:*",
4849
"chalk": "^4.1.0",
4950
"debug": "^4.3.1",
51+
"etag": "^1.8.1",
5052
"fast-glob": "^3.2.5",
5153
"minimist": "^1.2.5",
5254
"picomatch": "^2.2.2",

packages/preview/src/cli.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import chalk from 'chalk';
22
import * as Path from 'path';
33
import * as FS from 'fs';
44
import { createServer } from 'vite';
5-
import { version as viteVersion } from 'vite/package.json';
6-
import { version as previewVersion } from '../package.json';
75
import { PreviewPlugin } from './index';
86
import VuePlugin from '@vitejs/plugin-vue';
97

@@ -38,7 +36,14 @@ export async function run(argv: {
3836

3937
const command = argv._[0];
4038

41-
console.log(chalk.cyan(`Preview v${previewVersion} (vite v${viteVersion})`));
39+
const { version: previewVersion } = JSON.parse(
40+
FS.readFileSync(require.resolve('../package.json'), 'utf-8')
41+
);
42+
const { version: viteVersion } = JSON.parse(
43+
FS.readFileSync(require.resolve('vite/package.json'), 'utf-8')
44+
);
45+
46+
console.log(chalk.cyan(`Preview v${String(previewVersion)} (vite v${String(viteVersion)})`));
4247
const { help, h, version, v } = argv;
4348

4449
if (help || h) {

packages/preview/src/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import glob from 'fast-glob';
22
import * as FS from 'fs';
33
import * as Path from 'path';
44
import sirv from 'sirv';
5-
import { ModuleNode, Plugin, send } from 'vite';
5+
import type { ModuleNode, Plugin } from 'vite';
66
import {
77
genEntryHTML,
88
genPreviewAppEntryScript,
99
genPreviewIFrameContent,
1010
genVSCodeKeyboardEventSupport,
1111
} from './generators';
12+
import { send } from './send';
1213
import { ComponentMetadataStore } from './store/ComponentMetadataStore';
1314
import { DescriptorStore } from './store/DescriptorStore';
1415
import type { FileSystemHost } from './store/FileSystemHost';
@@ -265,7 +266,10 @@ function PreviewPlugin(options?: PreviewPluginOptions): Plugin[] {
265266
Path.resolve(store.root, resource.fileName)
266267
);
267268
} else {
268-
return compiler.compile(Path.resolve(store.root, resource.fileName), resource.index);
269+
return await compiler.compile(
270+
Path.resolve(store.root, resource.fileName),
271+
resource.index
272+
);
269273
}
270274
}
271275

packages/preview/src/send.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import type { IncomingMessage, OutgoingHttpHeaders, ServerResponse } from 'http';
2+
import getEtag from 'etag';
3+
import type { SourceMap } from 'rollup';
4+
5+
const alias: Record<string, string | undefined> = {
6+
js: 'application/javascript',
7+
css: 'text/css',
8+
html: 'text/html',
9+
json: 'application/json',
10+
};
11+
12+
export interface SendOptions {
13+
etag?: string;
14+
cacheControl?: string;
15+
headers?: OutgoingHttpHeaders;
16+
map?: SourceMap | null;
17+
}
18+
19+
export function send(
20+
req: IncomingMessage,
21+
res: ServerResponse,
22+
content: string | Buffer,
23+
type: string,
24+
options: SendOptions = {}
25+
): void {
26+
const {
27+
etag = getEtag(content, { weak: true }),
28+
cacheControl = 'no-cache',
29+
headers,
30+
map,
31+
} = options;
32+
33+
if (res.writableEnded) {
34+
return;
35+
}
36+
37+
if (req.headers['if-none-match'] === etag) {
38+
res.statusCode = 304;
39+
res.end();
40+
41+
return;
42+
}
43+
44+
res.setHeader('Content-Type', alias[type] ?? type);
45+
res.setHeader('Cache-Control', cacheControl);
46+
res.setHeader('Etag', etag);
47+
48+
if (headers != null) {
49+
for (const name in headers) {
50+
const value = headers[name];
51+
if (value != null) {
52+
res.setHeader(name, value);
53+
}
54+
}
55+
}
56+
57+
// inject source map reference
58+
if (map?.mappings != null) {
59+
if (typeof content === 'string') {
60+
content += genSourceMapString(map);
61+
} else {
62+
content = Buffer.concat([content, Buffer.from(genSourceMapString(map))]);
63+
}
64+
}
65+
66+
res.statusCode = 200;
67+
res.end(content);
68+
}
69+
70+
function genSourceMapString(map: SourceMap | string | undefined): string {
71+
if (typeof map !== 'string') {
72+
map = JSON.stringify(map);
73+
}
74+
75+
return `\n//# sourceMappingURL=data:application/json;base64,${Buffer.from(map).toString(
76+
'base64'
77+
)}`;
78+
}

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)