7
7
*/
8
8
9
9
import { lookup as lookupMimeType } from 'mrmime' ;
10
+ import { createHash } from 'node:crypto' ;
11
+ import { readFileSync } from 'node:fs' ;
12
+ import type { ServerResponse } from 'node:http' ;
10
13
import { extname } from 'node:path' ;
11
14
import type { Connect , ViteDevServer } from 'vite' ;
12
15
import { AngularMemoryOutputFiles , AngularOutputAssets , pathnameWithoutBasePath } from '../utils' ;
@@ -17,6 +20,8 @@ export interface ComponentStyleRecord {
17
20
reload ?: boolean ;
18
21
}
19
22
23
+ const JS_TS_REGEXP = / \. [ c m ] ? [ t j ] s x ? $ / ;
24
+
20
25
export function createAngularAssetsMiddleware (
21
26
server : ViteDevServer ,
22
27
assets : AngularOutputAssets ,
@@ -38,15 +43,28 @@ export function createAngularAssetsMiddleware(
38
43
// Rewrite all build assets to a vite raw fs URL
39
44
const asset = assets . get ( pathname ) ;
40
45
if ( asset ) {
41
- // Workaround to disable Vite transformer middleware.
42
- // See: https://github.com/vitejs/vite/blob/746a1daab0395f98f0afbdee8f364cb6cf2f3b3f/packages/vite/src/node/server/middlewares/transform.ts#L201 and
43
- // https://github.com/vitejs/vite/blob/746a1daab0395f98f0afbdee8f364cb6cf2f3b3f/packages/vite/src/node/server/transformRequest.ts#L204-L206
44
- req . headers . accept = 'text/html' ;
45
-
46
- // The encoding needs to match what happens in the vite static middleware.
47
- // ref: https://github.com/vitejs/vite/blob/d4f13bd81468961c8c926438e815ab6b1c82735e/packages/vite/src/node/server/middlewares/static.ts#L163
48
- req . url = `${ server . config . base } @fs/${ encodeURI ( asset . source ) } ` ;
49
- next ( ) ;
46
+ // This is a workaround to serve JS and TS files without Vite transformations.
47
+ if ( JS_TS_REGEXP . test ( extension ) ) {
48
+ const contents = readFileSync ( asset . source ) ;
49
+ const etag = `W/${ createHash ( 'sha256' ) . update ( contents ) . digest ( 'hex' ) } ` ;
50
+ if ( checkAndHandleEtag ( req , res , etag ) ) {
51
+ return ;
52
+ }
53
+
54
+ const mimeType = lookupMimeType ( extension ) ;
55
+ if ( mimeType ) {
56
+ res . setHeader ( 'Content-Type' , mimeType ) ;
57
+ }
58
+
59
+ res . setHeader ( 'ETag' , etag ) ;
60
+ res . setHeader ( 'Cache-Control' , 'no-cache' ) ;
61
+ res . end ( contents ) ;
62
+ } else {
63
+ // The encoding needs to match what happens in the vite static middleware.
64
+ // ref: https://github.com/vitejs/vite/blob/d4f13bd81468961c8c926438e815ab6b1c82735e/packages/vite/src/node/server/middlewares/static.ts#L163
65
+ req . url = `${ server . config . base } @fs/${ encodeURI ( asset . source ) } ` ;
66
+ next ( ) ;
67
+ }
50
68
51
69
return ;
52
70
}
@@ -100,12 +118,8 @@ export function createAngularAssetsMiddleware(
100
118
componentStyle . used . add ( componentId ) ;
101
119
}
102
120
103
- // Report if there are no changes to avoid reprocessing
104
121
const etag = `W/"${ outputFile . contents . byteLength } -${ outputFile . hash } -${ componentId } "` ;
105
- if ( req . headers [ 'if-none-match' ] === etag ) {
106
- res . statusCode = 304 ;
107
- res . end ( ) ;
108
-
122
+ if ( checkAndHandleEtag ( req , res , etag ) ) {
109
123
return ;
110
124
}
111
125
@@ -134,12 +148,8 @@ export function createAngularAssetsMiddleware(
134
148
}
135
149
}
136
150
137
- // Avoid resending the content if it has not changed since last request
138
151
const etag = `W/"${ outputFile . contents . byteLength } -${ outputFile . hash } "` ;
139
- if ( req . headers [ 'if-none-match' ] === etag ) {
140
- res . statusCode = 304 ;
141
- res . end ( ) ;
142
-
152
+ if ( checkAndHandleEtag ( req , res , etag ) ) {
143
153
return ;
144
154
}
145
155
@@ -188,3 +198,18 @@ export function createAngularAssetsMiddleware(
188
198
next ( ) ;
189
199
} ;
190
200
}
201
+
202
+ function checkAndHandleEtag (
203
+ req : Connect . IncomingMessage ,
204
+ res : ServerResponse ,
205
+ etag : string ,
206
+ ) : boolean {
207
+ if ( req . headers [ 'if-none-match' ] === etag ) {
208
+ res . statusCode = 304 ;
209
+ res . end ( ) ;
210
+
211
+ return true ;
212
+ }
213
+
214
+ return false ;
215
+ }
0 commit comments