@analogjs/vite-plugin-angular 3.0.0-alpha.7 → 3.0.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -9
- package/setup-vitest.js +154 -193
- package/setup-vitest.js.map +1 -1
- package/src/index.d.ts +1 -1
- package/src/index.js +6 -2
- package/src/index.js.map +1 -1
- package/src/lib/angular-build-optimizer-plugin.js +48 -62
- package/src/lib/angular-build-optimizer-plugin.js.map +1 -1
- package/src/lib/angular-jit-plugin.js +31 -37
- package/src/lib/angular-jit-plugin.js.map +1 -1
- package/src/lib/angular-pending-tasks.plugin.js +17 -18
- package/src/lib/angular-pending-tasks.plugin.js.map +1 -1
- package/src/lib/angular-vite-plugin.js +790 -1076
- package/src/lib/angular-vite-plugin.js.map +1 -1
- package/src/lib/angular-vitest-plugin.d.ts +16 -12
- package/src/lib/angular-vitest-plugin.js +97 -114
- package/src/lib/angular-vitest-plugin.js.map +1 -1
- package/src/lib/compiler-plugin.js +40 -44
- package/src/lib/compiler-plugin.js.map +1 -1
- package/src/lib/component-resolvers.d.ts +4 -2
- package/src/lib/component-resolvers.js +93 -64
- package/src/lib/component-resolvers.js.map +1 -1
- package/src/lib/host.js +69 -101
- package/src/lib/host.js.map +1 -1
- package/src/lib/live-reload-plugin.js +51 -63
- package/src/lib/live-reload-plugin.js.map +1 -1
- package/src/lib/nx-folder-plugin.js +18 -16
- package/src/lib/nx-folder-plugin.js.map +1 -1
- package/src/lib/plugins/file-replacements.plugin.js +35 -62
- package/src/lib/plugins/file-replacements.plugin.js.map +1 -1
- package/src/lib/router-plugin.js +23 -23
- package/src/lib/router-plugin.js.map +1 -1
- package/src/lib/tools/package.json +2 -5
- package/src/lib/tools/src/builders/vite/vite-build.impl.js +31 -38
- package/src/lib/tools/src/builders/vite/vite-build.impl.js.map +1 -1
- package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js +52 -60
- package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js.map +1 -1
- package/src/lib/tools/src/index.js +0 -2
- package/src/lib/utils/devkit.js +34 -38
- package/src/lib/utils/devkit.js.map +1 -1
- package/src/lib/utils/rolldown.d.ts +2 -0
- package/src/lib/utils/rolldown.js +12 -0
- package/src/lib/utils/rolldown.js.map +1 -0
- package/src/lib/utils/source-file-cache.js +35 -37
- package/src/lib/utils/source-file-cache.js.map +1 -1
- package/README.md +0 -91
- package/src/lib/models.js +0 -1
- package/src/lib/models.js.map +0 -1
- package/src/lib/tools/README.md +0 -3
- package/src/lib/tools/src/index.js.map +0 -1
- package/src/lib/utils/compiler-plugin-options.js +0 -1
- package/src/lib/utils/compiler-plugin-options.js.map +0 -1
- package/src/lib/utils/hmr-candidates.js +0 -272
- package/src/lib/utils/hmr-candidates.js.map +0 -1
|
@@ -1,1100 +1,814 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
1
|
+
import { angularFullVersion, cjt, createAngularCompilation, sourceFileCache } from "./utils/devkit.js";
|
|
2
|
+
import { getJsTransformConfigKey, isRolldown } from "./utils/rolldown.js";
|
|
3
|
+
import { buildOptimizerPlugin } from "./angular-build-optimizer-plugin.js";
|
|
4
|
+
import { jitPlugin } from "./angular-jit-plugin.js";
|
|
5
|
+
import { createCompilerPlugin, createRolldownCompilerPlugin } from "./compiler-plugin.js";
|
|
6
|
+
import { StyleUrlsResolver, TemplateUrlsResolver } from "./component-resolvers.js";
|
|
7
|
+
import { augmentHostWithCaching, augmentHostWithResources, augmentProgramWithVersioning, mergeTransformers } from "./host.js";
|
|
8
|
+
import { angularVitestPlugins } from "./angular-vitest-plugin.js";
|
|
9
|
+
import { pendingTasksPlugin } from "./angular-pending-tasks.plugin.js";
|
|
10
|
+
import { liveReloadPlugin } from "./live-reload-plugin.js";
|
|
11
|
+
import { nxFolderPlugin } from "./nx-folder-plugin.js";
|
|
12
|
+
import { replaceFiles } from "./plugins/file-replacements.plugin.js";
|
|
13
|
+
import { routerPlugin } from "./router-plugin.js";
|
|
14
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
15
|
+
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
16
|
+
import * as compilerCli from "@angular/compiler-cli";
|
|
17
|
+
import { createRequire } from "node:module";
|
|
18
|
+
import * as ngCompiler from "@angular/compiler";
|
|
19
|
+
import { globSync } from "tinyglobby";
|
|
20
|
+
import { defaultClientConditions, normalizePath, preprocessCSS } from "vite";
|
|
21
|
+
import { createHash } from "node:crypto";
|
|
22
|
+
//#region packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts
|
|
23
|
+
var require = createRequire(import.meta.url);
|
|
24
|
+
var DiagnosticModes = /* @__PURE__ */ function(DiagnosticModes) {
|
|
25
|
+
DiagnosticModes[DiagnosticModes["None"] = 0] = "None";
|
|
26
|
+
DiagnosticModes[DiagnosticModes["Option"] = 1] = "Option";
|
|
27
|
+
DiagnosticModes[DiagnosticModes["Syntactic"] = 2] = "Syntactic";
|
|
28
|
+
DiagnosticModes[DiagnosticModes["Semantic"] = 4] = "Semantic";
|
|
29
|
+
DiagnosticModes[DiagnosticModes["All"] = 7] = "All";
|
|
30
|
+
return DiagnosticModes;
|
|
31
|
+
}({});
|
|
31
32
|
/**
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
}
|
|
675
|
-
async function performCompilation(config, ids) {
|
|
676
|
-
let resolve;
|
|
677
|
-
const previousLock = compilationLock;
|
|
678
|
-
compilationLock = new Promise((r) => {
|
|
679
|
-
resolve = r;
|
|
680
|
-
});
|
|
681
|
-
try {
|
|
682
|
-
await previousLock;
|
|
683
|
-
await _doPerformCompilation(config, ids);
|
|
684
|
-
}
|
|
685
|
-
finally {
|
|
686
|
-
resolve();
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* This method share mutable state and performs the actual compilation work.
|
|
691
|
-
* It should not be called concurrently. Use `performCompilation` which wraps this method in a lock to ensure only one compilation runs at a time.
|
|
692
|
-
*/
|
|
693
|
-
async function _doPerformCompilation(config, ids) {
|
|
694
|
-
// Forward `ids` (modified files) so the Compilation API path can do
|
|
695
|
-
// incremental re-analysis instead of a full recompile on every change.
|
|
696
|
-
if (pluginOptions.useAngularCompilationAPI) {
|
|
697
|
-
await performAngularCompilation(config, ids);
|
|
698
|
-
return;
|
|
699
|
-
}
|
|
700
|
-
const isProd = config.mode === 'production';
|
|
701
|
-
const modifiedFiles = new Set(ids ?? []);
|
|
702
|
-
sourceFileCache.invalidate(modifiedFiles);
|
|
703
|
-
if (ids?.length) {
|
|
704
|
-
for (const id of ids || []) {
|
|
705
|
-
fileTransformMap.delete(id);
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
// Cached include discovery (invalidated only on FS events)
|
|
709
|
-
if (pluginOptions.include.length > 0 && includeCache.length === 0) {
|
|
710
|
-
includeCache = findIncludes();
|
|
711
|
-
}
|
|
712
|
-
const resolvedTsConfigPath = resolveTsConfigPath();
|
|
713
|
-
const tsconfigKey = [
|
|
714
|
-
resolvedTsConfigPath,
|
|
715
|
-
isProd ? 'prod' : 'dev',
|
|
716
|
-
isTest ? 'test' : 'app',
|
|
717
|
-
config.build?.lib ? 'lib' : 'nolib',
|
|
718
|
-
].join('|');
|
|
719
|
-
let cached = tsconfigOptionsCache.get(tsconfigKey);
|
|
720
|
-
if (!cached) {
|
|
721
|
-
const read = compilerCli.readConfiguration(resolvedTsConfigPath, {
|
|
722
|
-
suppressOutputPathCheck: true,
|
|
723
|
-
outDir: undefined,
|
|
724
|
-
sourceMap: false,
|
|
725
|
-
inlineSourceMap: !isProd,
|
|
726
|
-
inlineSources: !isProd,
|
|
727
|
-
declaration: false,
|
|
728
|
-
declarationMap: false,
|
|
729
|
-
allowEmptyCodegenFiles: false,
|
|
730
|
-
annotationsAs: 'decorators',
|
|
731
|
-
enableResourceInlining: false,
|
|
732
|
-
noEmitOnError: false,
|
|
733
|
-
mapRoot: undefined,
|
|
734
|
-
sourceRoot: undefined,
|
|
735
|
-
supportTestBed: false,
|
|
736
|
-
supportJitMode: false,
|
|
737
|
-
});
|
|
738
|
-
cached = { options: read.options, rootNames: read.rootNames };
|
|
739
|
-
tsconfigOptionsCache.set(tsconfigKey, cached);
|
|
740
|
-
}
|
|
741
|
-
// Clone options before mutation (preserve cache purity)
|
|
742
|
-
const tsCompilerOptions = { ...cached.options };
|
|
743
|
-
let rootNames = [...cached.rootNames];
|
|
744
|
-
if (pluginOptions.liveReload && watchMode) {
|
|
745
|
-
tsCompilerOptions['_enableHmr'] = true;
|
|
746
|
-
tsCompilerOptions['externalRuntimeStyles'] = true;
|
|
747
|
-
// Workaround for https://github.com/angular/angular/issues/59310
|
|
748
|
-
// Force extra instructions to be generated for HMR w/defer
|
|
749
|
-
tsCompilerOptions['supportTestBed'] = true;
|
|
750
|
-
}
|
|
751
|
-
if (tsCompilerOptions['compilationMode'] === 'partial') {
|
|
752
|
-
// These options can't be false in partial mode
|
|
753
|
-
tsCompilerOptions['supportTestBed'] = true;
|
|
754
|
-
tsCompilerOptions['supportJitMode'] = true;
|
|
755
|
-
}
|
|
756
|
-
if (!isTest && config.build?.lib) {
|
|
757
|
-
tsCompilerOptions['declaration'] = true;
|
|
758
|
-
tsCompilerOptions['declarationMap'] = watchMode;
|
|
759
|
-
tsCompilerOptions['inlineSources'] = true;
|
|
760
|
-
}
|
|
761
|
-
if (isTest) {
|
|
762
|
-
// Allow `TestBed.overrideXXX()` APIs.
|
|
763
|
-
tsCompilerOptions['supportTestBed'] = true;
|
|
764
|
-
}
|
|
765
|
-
const replacements = pluginOptions.fileReplacements.map((rp) => join(pluginOptions.workspaceRoot, rp.ssr || rp.with));
|
|
766
|
-
// Merge + dedupe root names
|
|
767
|
-
rootNames = [...new Set([...rootNames, ...includeCache, ...replacements])];
|
|
768
|
-
const hostKey = JSON.stringify(tsCompilerOptions);
|
|
769
|
-
let host;
|
|
770
|
-
if (cachedHost && cachedHostKey === hostKey) {
|
|
771
|
-
host = cachedHost;
|
|
772
|
-
}
|
|
773
|
-
else {
|
|
774
|
-
host = ts.createIncrementalCompilerHost(tsCompilerOptions, {
|
|
775
|
-
...ts.sys,
|
|
776
|
-
readFile(path, encoding) {
|
|
777
|
-
if (fileTransformMap.has(path)) {
|
|
778
|
-
return fileTransformMap.get(path);
|
|
779
|
-
}
|
|
780
|
-
const file = ts.sys.readFile.call(null, path, encoding);
|
|
781
|
-
if (file) {
|
|
782
|
-
fileTransformMap.set(path, file);
|
|
783
|
-
}
|
|
784
|
-
return file;
|
|
785
|
-
},
|
|
786
|
-
});
|
|
787
|
-
cachedHost = host;
|
|
788
|
-
cachedHostKey = hostKey;
|
|
789
|
-
// Only store cache if in watch mode
|
|
790
|
-
if (watchMode) {
|
|
791
|
-
augmentHostWithCaching(host, sourceFileCache);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
if (!jit) {
|
|
795
|
-
inlineComponentStyles = tsCompilerOptions['externalRuntimeStyles']
|
|
796
|
-
? new Map()
|
|
797
|
-
: undefined;
|
|
798
|
-
externalComponentStyles = tsCompilerOptions['externalRuntimeStyles']
|
|
799
|
-
? new Map()
|
|
800
|
-
: undefined;
|
|
801
|
-
augmentHostWithResources(host, styleTransform, {
|
|
802
|
-
inlineStylesExtension: pluginOptions.inlineStylesExtension,
|
|
803
|
-
isProd,
|
|
804
|
-
inlineComponentStyles,
|
|
805
|
-
externalComponentStyles,
|
|
806
|
-
sourceFileCache,
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
/**
|
|
810
|
-
* Creates a new NgtscProgram to analyze/re-analyze
|
|
811
|
-
* the source files and create a file emitter.
|
|
812
|
-
* This is shared between an initial build and a hot update.
|
|
813
|
-
*/
|
|
814
|
-
let typeScriptProgram;
|
|
815
|
-
let angularCompiler;
|
|
816
|
-
const oldBuilder = builder ?? ts.readBuilderProgram(tsCompilerOptions, host);
|
|
817
|
-
if (!jit) {
|
|
818
|
-
// Create the Angular specific program that contains the Angular compiler
|
|
819
|
-
const angularProgram = new compilerCli.NgtscProgram(rootNames, tsCompilerOptions, host, nextProgram);
|
|
820
|
-
angularCompiler = angularProgram.compiler;
|
|
821
|
-
typeScriptProgram = angularProgram.compiler.getCurrentProgram();
|
|
822
|
-
augmentProgramWithVersioning(typeScriptProgram);
|
|
823
|
-
builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(typeScriptProgram, host, oldBuilder);
|
|
824
|
-
nextProgram = angularProgram;
|
|
825
|
-
}
|
|
826
|
-
else {
|
|
827
|
-
builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(rootNames, tsCompilerOptions, host, oldBuilder);
|
|
828
|
-
typeScriptProgram = builder.getProgram();
|
|
829
|
-
}
|
|
830
|
-
if (!watchMode) {
|
|
831
|
-
// When not in watch mode, the startup cost of the incremental analysis can be avoided by
|
|
832
|
-
// using an abstract builder that only wraps a TypeScript program.
|
|
833
|
-
builder = ts.createAbstractBuilder(typeScriptProgram, host, oldBuilder);
|
|
834
|
-
}
|
|
835
|
-
if (angularCompiler) {
|
|
836
|
-
await angularCompiler.analyzeAsync();
|
|
837
|
-
}
|
|
838
|
-
const beforeTransformers = jit
|
|
839
|
-
? [
|
|
840
|
-
compilerCli.constructorParametersDownlevelTransform(builder.getProgram()),
|
|
841
|
-
createJitResourceTransformer(() => builder.getProgram().getTypeChecker()),
|
|
842
|
-
]
|
|
843
|
-
: [];
|
|
844
|
-
const transformers = mergeTransformers({ before: beforeTransformers }, jit ? {} : angularCompiler.prepareEmit().transformers);
|
|
845
|
-
const fileMetadata = getFileMetadata(builder, angularCompiler, pluginOptions.liveReload, pluginOptions.disableTypeChecking);
|
|
846
|
-
const writeFileCallback = (_filename, content, _a, _b, sourceFiles) => {
|
|
847
|
-
if (!sourceFiles?.length) {
|
|
848
|
-
return;
|
|
849
|
-
}
|
|
850
|
-
const filename = normalizePath(sourceFiles[0].fileName);
|
|
851
|
-
if (filename.includes('ngtypecheck.ts') || filename.includes('.d.')) {
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
854
|
-
const metadata = watchMode ? fileMetadata(filename) : {};
|
|
855
|
-
outputFiles.set(filename, {
|
|
856
|
-
content,
|
|
857
|
-
dependencies: [],
|
|
858
|
-
errors: metadata.errors,
|
|
859
|
-
warnings: metadata.warnings,
|
|
860
|
-
hmrUpdateCode: metadata.hmrUpdateCode,
|
|
861
|
-
hmrEligible: metadata.hmrEligible,
|
|
862
|
-
});
|
|
863
|
-
};
|
|
864
|
-
const writeOutputFile = (id) => {
|
|
865
|
-
const sourceFile = builder.getSourceFile(id);
|
|
866
|
-
if (!sourceFile) {
|
|
867
|
-
return;
|
|
868
|
-
}
|
|
869
|
-
let content = '';
|
|
870
|
-
builder.emit(sourceFile, (filename, data) => {
|
|
871
|
-
if (/\.[cm]?js$/.test(filename)) {
|
|
872
|
-
content = data;
|
|
873
|
-
}
|
|
874
|
-
if (!watchMode &&
|
|
875
|
-
!isTest &&
|
|
876
|
-
/\.d\.ts/.test(filename) &&
|
|
877
|
-
!filename.includes('.ngtypecheck.')) {
|
|
878
|
-
// output to library root instead /src
|
|
879
|
-
const declarationPath = resolve(config.root, config.build.outDir, relative(config.root, filename)).replace('/src/', '/');
|
|
880
|
-
const declarationFileDir = declarationPath
|
|
881
|
-
.replace(basename(filename), '')
|
|
882
|
-
.replace('/src/', '/');
|
|
883
|
-
declarationFiles.push({
|
|
884
|
-
declarationFileDir,
|
|
885
|
-
declarationPath,
|
|
886
|
-
data,
|
|
887
|
-
});
|
|
888
|
-
}
|
|
889
|
-
}, undefined /* cancellationToken */, undefined /* emitOnlyDtsFiles */, transformers);
|
|
890
|
-
writeFileCallback(id, content, false, undefined, [sourceFile]);
|
|
891
|
-
if (angularCompiler) {
|
|
892
|
-
angularCompiler.incrementalCompilation.recordSuccessfulEmit(sourceFile);
|
|
893
|
-
}
|
|
894
|
-
};
|
|
895
|
-
if (watchMode) {
|
|
896
|
-
if (ids && ids.length > 0) {
|
|
897
|
-
ids.forEach((id) => writeOutputFile(id));
|
|
898
|
-
}
|
|
899
|
-
else {
|
|
900
|
-
/**
|
|
901
|
-
* Only block the server from starting up
|
|
902
|
-
* during testing.
|
|
903
|
-
*/
|
|
904
|
-
if (isTest) {
|
|
905
|
-
// TypeScript will loop until there are no more affected files in the program
|
|
906
|
-
while (builder.emitNextAffectedFile(writeFileCallback, undefined, undefined, transformers)) {
|
|
907
|
-
/* empty */
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
if (!isTest) {
|
|
913
|
-
/**
|
|
914
|
-
* Perf: Output files on demand so the dev server
|
|
915
|
-
* isn't blocked when emitting files.
|
|
916
|
-
*/
|
|
917
|
-
outputFile = writeOutputFile;
|
|
918
|
-
}
|
|
919
|
-
}
|
|
33
|
+
* TypeScript file extension regex
|
|
34
|
+
* Match .(c or m)ts, .ts extensions with an optional ? for query params
|
|
35
|
+
* Ignore .tsx extensions
|
|
36
|
+
*/
|
|
37
|
+
var TS_EXT_REGEX = /\.[cm]?(ts)[^x]?\??/;
|
|
38
|
+
var classNames = /* @__PURE__ */ new Map();
|
|
39
|
+
function angular(options) {
|
|
40
|
+
/**
|
|
41
|
+
* Normalize plugin options so defaults
|
|
42
|
+
* are used for values not provided.
|
|
43
|
+
*/
|
|
44
|
+
const pluginOptions = {
|
|
45
|
+
tsconfigGetter: createTsConfigGetter(options?.tsconfig),
|
|
46
|
+
workspaceRoot: options?.workspaceRoot ?? process.cwd(),
|
|
47
|
+
inlineStylesExtension: options?.inlineStylesExtension ?? "css",
|
|
48
|
+
advanced: { tsTransformers: {
|
|
49
|
+
before: options?.advanced?.tsTransformers?.before ?? [],
|
|
50
|
+
after: options?.advanced?.tsTransformers?.after ?? [],
|
|
51
|
+
afterDeclarations: options?.advanced?.tsTransformers?.afterDeclarations ?? []
|
|
52
|
+
} },
|
|
53
|
+
supportedBrowsers: options?.supportedBrowsers ?? ["safari 15"],
|
|
54
|
+
jit: options?.jit,
|
|
55
|
+
include: options?.include ?? [],
|
|
56
|
+
additionalContentDirs: options?.additionalContentDirs ?? [],
|
|
57
|
+
liveReload: options?.liveReload ?? false,
|
|
58
|
+
disableTypeChecking: options?.disableTypeChecking ?? true,
|
|
59
|
+
fileReplacements: options?.fileReplacements ?? [],
|
|
60
|
+
useAngularCompilationAPI: options?.experimental?.useAngularCompilationAPI ?? false
|
|
61
|
+
};
|
|
62
|
+
let resolvedConfig;
|
|
63
|
+
let tsConfigResolutionContext = null;
|
|
64
|
+
const ts = require("typescript");
|
|
65
|
+
let builder;
|
|
66
|
+
let nextProgram;
|
|
67
|
+
const tsconfigOptionsCache = /* @__PURE__ */ new Map();
|
|
68
|
+
let cachedHost;
|
|
69
|
+
let cachedHostKey;
|
|
70
|
+
let includeCache = [];
|
|
71
|
+
function invalidateFsCaches() {
|
|
72
|
+
includeCache = [];
|
|
73
|
+
}
|
|
74
|
+
function invalidateTsconfigCaches() {
|
|
75
|
+
tsconfigOptionsCache.clear();
|
|
76
|
+
cachedHost = void 0;
|
|
77
|
+
cachedHostKey = void 0;
|
|
78
|
+
}
|
|
79
|
+
let watchMode = false;
|
|
80
|
+
let testWatchMode = isTestWatchMode();
|
|
81
|
+
let inlineComponentStyles;
|
|
82
|
+
let externalComponentStyles;
|
|
83
|
+
const sourceFileCache$1 = new sourceFileCache();
|
|
84
|
+
const isTest = process.env.NODE_ENV === "test" || !!process.env["VITEST"];
|
|
85
|
+
const isVitestVscode = !!process.env["VITEST_VSCODE"];
|
|
86
|
+
const isStackBlitz = !!process.versions["webcontainer"];
|
|
87
|
+
const isAstroIntegration = process.env["ANALOG_ASTRO"] === "true";
|
|
88
|
+
const jit = typeof pluginOptions?.jit !== "undefined" ? pluginOptions.jit : isTest;
|
|
89
|
+
let viteServer;
|
|
90
|
+
const styleUrlsResolver = new StyleUrlsResolver();
|
|
91
|
+
const templateUrlsResolver = new TemplateUrlsResolver();
|
|
92
|
+
let outputFile;
|
|
93
|
+
const outputFiles = /* @__PURE__ */ new Map();
|
|
94
|
+
const fileEmitter = (file) => {
|
|
95
|
+
outputFile?.(file);
|
|
96
|
+
return outputFiles.get(normalizePath(file));
|
|
97
|
+
};
|
|
98
|
+
let initialCompilation = false;
|
|
99
|
+
const declarationFiles = [];
|
|
100
|
+
const fileTransformMap = /* @__PURE__ */ new Map();
|
|
101
|
+
let styleTransform;
|
|
102
|
+
let pendingCompilation;
|
|
103
|
+
let compilationLock = Promise.resolve();
|
|
104
|
+
let angularCompilation;
|
|
105
|
+
function angularPlugin() {
|
|
106
|
+
let isProd = false;
|
|
107
|
+
if (angularFullVersion < 19e4 || isTest) pluginOptions.liveReload = false;
|
|
108
|
+
if (pluginOptions.useAngularCompilationAPI) {
|
|
109
|
+
if (angularFullVersion < 200100) {
|
|
110
|
+
pluginOptions.useAngularCompilationAPI = false;
|
|
111
|
+
console.warn("[@analogjs/vite-plugin-angular]: The Angular Compilation API is only available with Angular v20.1 and later");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
name: "@analogjs/vite-plugin-angular",
|
|
116
|
+
async config(config, { command }) {
|
|
117
|
+
watchMode = command === "serve";
|
|
118
|
+
isProd = config.mode === "production" || process.env.NODE_ENV === "production";
|
|
119
|
+
tsConfigResolutionContext = {
|
|
120
|
+
root: config.root || ".",
|
|
121
|
+
isProd,
|
|
122
|
+
isLib: !!config?.build?.lib
|
|
123
|
+
};
|
|
124
|
+
const preliminaryTsConfigPath = resolveTsConfigPath();
|
|
125
|
+
const esbuild = pluginOptions.useAngularCompilationAPI ? void 0 : config.esbuild ?? false;
|
|
126
|
+
const oxc = pluginOptions.useAngularCompilationAPI ? void 0 : config.oxc ?? false;
|
|
127
|
+
const defineOptions = {
|
|
128
|
+
ngJitMode: "false",
|
|
129
|
+
ngI18nClosureMode: "false",
|
|
130
|
+
...watchMode ? {} : { ngDevMode: "false" }
|
|
131
|
+
};
|
|
132
|
+
const useRolldown = isRolldown();
|
|
133
|
+
const jsTransformConfigKey = getJsTransformConfigKey();
|
|
134
|
+
const jsTransformConfigValue = jsTransformConfigKey === "oxc" ? oxc : esbuild;
|
|
135
|
+
const rolldownOptions = { plugins: [createRolldownCompilerPlugin({
|
|
136
|
+
tsconfig: preliminaryTsConfigPath,
|
|
137
|
+
sourcemap: !isProd,
|
|
138
|
+
advancedOptimizations: isProd,
|
|
139
|
+
jit,
|
|
140
|
+
incremental: watchMode
|
|
141
|
+
})] };
|
|
142
|
+
const esbuildOptions = {
|
|
143
|
+
plugins: [createCompilerPlugin({
|
|
144
|
+
tsconfig: preliminaryTsConfigPath,
|
|
145
|
+
sourcemap: !isProd,
|
|
146
|
+
advancedOptimizations: isProd,
|
|
147
|
+
jit,
|
|
148
|
+
incremental: watchMode
|
|
149
|
+
}, isTest, !isAstroIntegration)],
|
|
150
|
+
define: defineOptions
|
|
151
|
+
};
|
|
152
|
+
return {
|
|
153
|
+
[jsTransformConfigKey]: jsTransformConfigValue,
|
|
154
|
+
optimizeDeps: {
|
|
155
|
+
include: ["rxjs/operators", "rxjs"],
|
|
156
|
+
exclude: ["@angular/platform-server"],
|
|
157
|
+
...useRolldown ? { rolldownOptions } : { esbuildOptions }
|
|
158
|
+
},
|
|
159
|
+
resolve: { conditions: ["style", ...config.resolve?.conditions || defaultClientConditions] }
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
configResolved(config) {
|
|
163
|
+
resolvedConfig = config;
|
|
164
|
+
if (pluginOptions.useAngularCompilationAPI) {
|
|
165
|
+
externalComponentStyles = /* @__PURE__ */ new Map();
|
|
166
|
+
inlineComponentStyles = /* @__PURE__ */ new Map();
|
|
167
|
+
}
|
|
168
|
+
if (!jit) styleTransform = (code, filename) => preprocessCSS(code, filename, config);
|
|
169
|
+
if (isTest) testWatchMode = !(config.server.watch === null) || config.test?.watch === true || testWatchMode;
|
|
170
|
+
},
|
|
171
|
+
configureServer(server) {
|
|
172
|
+
viteServer = server;
|
|
173
|
+
const invalidateCompilationOnFsChange = createFsWatcherCacheInvalidator(invalidateFsCaches, invalidateTsconfigCaches, () => performCompilation(resolvedConfig));
|
|
174
|
+
server.watcher.on("add", invalidateCompilationOnFsChange);
|
|
175
|
+
server.watcher.on("unlink", invalidateCompilationOnFsChange);
|
|
176
|
+
server.watcher.on("change", (file) => {
|
|
177
|
+
if (file.includes("tsconfig")) invalidateTsconfigCaches();
|
|
178
|
+
});
|
|
179
|
+
},
|
|
180
|
+
async buildStart() {
|
|
181
|
+
if (!isVitestVscode) {
|
|
182
|
+
await performCompilation(resolvedConfig);
|
|
183
|
+
pendingCompilation = null;
|
|
184
|
+
initialCompilation = true;
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
async handleHotUpdate(ctx) {
|
|
188
|
+
if (TS_EXT_REGEX.test(ctx.file)) {
|
|
189
|
+
const [fileId] = ctx.file.split("?");
|
|
190
|
+
pendingCompilation = performCompilation(resolvedConfig, [fileId]);
|
|
191
|
+
let result;
|
|
192
|
+
if (pluginOptions.liveReload) {
|
|
193
|
+
await pendingCompilation;
|
|
194
|
+
pendingCompilation = null;
|
|
195
|
+
result = fileEmitter(fileId);
|
|
196
|
+
}
|
|
197
|
+
if (pluginOptions.liveReload && result?.hmrEligible && classNames.get(fileId)) {
|
|
198
|
+
const relativeFileId = `${normalizePath(relative(process.cwd(), fileId))}@${classNames.get(fileId)}`;
|
|
199
|
+
sendHMRComponentUpdate(ctx.server, relativeFileId);
|
|
200
|
+
return ctx.modules.map((mod) => {
|
|
201
|
+
if (mod.id === ctx.file) return markModuleSelfAccepting(mod);
|
|
202
|
+
return mod;
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (/\.(html|htm|css|less|sass|scss)$/.test(ctx.file)) {
|
|
207
|
+
fileTransformMap.delete(ctx.file.split("?")[0]);
|
|
208
|
+
/**
|
|
209
|
+
* Check to see if this was a direct request
|
|
210
|
+
* for an external resource (styles, html).
|
|
211
|
+
*/
|
|
212
|
+
const isDirect = ctx.modules.find((mod) => ctx.file === mod.file && mod.id?.includes("?direct"));
|
|
213
|
+
const isInline = ctx.modules.find((mod) => ctx.file === mod.file && mod.id?.includes("?inline"));
|
|
214
|
+
if (isDirect || isInline) {
|
|
215
|
+
if (pluginOptions.liveReload && isDirect?.id && isDirect.file) {
|
|
216
|
+
if (isDirect.type === "css" && isComponentStyleSheet(isDirect.id)) {
|
|
217
|
+
const { encapsulation } = getComponentStyleSheetMeta(isDirect.id);
|
|
218
|
+
if (encapsulation !== "shadow") {
|
|
219
|
+
ctx.server.ws.send({
|
|
220
|
+
type: "update",
|
|
221
|
+
updates: [{
|
|
222
|
+
type: "css-update",
|
|
223
|
+
timestamp: Date.now(),
|
|
224
|
+
path: isDirect.url,
|
|
225
|
+
acceptedPath: isDirect.file
|
|
226
|
+
}]
|
|
227
|
+
});
|
|
228
|
+
return ctx.modules.filter((mod) => {
|
|
229
|
+
return mod.file !== ctx.file || mod.id !== isDirect.id;
|
|
230
|
+
}).map((mod) => {
|
|
231
|
+
if (mod.file === ctx.file) return markModuleSelfAccepting(mod);
|
|
232
|
+
return mod;
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return ctx.modules;
|
|
238
|
+
}
|
|
239
|
+
const mods = [];
|
|
240
|
+
const updates = [];
|
|
241
|
+
ctx.modules.forEach((mod) => {
|
|
242
|
+
mod.importers.forEach((imp) => {
|
|
243
|
+
ctx.server.moduleGraph.invalidateModule(imp);
|
|
244
|
+
if (pluginOptions.liveReload && classNames.get(imp.id)) updates.push(imp.id);
|
|
245
|
+
else mods.push(imp);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
pendingCompilation = performCompilation(resolvedConfig, [...mods.map((mod) => mod.id), ...updates]);
|
|
249
|
+
if (updates.length > 0) {
|
|
250
|
+
await pendingCompilation;
|
|
251
|
+
pendingCompilation = null;
|
|
252
|
+
updates.forEach((updateId) => {
|
|
253
|
+
const impRelativeFileId = `${normalizePath(relative(process.cwd(), updateId))}@${classNames.get(updateId)}`;
|
|
254
|
+
sendHMRComponentUpdate(ctx.server, impRelativeFileId);
|
|
255
|
+
});
|
|
256
|
+
return ctx.modules.map((mod) => {
|
|
257
|
+
if (mod.id === ctx.file) return markModuleSelfAccepting(mod);
|
|
258
|
+
return mod;
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
return mods;
|
|
262
|
+
}
|
|
263
|
+
classNames.clear();
|
|
264
|
+
return ctx.modules;
|
|
265
|
+
},
|
|
266
|
+
resolveId(id, importer) {
|
|
267
|
+
if (jit && id.startsWith("angular:jit:")) {
|
|
268
|
+
const path = id.split(";")[1];
|
|
269
|
+
return `${normalizePath(resolve(dirname(importer), path))}?${id.includes(":style") ? "inline" : "raw"}`;
|
|
270
|
+
}
|
|
271
|
+
if (isComponentStyleSheet(id)) {
|
|
272
|
+
const componentStyles = externalComponentStyles?.get(getFilenameFromPath(id));
|
|
273
|
+
if (componentStyles) return componentStyles + new URL(id, "http://localhost").search;
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
async load(id) {
|
|
277
|
+
if (isComponentStyleSheet(id)) {
|
|
278
|
+
const componentStyles = inlineComponentStyles?.get(getFilenameFromPath(id));
|
|
279
|
+
if (componentStyles) return componentStyles;
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
transform: {
|
|
283
|
+
filter: { id: {
|
|
284
|
+
include: [TS_EXT_REGEX],
|
|
285
|
+
exclude: [
|
|
286
|
+
/node_modules/,
|
|
287
|
+
"type=script",
|
|
288
|
+
"@ng/component"
|
|
289
|
+
]
|
|
290
|
+
} },
|
|
291
|
+
async handler(code, id) {
|
|
292
|
+
/**
|
|
293
|
+
* Check for options.transformFilter
|
|
294
|
+
*/
|
|
295
|
+
if (options?.transformFilter && !(options?.transformFilter(code, id) ?? true)) return;
|
|
296
|
+
if (pluginOptions.useAngularCompilationAPI) {
|
|
297
|
+
if (!/(Component|Directive|Pipe|Injectable|NgModule)\(/.test(code)) return;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Skip transforming content files
|
|
301
|
+
*/
|
|
302
|
+
if (id.includes("?") && id.includes("analog-content-")) return;
|
|
303
|
+
/**
|
|
304
|
+
* Encapsulate component stylesheets that use emulated encapsulation
|
|
305
|
+
*/
|
|
306
|
+
if (pluginOptions.liveReload && isComponentStyleSheet(id)) {
|
|
307
|
+
const { encapsulation, componentId } = getComponentStyleSheetMeta(id);
|
|
308
|
+
if (encapsulation === "emulated" && componentId) return {
|
|
309
|
+
code: ngCompiler.encapsulateStyle(code, componentId),
|
|
310
|
+
map: null
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
if (id.includes(".ts?")) id = id.replace(/\?(.*)/, "");
|
|
314
|
+
fileTransformMap.set(id, code);
|
|
315
|
+
/**
|
|
316
|
+
* Re-analyze on each transform
|
|
317
|
+
* for test(Vitest)
|
|
318
|
+
*/
|
|
319
|
+
if (isTest) {
|
|
320
|
+
if (isVitestVscode && !initialCompilation) {
|
|
321
|
+
pendingCompilation = performCompilation(resolvedConfig);
|
|
322
|
+
initialCompilation = true;
|
|
323
|
+
}
|
|
324
|
+
const tsMod = viteServer?.moduleGraph.getModuleById(id);
|
|
325
|
+
if (tsMod) {
|
|
326
|
+
const invalidated = tsMod.lastInvalidationTimestamp;
|
|
327
|
+
if (testWatchMode && invalidated) pendingCompilation = performCompilation(resolvedConfig, [id]);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
const hasComponent = code.includes("@Component");
|
|
331
|
+
const templateUrls = hasComponent ? templateUrlsResolver.resolve(code, id) : [];
|
|
332
|
+
const styleUrls = hasComponent ? styleUrlsResolver.resolve(code, id) : [];
|
|
333
|
+
if (hasComponent && watchMode) for (const urlSet of [...templateUrls, ...styleUrls]) {
|
|
334
|
+
const [, absoluteFileUrl] = urlSet.split("|");
|
|
335
|
+
this.addWatchFile(absoluteFileUrl);
|
|
336
|
+
}
|
|
337
|
+
if (pendingCompilation) {
|
|
338
|
+
await pendingCompilation;
|
|
339
|
+
pendingCompilation = null;
|
|
340
|
+
}
|
|
341
|
+
const typescriptResult = fileEmitter(id);
|
|
342
|
+
if (typescriptResult?.warnings && typescriptResult?.warnings.length > 0) this.warn(`${typescriptResult.warnings.join("\n")}`);
|
|
343
|
+
if (typescriptResult?.errors && typescriptResult?.errors.length > 0) this.error(`${typescriptResult.errors.join("\n")}`);
|
|
344
|
+
let data = typescriptResult?.content ?? "";
|
|
345
|
+
if (jit && data.includes("angular:jit:")) {
|
|
346
|
+
data = data.replace(/angular:jit:style:inline;/g, "virtual:angular:jit:style:inline;");
|
|
347
|
+
templateUrls.forEach((templateUrlSet) => {
|
|
348
|
+
const [templateFile, resolvedTemplateUrl] = templateUrlSet.split("|");
|
|
349
|
+
data = data.replace(`angular:jit:template:file;${templateFile}`, `${resolvedTemplateUrl}?raw`);
|
|
350
|
+
});
|
|
351
|
+
styleUrls.forEach((styleUrlSet) => {
|
|
352
|
+
const [styleFile, resolvedStyleUrl] = styleUrlSet.split("|");
|
|
353
|
+
data = data.replace(`angular:jit:style:file;${styleFile}`, `${resolvedStyleUrl}?inline`);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
code: data,
|
|
358
|
+
map: null
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
closeBundle() {
|
|
363
|
+
declarationFiles.forEach(({ declarationFileDir, declarationPath, data }) => {
|
|
364
|
+
mkdirSync(declarationFileDir, { recursive: true });
|
|
365
|
+
writeFileSync(declarationPath, data, "utf-8");
|
|
366
|
+
});
|
|
367
|
+
angularCompilation?.close?.();
|
|
368
|
+
angularCompilation = void 0;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
return [
|
|
373
|
+
replaceFiles(pluginOptions.fileReplacements, pluginOptions.workspaceRoot),
|
|
374
|
+
angularPlugin(),
|
|
375
|
+
pluginOptions.liveReload && liveReloadPlugin({
|
|
376
|
+
classNames,
|
|
377
|
+
fileEmitter
|
|
378
|
+
}),
|
|
379
|
+
...isTest && !isStackBlitz ? angularVitestPlugins() : [],
|
|
380
|
+
jit && jitPlugin({ inlineStylesExtension: pluginOptions.inlineStylesExtension }),
|
|
381
|
+
buildOptimizerPlugin({
|
|
382
|
+
supportedBrowsers: pluginOptions.supportedBrowsers,
|
|
383
|
+
jit
|
|
384
|
+
}),
|
|
385
|
+
routerPlugin(),
|
|
386
|
+
angularFullVersion < 190004 && pendingTasksPlugin(),
|
|
387
|
+
nxFolderPlugin()
|
|
388
|
+
].filter(Boolean);
|
|
389
|
+
function findIncludes() {
|
|
390
|
+
const workspaceRoot = normalizePath(resolve(pluginOptions.workspaceRoot));
|
|
391
|
+
return globSync([...pluginOptions.include.map((glob) => `${workspaceRoot}${glob}`)], {
|
|
392
|
+
dot: true,
|
|
393
|
+
absolute: true
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
function createTsConfigGetter(tsconfigOrGetter) {
|
|
397
|
+
if (typeof tsconfigOrGetter === "function") return tsconfigOrGetter;
|
|
398
|
+
return () => tsconfigOrGetter || "";
|
|
399
|
+
}
|
|
400
|
+
function getTsConfigPath(root, tsconfig, isProd, isTest, isLib) {
|
|
401
|
+
if (tsconfig && isAbsolute(tsconfig)) {
|
|
402
|
+
if (!existsSync(tsconfig)) console.error(`[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${tsconfig}. This causes compilation issues. Check the path or set the "tsconfig" property with an absolute path.`);
|
|
403
|
+
return tsconfig;
|
|
404
|
+
}
|
|
405
|
+
let tsconfigFilePath = "./tsconfig.app.json";
|
|
406
|
+
if (isLib) tsconfigFilePath = isProd ? "./tsconfig.lib.prod.json" : "./tsconfig.lib.json";
|
|
407
|
+
if (isTest) tsconfigFilePath = "./tsconfig.spec.json";
|
|
408
|
+
if (tsconfig) tsconfigFilePath = tsconfig;
|
|
409
|
+
const resolvedPath = resolve(root, tsconfigFilePath);
|
|
410
|
+
if (!existsSync(resolvedPath)) console.error(`[@analogjs/vite-plugin-angular]: Unable to resolve tsconfig at ${resolvedPath}. This causes compilation issues. Check the path or set the "tsconfig" property with an absolute path.`);
|
|
411
|
+
return resolvedPath;
|
|
412
|
+
}
|
|
413
|
+
function resolveTsConfigPath() {
|
|
414
|
+
const tsconfigValue = pluginOptions.tsconfigGetter();
|
|
415
|
+
return getTsConfigPath(tsConfigResolutionContext.root, tsconfigValue, tsConfigResolutionContext.isProd, isTest, tsConfigResolutionContext.isLib);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Perform compilation using Angular's private Compilation API.
|
|
419
|
+
*
|
|
420
|
+
* Key differences from the standard `performCompilation` path:
|
|
421
|
+
* 1. The compilation instance is reused across rebuilds (nullish-coalescing
|
|
422
|
+
* assignment below) so Angular retains prior state and can diff it to
|
|
423
|
+
* produce `templateUpdates` for HMR.
|
|
424
|
+
* 2. `ids` (modified files) are forwarded to both the source-file cache and
|
|
425
|
+
* `angularCompilation.update()` so that incremental re-analysis is
|
|
426
|
+
* scoped to what actually changed.
|
|
427
|
+
* 3. `fileReplacements` are converted and passed into Angular's host via
|
|
428
|
+
* `toAngularCompilationFileReplacements`.
|
|
429
|
+
* 4. `templateUpdates` from the compilation result are mapped back to
|
|
430
|
+
* file-level HMR metadata (`hmrUpdateCode`, `hmrEligible`, `classNames`).
|
|
431
|
+
*/
|
|
432
|
+
async function performAngularCompilation(config, ids) {
|
|
433
|
+
angularCompilation ??= await createAngularCompilation(!!pluginOptions.jit, false);
|
|
434
|
+
const modifiedFiles = ids?.length ? new Set(ids.map((file) => normalizePath(file))) : void 0;
|
|
435
|
+
if (modifiedFiles?.size) sourceFileCache$1.invalidate(modifiedFiles);
|
|
436
|
+
if (modifiedFiles?.size && angularCompilation.update) await angularCompilation.update(modifiedFiles);
|
|
437
|
+
const resolvedTsConfigPath = resolveTsConfigPath();
|
|
438
|
+
const compilationResult = await angularCompilation.initialize(resolvedTsConfigPath, {
|
|
439
|
+
fileReplacements: toAngularCompilationFileReplacements(pluginOptions.fileReplacements, pluginOptions.workspaceRoot),
|
|
440
|
+
modifiedFiles,
|
|
441
|
+
async transformStylesheet(data, containingFile, resourceFile, order, className) {
|
|
442
|
+
if (pluginOptions.liveReload) {
|
|
443
|
+
const filename = createHash("sha256").update(containingFile).update(className).update(String(order)).update(data).digest("hex") + "." + pluginOptions.inlineStylesExtension;
|
|
444
|
+
inlineComponentStyles.set(filename, data);
|
|
445
|
+
return filename;
|
|
446
|
+
}
|
|
447
|
+
const filename = resourceFile ?? containingFile.replace(".ts", `.${options?.inlineStylesExtension}`);
|
|
448
|
+
let stylesheetResult;
|
|
449
|
+
try {
|
|
450
|
+
stylesheetResult = await preprocessCSS(data, `${filename}?direct`, resolvedConfig);
|
|
451
|
+
} catch (e) {
|
|
452
|
+
console.error(`${e}`);
|
|
453
|
+
}
|
|
454
|
+
return stylesheetResult?.code || "";
|
|
455
|
+
},
|
|
456
|
+
processWebWorker(workerFile, containingFile) {
|
|
457
|
+
return "";
|
|
458
|
+
}
|
|
459
|
+
}, (tsCompilerOptions) => {
|
|
460
|
+
if (pluginOptions.liveReload && watchMode) {
|
|
461
|
+
tsCompilerOptions["_enableHmr"] = true;
|
|
462
|
+
tsCompilerOptions["externalRuntimeStyles"] = true;
|
|
463
|
+
tsCompilerOptions["supportTestBed"] = true;
|
|
464
|
+
}
|
|
465
|
+
if (tsCompilerOptions.compilationMode === "partial") {
|
|
466
|
+
tsCompilerOptions["supportTestBed"] = true;
|
|
467
|
+
tsCompilerOptions["supportJitMode"] = true;
|
|
468
|
+
}
|
|
469
|
+
if (!isTest && config.build?.lib) {
|
|
470
|
+
tsCompilerOptions["declaration"] = true;
|
|
471
|
+
tsCompilerOptions["declarationMap"] = watchMode;
|
|
472
|
+
tsCompilerOptions["inlineSources"] = true;
|
|
473
|
+
}
|
|
474
|
+
if (isTest) tsCompilerOptions["supportTestBed"] = true;
|
|
475
|
+
return tsCompilerOptions;
|
|
476
|
+
});
|
|
477
|
+
compilationResult.externalStylesheets?.forEach((value, key) => {
|
|
478
|
+
externalComponentStyles?.set(`${value}.css`, key);
|
|
479
|
+
});
|
|
480
|
+
const diagnostics = await angularCompilation.diagnoseFiles(pluginOptions.disableTypeChecking ? DiagnosticModes.All & ~DiagnosticModes.Semantic : DiagnosticModes.All);
|
|
481
|
+
const errors = diagnostics.errors?.length ? diagnostics.errors : [];
|
|
482
|
+
const warnings = diagnostics.warnings?.length ? diagnostics.warnings : [];
|
|
483
|
+
const templateUpdates = mapTemplateUpdatesToFiles(compilationResult.templateUpdates);
|
|
484
|
+
for (const file of await angularCompilation.emitAffectedFiles()) {
|
|
485
|
+
const normalizedFilename = normalizePath(file.filename);
|
|
486
|
+
const templateUpdate = templateUpdates.get(normalizedFilename);
|
|
487
|
+
if (templateUpdate) classNames.set(normalizedFilename, templateUpdate.className);
|
|
488
|
+
outputFiles.set(normalizedFilename, {
|
|
489
|
+
content: file.contents,
|
|
490
|
+
dependencies: [],
|
|
491
|
+
errors: errors.map((error) => error.text || ""),
|
|
492
|
+
warnings: warnings.map((warning) => warning.text || ""),
|
|
493
|
+
hmrUpdateCode: templateUpdate?.code,
|
|
494
|
+
hmrEligible: !!templateUpdate?.code
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
async function performCompilation(config, ids) {
|
|
499
|
+
let resolve;
|
|
500
|
+
const previousLock = compilationLock;
|
|
501
|
+
compilationLock = new Promise((r) => {
|
|
502
|
+
resolve = r;
|
|
503
|
+
});
|
|
504
|
+
try {
|
|
505
|
+
await previousLock;
|
|
506
|
+
await _doPerformCompilation(config, ids);
|
|
507
|
+
} finally {
|
|
508
|
+
resolve();
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* This method share mutable state and performs the actual compilation work.
|
|
513
|
+
* It should not be called concurrently. Use `performCompilation` which wraps this method in a lock to ensure only one compilation runs at a time.
|
|
514
|
+
*/
|
|
515
|
+
async function _doPerformCompilation(config, ids) {
|
|
516
|
+
if (pluginOptions.useAngularCompilationAPI) {
|
|
517
|
+
await performAngularCompilation(config, ids);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
const isProd = config.mode === "production";
|
|
521
|
+
const modifiedFiles = new Set(ids ?? []);
|
|
522
|
+
sourceFileCache$1.invalidate(modifiedFiles);
|
|
523
|
+
if (ids?.length) for (const id of ids || []) fileTransformMap.delete(id);
|
|
524
|
+
if (pluginOptions.include.length > 0 && includeCache.length === 0) includeCache = findIncludes();
|
|
525
|
+
const resolvedTsConfigPath = resolveTsConfigPath();
|
|
526
|
+
const tsconfigKey = [
|
|
527
|
+
resolvedTsConfigPath,
|
|
528
|
+
isProd ? "prod" : "dev",
|
|
529
|
+
isTest ? "test" : "app",
|
|
530
|
+
config.build?.lib ? "lib" : "nolib"
|
|
531
|
+
].join("|");
|
|
532
|
+
let cached = tsconfigOptionsCache.get(tsconfigKey);
|
|
533
|
+
if (!cached) {
|
|
534
|
+
const read = compilerCli.readConfiguration(resolvedTsConfigPath, {
|
|
535
|
+
suppressOutputPathCheck: true,
|
|
536
|
+
outDir: void 0,
|
|
537
|
+
sourceMap: false,
|
|
538
|
+
inlineSourceMap: !isProd,
|
|
539
|
+
inlineSources: !isProd,
|
|
540
|
+
declaration: false,
|
|
541
|
+
declarationMap: false,
|
|
542
|
+
allowEmptyCodegenFiles: false,
|
|
543
|
+
annotationsAs: "decorators",
|
|
544
|
+
enableResourceInlining: false,
|
|
545
|
+
noEmitOnError: false,
|
|
546
|
+
mapRoot: void 0,
|
|
547
|
+
sourceRoot: void 0,
|
|
548
|
+
supportTestBed: false,
|
|
549
|
+
supportJitMode: false
|
|
550
|
+
});
|
|
551
|
+
cached = {
|
|
552
|
+
options: read.options,
|
|
553
|
+
rootNames: read.rootNames
|
|
554
|
+
};
|
|
555
|
+
tsconfigOptionsCache.set(tsconfigKey, cached);
|
|
556
|
+
}
|
|
557
|
+
const tsCompilerOptions = { ...cached.options };
|
|
558
|
+
let rootNames = [...cached.rootNames];
|
|
559
|
+
if (pluginOptions.liveReload && watchMode) {
|
|
560
|
+
tsCompilerOptions["_enableHmr"] = true;
|
|
561
|
+
tsCompilerOptions["externalRuntimeStyles"] = true;
|
|
562
|
+
tsCompilerOptions["supportTestBed"] = true;
|
|
563
|
+
}
|
|
564
|
+
if (tsCompilerOptions["compilationMode"] === "partial") {
|
|
565
|
+
tsCompilerOptions["supportTestBed"] = true;
|
|
566
|
+
tsCompilerOptions["supportJitMode"] = true;
|
|
567
|
+
}
|
|
568
|
+
if (!isTest && config.build?.lib) {
|
|
569
|
+
tsCompilerOptions["declaration"] = true;
|
|
570
|
+
tsCompilerOptions["declarationMap"] = watchMode;
|
|
571
|
+
tsCompilerOptions["inlineSources"] = true;
|
|
572
|
+
}
|
|
573
|
+
if (isTest) tsCompilerOptions["supportTestBed"] = true;
|
|
574
|
+
const replacements = pluginOptions.fileReplacements.map((rp) => join(pluginOptions.workspaceRoot, rp.ssr || rp.with));
|
|
575
|
+
rootNames = [...new Set([
|
|
576
|
+
...rootNames,
|
|
577
|
+
...includeCache,
|
|
578
|
+
...replacements
|
|
579
|
+
])];
|
|
580
|
+
const hostKey = JSON.stringify(tsCompilerOptions);
|
|
581
|
+
let host;
|
|
582
|
+
if (cachedHost && cachedHostKey === hostKey) host = cachedHost;
|
|
583
|
+
else {
|
|
584
|
+
host = ts.createIncrementalCompilerHost(tsCompilerOptions, {
|
|
585
|
+
...ts.sys,
|
|
586
|
+
readFile(path, encoding) {
|
|
587
|
+
if (fileTransformMap.has(path)) return fileTransformMap.get(path);
|
|
588
|
+
const file = ts.sys.readFile.call(null, path, encoding);
|
|
589
|
+
if (file) fileTransformMap.set(path, file);
|
|
590
|
+
return file;
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
cachedHost = host;
|
|
594
|
+
cachedHostKey = hostKey;
|
|
595
|
+
if (watchMode) augmentHostWithCaching(host, sourceFileCache$1);
|
|
596
|
+
}
|
|
597
|
+
if (!jit) {
|
|
598
|
+
inlineComponentStyles = tsCompilerOptions["externalRuntimeStyles"] ? /* @__PURE__ */ new Map() : void 0;
|
|
599
|
+
externalComponentStyles = tsCompilerOptions["externalRuntimeStyles"] ? /* @__PURE__ */ new Map() : void 0;
|
|
600
|
+
augmentHostWithResources(host, styleTransform, {
|
|
601
|
+
inlineStylesExtension: pluginOptions.inlineStylesExtension,
|
|
602
|
+
isProd,
|
|
603
|
+
inlineComponentStyles,
|
|
604
|
+
externalComponentStyles,
|
|
605
|
+
sourceFileCache: sourceFileCache$1
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Creates a new NgtscProgram to analyze/re-analyze
|
|
610
|
+
* the source files and create a file emitter.
|
|
611
|
+
* This is shared between an initial build and a hot update.
|
|
612
|
+
*/
|
|
613
|
+
let typeScriptProgram;
|
|
614
|
+
let angularCompiler;
|
|
615
|
+
const oldBuilder = builder ?? ts.readBuilderProgram(tsCompilerOptions, host);
|
|
616
|
+
if (!jit) {
|
|
617
|
+
const angularProgram = new compilerCli.NgtscProgram(rootNames, tsCompilerOptions, host, nextProgram);
|
|
618
|
+
angularCompiler = angularProgram.compiler;
|
|
619
|
+
typeScriptProgram = angularProgram.compiler.getCurrentProgram();
|
|
620
|
+
augmentProgramWithVersioning(typeScriptProgram);
|
|
621
|
+
builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(typeScriptProgram, host, oldBuilder);
|
|
622
|
+
nextProgram = angularProgram;
|
|
623
|
+
} else {
|
|
624
|
+
builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(rootNames, tsCompilerOptions, host, oldBuilder);
|
|
625
|
+
typeScriptProgram = builder.getProgram();
|
|
626
|
+
}
|
|
627
|
+
if (!watchMode) builder = ts.createAbstractBuilder(typeScriptProgram, host, oldBuilder);
|
|
628
|
+
if (angularCompiler) await angularCompiler.analyzeAsync();
|
|
629
|
+
const transformers = mergeTransformers({ before: jit ? [compilerCli.constructorParametersDownlevelTransform(builder.getProgram()), cjt(() => builder.getProgram().getTypeChecker())] : [] }, jit ? {} : angularCompiler.prepareEmit().transformers);
|
|
630
|
+
const fileMetadata = getFileMetadata(builder, angularCompiler, pluginOptions.liveReload, pluginOptions.disableTypeChecking);
|
|
631
|
+
const writeFileCallback = (_filename, content, _a, _b, sourceFiles) => {
|
|
632
|
+
if (!sourceFiles?.length) return;
|
|
633
|
+
const filename = normalizePath(sourceFiles[0].fileName);
|
|
634
|
+
if (filename.includes("ngtypecheck.ts") || filename.includes(".d.")) return;
|
|
635
|
+
const metadata = watchMode ? fileMetadata(filename) : {};
|
|
636
|
+
outputFiles.set(filename, {
|
|
637
|
+
content,
|
|
638
|
+
dependencies: [],
|
|
639
|
+
errors: metadata.errors,
|
|
640
|
+
warnings: metadata.warnings,
|
|
641
|
+
hmrUpdateCode: metadata.hmrUpdateCode,
|
|
642
|
+
hmrEligible: metadata.hmrEligible
|
|
643
|
+
});
|
|
644
|
+
};
|
|
645
|
+
const writeOutputFile = (id) => {
|
|
646
|
+
const sourceFile = builder.getSourceFile(id);
|
|
647
|
+
if (!sourceFile) return;
|
|
648
|
+
let content = "";
|
|
649
|
+
builder.emit(sourceFile, (filename, data) => {
|
|
650
|
+
if (/\.[cm]?js$/.test(filename)) content = data;
|
|
651
|
+
if (!watchMode && !isTest && /\.d\.ts/.test(filename) && !filename.includes(".ngtypecheck.")) {
|
|
652
|
+
const declarationPath = resolve(config.root, config.build.outDir, relative(config.root, filename)).replace("/src/", "/");
|
|
653
|
+
const declarationFileDir = declarationPath.replace(basename(filename), "").replace("/src/", "/");
|
|
654
|
+
declarationFiles.push({
|
|
655
|
+
declarationFileDir,
|
|
656
|
+
declarationPath,
|
|
657
|
+
data
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
}, void 0, void 0, transformers);
|
|
661
|
+
writeFileCallback(id, content, false, void 0, [sourceFile]);
|
|
662
|
+
if (angularCompiler) angularCompiler.incrementalCompilation.recordSuccessfulEmit(sourceFile);
|
|
663
|
+
};
|
|
664
|
+
if (watchMode) {
|
|
665
|
+
if (ids && ids.length > 0) ids.forEach((id) => writeOutputFile(id));
|
|
666
|
+
else if (isTest) while (builder.emitNextAffectedFile(writeFileCallback, void 0, void 0, transformers));
|
|
667
|
+
}
|
|
668
|
+
if (!isTest)
|
|
669
|
+
/**
|
|
670
|
+
* Perf: Output files on demand so the dev server
|
|
671
|
+
* isn't blocked when emitting files.
|
|
672
|
+
*/
|
|
673
|
+
outputFile = writeOutputFile;
|
|
674
|
+
}
|
|
920
675
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
676
|
+
function createFsWatcherCacheInvalidator(invalidateFsCaches, invalidateTsconfigCaches, performCompilation) {
|
|
677
|
+
return async () => {
|
|
678
|
+
invalidateFsCaches();
|
|
679
|
+
invalidateTsconfigCaches();
|
|
680
|
+
await performCompilation();
|
|
681
|
+
};
|
|
927
682
|
}
|
|
928
683
|
/**
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
return [
|
|
947
|
-
[
|
|
948
|
-
isAbsolute(replacement.replace)
|
|
949
|
-
? replacement.replace
|
|
950
|
-
: resolve(workspaceRoot, replacement.replace),
|
|
951
|
-
isAbsolute(replacement.with)
|
|
952
|
-
? replacement.with
|
|
953
|
-
: resolve(workspaceRoot, replacement.with),
|
|
954
|
-
],
|
|
955
|
-
];
|
|
956
|
-
});
|
|
957
|
-
return mappedReplacements.length
|
|
958
|
-
? Object.fromEntries(mappedReplacements)
|
|
959
|
-
: undefined;
|
|
684
|
+
* Convert Analog/Angular CLI-style file replacements into the flat record
|
|
685
|
+
* expected by `AngularHostOptions.fileReplacements`.
|
|
686
|
+
*
|
|
687
|
+
* Only browser replacements (`{ replace, with }`) are converted. SSR-only
|
|
688
|
+
* replacements (`{ replace, ssr }`) are left for the Vite runtime plugin to
|
|
689
|
+
* handle — they should not be baked into the Angular compilation host because
|
|
690
|
+
* that would apply them to both browser and server builds.
|
|
691
|
+
*
|
|
692
|
+
* Relative paths are resolved against `workspaceRoot` so that the host
|
|
693
|
+
* receives the same absolute paths it would get from the Angular CLI.
|
|
694
|
+
*/
|
|
695
|
+
function toAngularCompilationFileReplacements(replacements, workspaceRoot) {
|
|
696
|
+
const mappedReplacements = replacements.flatMap((replacement) => {
|
|
697
|
+
if (!("with" in replacement)) return [];
|
|
698
|
+
return [[isAbsolute(replacement.replace) ? replacement.replace : resolve(workspaceRoot, replacement.replace), isAbsolute(replacement.with) ? replacement.with : resolve(workspaceRoot, replacement.with)]];
|
|
699
|
+
});
|
|
700
|
+
return mappedReplacements.length ? Object.fromEntries(mappedReplacements) : void 0;
|
|
960
701
|
}
|
|
961
702
|
/**
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
703
|
+
* Map Angular's `templateUpdates` (keyed by `encodedFilePath@ClassName`)
|
|
704
|
+
* back to absolute file paths with their associated HMR code and component
|
|
705
|
+
* class name.
|
|
706
|
+
*
|
|
707
|
+
* Angular's private Compilation API emits template update keys in the form
|
|
708
|
+
* `encodeURIComponent(relativePath + '@' + className)`. We decode and resolve
|
|
709
|
+
* them so the caller can look up updates by the same normalized absolute path
|
|
710
|
+
* used elsewhere in the plugin (`outputFiles`, `classNames`, etc.).
|
|
711
|
+
*/
|
|
712
|
+
function mapTemplateUpdatesToFiles(templateUpdates) {
|
|
713
|
+
const updatesByFile = /* @__PURE__ */ new Map();
|
|
714
|
+
templateUpdates?.forEach((code, encodedUpdateId) => {
|
|
715
|
+
const [file, className = ""] = decodeURIComponent(encodedUpdateId).split("@");
|
|
716
|
+
const resolvedFile = normalizePath(resolve(process.cwd(), file));
|
|
717
|
+
updatesByFile.set(resolvedFile, {
|
|
718
|
+
className,
|
|
719
|
+
code
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
return updatesByFile;
|
|
982
723
|
}
|
|
983
724
|
function sendHMRComponentUpdate(server, id) {
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
725
|
+
server.ws.send("angular:component-update", {
|
|
726
|
+
id: encodeURIComponent(id),
|
|
727
|
+
timestamp: Date.now()
|
|
728
|
+
});
|
|
729
|
+
classNames.delete(id);
|
|
989
730
|
}
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
return { errors, warnings, hmrUpdateCode, hmrEligible };
|
|
1020
|
-
};
|
|
731
|
+
function getFileMetadata(program, angularCompiler, liveReload, disableTypeChecking) {
|
|
732
|
+
const ts = require("typescript");
|
|
733
|
+
return (file) => {
|
|
734
|
+
const sourceFile = program.getSourceFile(file);
|
|
735
|
+
if (!sourceFile) return {};
|
|
736
|
+
const diagnostics = getDiagnosticsForSourceFile(sourceFile, !!disableTypeChecking, program, angularCompiler);
|
|
737
|
+
const errors = diagnostics.filter((d) => d.category === ts.DiagnosticCategory?.Error).map((d) => typeof d.messageText === "object" ? d.messageText.messageText : d.messageText);
|
|
738
|
+
const warnings = diagnostics.filter((d) => d.category === ts.DiagnosticCategory?.Warning).map((d) => d.messageText);
|
|
739
|
+
let hmrUpdateCode = void 0;
|
|
740
|
+
let hmrEligible = false;
|
|
741
|
+
if (liveReload) {
|
|
742
|
+
for (const node of sourceFile.statements) if (ts.isClassDeclaration(node) && node.name != null) {
|
|
743
|
+
hmrUpdateCode = angularCompiler?.emitHmrUpdateModule(node);
|
|
744
|
+
if (hmrUpdateCode) {
|
|
745
|
+
classNames.set(file, node.name.getText());
|
|
746
|
+
hmrEligible = true;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
return {
|
|
751
|
+
errors,
|
|
752
|
+
warnings,
|
|
753
|
+
hmrUpdateCode,
|
|
754
|
+
hmrEligible
|
|
755
|
+
};
|
|
756
|
+
};
|
|
1021
757
|
}
|
|
1022
758
|
function getDiagnosticsForSourceFile(sourceFile, disableTypeChecking, program, angularCompiler) {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
: [];
|
|
1033
|
-
return [
|
|
1034
|
-
...syntacticDiagnostics,
|
|
1035
|
-
...semanticDiagnostics,
|
|
1036
|
-
...angularDiagnostics,
|
|
1037
|
-
];
|
|
759
|
+
const syntacticDiagnostics = program.getSyntacticDiagnostics(sourceFile);
|
|
760
|
+
if (disableTypeChecking) return syntacticDiagnostics;
|
|
761
|
+
const semanticDiagnostics = program.getSemanticDiagnostics(sourceFile);
|
|
762
|
+
const angularDiagnostics = angularCompiler ? angularCompiler.getDiagnosticsForFile(sourceFile, 1) : [];
|
|
763
|
+
return [
|
|
764
|
+
...syntacticDiagnostics,
|
|
765
|
+
...semanticDiagnostics,
|
|
766
|
+
...angularDiagnostics
|
|
767
|
+
];
|
|
1038
768
|
}
|
|
1039
769
|
function markModuleSelfAccepting(mod) {
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
...mod,
|
|
1046
|
-
isSelfAccepting: true,
|
|
1047
|
-
};
|
|
770
|
+
if ("_clientModule" in mod) mod["_clientModule"].isSelfAccepting = true;
|
|
771
|
+
return {
|
|
772
|
+
...mod,
|
|
773
|
+
isSelfAccepting: true
|
|
774
|
+
};
|
|
1048
775
|
}
|
|
1049
776
|
function isComponentStyleSheet(id) {
|
|
1050
|
-
|
|
777
|
+
return id.includes("ngcomp=");
|
|
1051
778
|
}
|
|
1052
779
|
function getComponentStyleSheetMeta(id) {
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
};
|
|
780
|
+
const params = new URL(id, "http://localhost").searchParams;
|
|
781
|
+
return {
|
|
782
|
+
componentId: params.get("ngcomp"),
|
|
783
|
+
encapsulation: {
|
|
784
|
+
"0": "emulated",
|
|
785
|
+
"2": "none",
|
|
786
|
+
"3": "shadow"
|
|
787
|
+
}[params.get("e")]
|
|
788
|
+
};
|
|
1063
789
|
}
|
|
1064
790
|
/**
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
791
|
+
* Removes leading / and query string from a url path
|
|
792
|
+
* e.g. /foo.scss?direct&ngcomp=ng-c3153525609&e=0 returns foo.scss
|
|
793
|
+
* @param id
|
|
794
|
+
*/
|
|
1069
795
|
function getFilenameFromPath(id) {
|
|
1070
|
-
|
|
796
|
+
return new URL(id, "http://localhost").pathname.replace(/^\//, "");
|
|
1071
797
|
}
|
|
1072
798
|
/**
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
if (hasNoRun) {
|
|
1085
|
-
return true;
|
|
1086
|
-
}
|
|
1087
|
-
// check for --watch=false or --no-watch
|
|
1088
|
-
const hasWatch = args.find((arg) => arg.includes('watch'));
|
|
1089
|
-
if (hasWatch && ['false', 'no'].some((neg) => hasWatch.includes(neg))) {
|
|
1090
|
-
return false;
|
|
1091
|
-
}
|
|
1092
|
-
// check for --watch false
|
|
1093
|
-
const watchIndex = args.findIndex((arg) => arg.includes('watch'));
|
|
1094
|
-
const watchArg = args[watchIndex + 1];
|
|
1095
|
-
if (watchArg && watchArg === 'false') {
|
|
1096
|
-
return false;
|
|
1097
|
-
}
|
|
1098
|
-
return true;
|
|
799
|
+
* Checks for vitest run from the command line
|
|
800
|
+
* @returns boolean
|
|
801
|
+
*/
|
|
802
|
+
function isTestWatchMode(args = process.argv) {
|
|
803
|
+
if (args.find((arg) => arg.includes("--run"))) return false;
|
|
804
|
+
if (args.find((arg) => arg.includes("--no-run"))) return true;
|
|
805
|
+
const hasWatch = args.find((arg) => arg.includes("watch"));
|
|
806
|
+
if (hasWatch && ["false", "no"].some((neg) => hasWatch.includes(neg))) return false;
|
|
807
|
+
const watchArg = args[args.findIndex((arg) => arg.includes("watch")) + 1];
|
|
808
|
+
if (watchArg && watchArg === "false") return false;
|
|
809
|
+
return true;
|
|
1099
810
|
}
|
|
811
|
+
//#endregion
|
|
812
|
+
export { angular };
|
|
813
|
+
|
|
1100
814
|
//# sourceMappingURL=angular-vite-plugin.js.map
|