-
Notifications
You must be signed in to change notification settings - Fork 795
/
stencil-public-compiler.ts
2714 lines (2473 loc) · 86 KB
/
stencil-public-compiler.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
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
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import type { ConfigFlags } from '../cli/config-flags';
import type { PrerenderUrlResults, PrintLine } from '../internal';
import type { JsonDocs } from './stencil-public-docs';
export * from './stencil-public-docs';
/**
* https://stenciljs.com/docs/config/
*/
export interface StencilConfig {
/**
* By default, Stencil will attempt to optimize small scripts by inlining them in HTML. Setting
* this flag to `false` will prevent this optimization and keep all scripts separate from HTML.
*/
allowInlineScripts?: boolean;
/**
* By setting `autoprefixCss` to `true`, Stencil will use the appropriate config to automatically
* prefix css. For example, developers can write modern and standard css properties, such as
* "transform", and Stencil will automatically add in the prefixed version, such as "-webkit-transform".
* As of Stencil v2, autoprefixing CSS is no longer the default.
* Defaults to `false`
*/
autoprefixCss?: boolean | any;
/**
* By default, Stencil will statically analyze the application and generate a component graph of
* how all the components are interconnected.
*
* From the component graph it is able to best decide how components should be grouped
* depending on their usage with one another within the app.
* By doing so it's able to bundle components together in order to reduce network requests.
* However, bundles can be manually generated using the bundles config.
*
* The bundles config is an array of objects that represent how components are grouped together
* in lazy-loaded bundles.
* This config is rarely needed as Stencil handles this automatically behind the scenes.
*/
bundles?: ConfigBundle[];
/**
* Stencil will cache build results in order to speed up rebuilds.
* To disable this feature, set enableCache to false.
*/
enableCache?: boolean;
/**
* Stencil is traditionally used to compile many components into an app,
* and each component comes with its own compartmentalized styles.
* However, it's still common to have styles which should be "global" across all components and the website.
* A global CSS file is often useful to set CSS Variables.
*
* Additionally, the globalStyle config can be used to precompile styles with Sass, PostCss, etc.
* Below is an example folder structure containing a webapp's global sass file, named app.css.
*/
globalStyle?: string;
/**
* When the hashFileNames config is set to true, and it is a production build,
* the hashedFileNameLength config is used to determine how many characters the file name's hash should be.
*/
hashedFileNameLength?: number;
/**
* During production builds, the content of each generated file is hashed to represent the content,
* and the hashed value is used as the filename. If the content isn't updated between builds,
* then it receives the same filename. When the content is updated, then the filename is different.
*
* By doing this, deployed apps can "forever-cache" the build directory and take full advantage of
* content delivery networks (CDNs) and heavily caching files for faster apps.
*/
hashFileNames?: boolean;
/**
* The namespace config is a string representing a namespace for the app.
* For apps that are not meant to be a library of reusable components,
* the default of App is just fine. However, if the app is meant to be consumed
* as a third-party library, such as Ionic, a unique namespace is required.
*/
namespace?: string;
/**
* Stencil is able to take an app's source and compile it to numerous targets,
* such as an app to be deployed on an http server, or as a third-party library
* to be distributed on npm. By default, Stencil apps have an output target type of www.
*
* The outputTargets config is an array of objects, with types of www and dist.
*/
outputTargets?: OutputTarget[];
/**
* The plugins config can be used to add your own rollup plugins.
* By default, Stencil does not come with Sass or PostCss support.
* However, either can be added using the plugin array.
*/
plugins?: any[];
/**
* Generate js source map files for all bundles
*/
sourceMap?: boolean;
/**
* The srcDir config specifies the directory which should contain the source typescript files
* for each component. The standard for Stencil apps is to use src, which is the default.
*/
srcDir?: string;
/**
* Sets whether or not Stencil should transform path aliases set in a project's
* `tsconfig.json` from the assigned module aliases to resolved relative paths.
*
* This behavior is opt-in and hence this flag defaults to `false`.
*/
transformAliasedImportPaths?: boolean;
/**
* Passes custom configuration down to the "@rollup/plugin-commonjs" that Stencil uses under the hood.
* For further information: https://stenciljs.com/docs/module-bundling
*/
commonjs?: BundlingConfig;
/**
* Passes custom configuration down to the "@rollup/plugin-node-resolve" that Stencil uses under the hood.
* For further information: https://stenciljs.com/docs/module-bundling
*/
nodeResolve?: NodeResolveConfig;
/**
* Passes custom configuration down to rollup itself, not all rollup options can be overridden.
*/
rollupConfig?: RollupConfig;
/**
* Sets if the ES5 build should be generated or not. Stencil generates a modern build without ES5,
* whereas this setting to `true` will also create es5 builds for both dev and prod modes. Setting
* `buildEs5` to `prod` will only build ES5 in prod mode. Basically if the app does not need to run
* on legacy browsers (IE11 and Edge 18 and below), it's safe to not build ES5, which will also speed
* up build times. Defaults to `false`.
*/
buildEs5?: boolean | 'prod';
/**
* Sets if the JS browser files are minified or not. Stencil uses `terser` under the hood.
* Defaults to `false` in dev mode and `true` in production mode.
*/
minifyJs?: boolean;
/**
* Sets if the CSS is minified or not.
* Defaults to `false` in dev mode and `true` in production mode.
*/
minifyCss?: boolean;
/**
* Forces Stencil to run in `dev` mode if the value is `true` and `production` mode
* if it's `false`.
*
* Defaults to `false` (ie. production) unless the `--dev` flag is used in the CLI.
*/
devMode?: boolean;
/**
* Object to provide a custom logger. By default a `logger` is already provided for the
* platform the compiler is running on, such as NodeJS or a browser.
*/
logger?: Logger;
/**
* Config to add extra runtime for DOM features that require more polyfills. Note
* that not all DOM APIs are fully polyfilled when using the slot polyfill. These
* are opt-in since not all users will require the additional runtime.
*/
extras?: ConfigExtras;
/**
* The hydrated flag identifies if a component and all of its child components
* have finished hydrating. This helps prevent any flash of unstyled content (FOUC)
* as various components are asynchronously downloaded and rendered. By default it
* will add the `hydrated` CSS class to the element. The `hydratedFlag` config can be used
* to change the name of the CSS class, change it to an attribute, or change which
* type of CSS properties and values are assigned before and after hydrating. This config
* can also be used to not include the hydrated flag at all by setting it to `null`.
*/
hydratedFlag?: HydratedFlag | null;
/**
* Ionic prefers to hide all components prior to hydration with a style tag appended
* to the head of the document containing some `visibility: hidden;` css rules.
*
* Disabling this will remove the style tag that sets `visibility: hidden;` on all
* unhydrated web components. This more closely follows the HTML spec, and allows
* you to set your own fallback content.
*
*/
invisiblePrehydration?: boolean;
/**
* Sets the task queue used by stencil's runtime. The task queue schedules DOM read and writes
* across the frames to efficiently render and reduce layout thrashing. By default,
* `async` is used. It's recommended to also try each setting to decide which works
* best for your use-case. In all cases, if your app has many CPU intensive tasks causing the
* main thread to periodically lock-up, it's always recommended to try
* [Web Workers](https://stenciljs.com/docs/web-workers) for those tasks.
*
* - `async`: DOM read and writes are scheduled in the next frame to prevent layout thrashing.
* During intensive CPU tasks it will not reschedule rendering to happen in the next frame.
* `async` is ideal for most apps, and if the app has many intensive tasks causing the main
* thread to lock-up, it's recommended to try [Web Workers](https://stenciljs.com/docs/web-workers)
* rather than the congestion async queue.
*
* - `congestionAsync`: DOM reads and writes are scheduled in the next frame to prevent layout
* thrashing. When the app is heavily tasked and the queue becomes congested it will then
* split the work across multiple frames to prevent blocking the main thread. However, it can
* also introduce unnecessary reflows in some cases, especially during startup. `congestionAsync`
* is ideal for apps running animations while also simultaneously executing intensive tasks
* which may lock-up the main thread.
*
* - `immediate`: Makes writeTask() and readTask() callbacks to be executed synchronously. Tasks
* are not scheduled to run in the next frame, but do note there is at least one microtask.
* The `immediate` setting is ideal for apps that do not provide long running and smooth
* animations. Like the async setting, if the app has intensive tasks causing the main thread
* to lock-up, it's recommended to try [Web Workers](https://stenciljs.com/docs/web-workers).
*/
taskQueue?: 'async' | 'immediate' | 'congestionAsync';
/**
* Provide a object of key/values accessible within the app, using the `Env` object.
*/
env?: { [prop: string]: string | undefined };
globalScript?: string;
srcIndexHtml?: string;
watch?: boolean;
testing?: TestingConfig;
maxConcurrentWorkers?: number;
preamble?: string;
rollupPlugins?: { before?: any[]; after?: any[] };
entryComponentsHint?: string[];
buildDist?: boolean;
buildLogFilePath?: string;
cacheDir?: string;
devInspector?: boolean;
devServer?: StencilDevServerConfig;
enableCacheStats?: boolean;
sys?: CompilerSystem;
tsconfig?: string;
validateTypes?: boolean;
/**
* An array of RegExp patterns that are matched against all source files before adding
* to the watch list in watch mode. If the file path matches any of the patterns, when it
* is updated, it will not trigger a re-run of tests.
*/
watchIgnoredRegex?: RegExp | RegExp[];
/**
* Set whether unused dependencies should be excluded from the built output.
*/
excludeUnusedDependencies?: boolean;
stencilCoreResolvedId?: string;
}
export interface ConfigExtras {
/**
* By default, the slot polyfill does not update `appendChild()` so that it appends
* new child nodes into the correct child slot like how shadow dom works. This is an opt-in
* polyfill for those who need it when using `element.appendChild(node)` and expecting the
* child to be appended in the same location shadow dom would. This is not required for
* IE11 or Edge 18, but can be enabled if the app is using `appendChild()`. Defaults to `false`.
*/
appendChildSlotFix?: boolean;
/**
* By default, the runtime does not polyfill `cloneNode()` when cloning a component
* that uses the slot polyfill. This is an opt-in polyfill for those who need it.
* This is not required for IE11 or Edge 18, but can be enabled if the app is using
* `cloneNode()` and unexpected node are being cloned due to the slot polyfill
* simulating shadow dom. Defaults to `false`.
*/
cloneNodeFix?: boolean;
// TODO(STENCIL-659): Remove code implementing the CSS variable shim
/**
* Include the CSS Custom Property polyfill/shim for legacy browsers. ESM builds will
* not include the css vars shim. Defaults to `false`
*
* @deprecated Since Stencil v3.0.0. IE 11, Edge <= 18, and old Safari
* versions are no longer supported.
*/
__deprecated__cssVarsShim?: boolean;
// TODO(STENCIL-661): Remove code related to the dynamic import shim
/**
* Dynamic `import()` shim. This is only needed for Edge 18 and below, and
* Firefox 67 and below. Defaults to `false`.
* @deprecated Since Stencil v3.0.0. IE 11, Edge <= 18, and old Safari
* versions are no longer supported.
*/
__deprecated__dynamicImportShim?: boolean;
/**
* Experimental flag. Projects that use a Stencil library built using the `dist` output target may have trouble lazily
* loading components when using a bundler such as Vite or Parcel. Setting this flag to `true` will change how Stencil
* lazily loads components in a way that works with additional bundlers. Setting this flag to `true` will increase
* the size of the compiled output. Defaults to `false`.
* @deprecated This flag has been deprecated in favor of `enableImportInjection`, which provides the same
* functionality. `experimentalImportInjection` will be removed in a future major version of Stencil.
*/
experimentalImportInjection?: boolean;
/**
* Projects that use a Stencil library built using the `dist` output target may have trouble lazily
* loading components when using a bundler such as Vite or Parcel. Setting this flag to `true` will change how Stencil
* lazily loads components in a way that works with additional bundlers. Setting this flag to `true` will increase
* the size of the compiled output. Defaults to `false`.
*/
enableImportInjection?: boolean;
/**
* Dispatches component lifecycle events. Mainly used for testing. Defaults to `false`.
*/
lifecycleDOMEvents?: boolean;
// TODO(STENCIL-663): Remove code related to deprecated `safari10` field.
/**
* Safari 10 supports ES modules with `<script type="module">`, however, it did not implement
* `<script nomodule>`. When set to `true`, the runtime will patch support for Safari 10
* due to its lack of `nomodule` support.
* Defaults to `false`.
*
* @deprecated Since Stencil v3.0.0, Safari 10 is no longer supported.
*/
__deprecated__safari10?: boolean;
/**
* It is possible to assign data to the actual `<script>` element's `data-opts` property,
* which then gets passed to Stencil's initial bootstrap. This feature is only required
* for very special cases and rarely needed. Defaults to `false`.
*/
scriptDataOpts?: boolean;
/**
* Experimental flag to align the behavior of invoking `textContent` on a scoped component to act more like a
* component that uses the shadow DOM. Defaults to `false`
*/
scopedSlotTextContentFix?: boolean;
// TODO(STENCIL-662): Remove code related to deprecated shadowDomShim field
/**
* If enabled `true`, the runtime will check if the shadow dom shim is required. However,
* if it's determined that shadow dom is already natively supported by the browser then
* it does not request the shim. When set to `false` it will avoid all shadow dom tests.
* Defaults to `false`.
*
* @deprecated Since Stencil v3.0.0. IE 11, Edge <= 18, and old Safari versions
* are no longer supported.
*/
__deprecated__shadowDomShim?: boolean;
/**
* When a component is first attached to the DOM, this setting will wait a single tick before
* rendering. This works around an Angular issue, where Angular attaches the elements before
* settings their initial state, leading to double renders and unnecessary event dispatches.
* Defaults to `false`.
*/
initializeNextTick?: boolean;
/**
* For browsers that do not support shadow dom (IE11 and Edge 18 and below), slot is polyfilled
* to simulate the same behavior. However, the host element's `childNodes` and `children`
* getters are not patched to only show the child nodes and elements of the default slot.
* Defaults to `false`.
*/
slotChildNodesFix?: boolean;
/**
* Enables the tagNameTransform option of `defineCustomElements()`, so the component tagName
* can be customized at runtime. Defaults to `false`.
*/
tagNameTransform?: boolean;
}
export interface Config extends StencilConfig {
buildAppCore?: boolean;
buildDocs?: boolean;
configPath?: string;
writeLog?: boolean;
devServer?: DevServerConfig;
flags?: ConfigFlags;
fsNamespace?: string;
logLevel?: LogLevel;
rootDir?: string;
packageJsonFilePath?: string;
suppressLogs?: boolean;
profile?: boolean;
tsCompilerOptions?: any;
_isValidated?: boolean;
_isTesting?: boolean;
}
/**
* A 'loose' type useful for wrapping an incomplete / possible malformed
* object as we work on getting it comply with a particular Interface T.
*
* Example:
*
* ```ts
* interface Foo {
* bar: string
* }
*
* function validateFoo(foo: Loose<Foo>): Foo {
* let validatedFoo = {
* ...foo,
* bar: foo.bar || DEFAULT_BAR
* }
*
* return validatedFoo
* }
* ```
*
* Use this when you need to take user input or something from some other part
* of the world that we don't control and transform it into something
* conforming to a given interface. For best results, pair with a validation
* function as shown in the example.
*/
type Loose<T extends Object> = Record<string, any> & Partial<T>;
/**
* A Loose version of the Config interface. This is intended to let us load a partial config
* and have type information carry though as we construct an object which is a valid `Config`.
*/
export type UnvalidatedConfig = Loose<Config>;
/**
* Helper type to strip optional markers from keys in a type, while preserving other type information for the key.
* This type takes a union of keys, K, in type T to allow for the type T to be gradually updated.
*
* ```typescript
* type Foo { bar?: number, baz?: string }
* type ReqFieldFoo = RequireFields<Foo, 'bar'>; // { bar: number, baz?: string }
* ```
*/
type RequireFields<T, K extends keyof T> = T & { [P in K]-?: T[P] };
/**
* Fields in {@link Config} to make required for {@link ValidatedConfig}
*/
type StrictConfigFields =
| 'cacheDir'
| 'devServer'
| 'flags'
| 'hydratedFlag'
| 'logger'
| 'outputTargets'
| 'packageJsonFilePath'
| 'rollupConfig'
| 'rootDir'
| 'srcDir'
| 'srcIndexHtml'
| 'sys'
| 'testing'
| 'transformAliasedImportPaths';
/**
* A version of {@link Config} that makes certain fields required. This type represents a valid configuration entity.
* When a configuration is received by the user, it is a bag of unverified data. In order to make stricter guarantees
* about the data from a type-safety perspective, this type is intended to be used throughout the codebase once
* validations have occurred at runtime.
*/
export type ValidatedConfig = RequireFields<Config, StrictConfigFields>;
export interface HydratedFlag {
/**
* Defaults to `hydrated`.
*/
name?: string;
/**
* Can be either `class` or `attribute`. Defaults to `class`.
*/
selector?: 'class' | 'attribute';
/**
* The CSS property used to show and hide components. Defaults to use the CSS `visibility`
* property. Other commonly used CSS properties would be `display` with the `initialValue`
* setting as `none`, or `opacity` with the `initialValue` as `0`. Defaults to `visibility`
* and the default `initialValue` is `hidden`.
*/
property?: string;
/**
* This is the CSS value to give all components before it has been hydrated.
* Defaults to `hidden`.
*/
initialValue?: string;
/**
* This is the CSS value to assign once a component has finished hydrating.
* This is the CSS value that'll allow the component to show. Defaults to `inherit`.
*/
hydratedValue?: string;
}
export interface StencilDevServerConfig {
/**
* IP address used by the dev server. The default is `0.0.0.0`, which points to all IPv4 addresses
* on the local machine, such as `localhost`.
*/
address?: string;
/**
* Base path to be used by the server. Defaults to the root pathname.
*/
basePath?: string;
/**
* EXPERIMENTAL!
* During development, node modules can be independently requested and bundled, making for
* faster build times. This is only available using the Stencil Dev Server throughout
* development. Production builds and builds with the `es5` flag will override
* this setting to `false`. Default is `false`.
*/
experimentalDevModules?: boolean;
/**
* If the dev server should respond with gzip compressed content. Defaults to `true`.
*/
gzip?: boolean;
/**
* When set, the dev server will run via https using the SSL certificate and key you provide
* (use `fs` if you want to read them from files).
*/
https?: Credentials;
/**
* The URL the dev server should first open to. Defaults to `/`.
*/
initialLoadUrl?: string;
/**
* When `true`, every request to the server will be logged within the terminal.
* Defaults to `false`.
*/
logRequests?: boolean;
/**
* By default, when dev server is started the local dev URL is opened in your default browser.
* However, to prevent this URL to be opened change this value to `false`. Defaults to `true`.
*/
openBrowser?: boolean;
/**
* Sets the server's port. Defaults to `3333`.
*/
port?: number;
/**
* When files are watched and updated, by default the dev server will use `hmr` (Hot Module Replacement)
* to update the page without a full page refresh. To have the page do a full refresh use `pageReload`.
* To disable any reloading, use `null`. Defaults to `hmr`.
*/
reloadStrategy?: PageReloadStrategy;
/**
* Local path to a NodeJs file with a dev server request listener as the default export.
* The user's request listener is given the first chance to handle every request the dev server
* receives, and can choose to handle it or instead pass it on to the default dev server
* by calling `next()`.
*
* Below is an example of a NodeJs file the `requestListenerPath` config is using.
* The request and response arguments are the same as Node's `http` module and `RequestListener`
* callback. https://nodejs.org/api/http.html#http_http_createserver_options_requestlistener
*
* ```js
* module.exports = function (req, res, next) {
* if (req.url === '/ping') {
* // custom response overriding the dev server
* res.setHeader('Content-Type', 'text/plain');
* res.writeHead(200);
* res.end('pong');
* } else {
* // pass request on to the default dev server
* next();
* }
* };
* ```
*/
requestListenerPath?: string;
/**
* The root directory to serve the files from.
*/
root?: string;
/**
* If the dev server should Server-Side Render (SSR) each page, meaning it'll dynamically generate
* server-side rendered html on each page load. The `--ssr` flag will most commonly be used with
* the`--dev --watch --serve` flags during development. Note that this is for development purposes
* only, and the built-in dev server should not be used for production. Defaults to `false`.
*/
ssr?: boolean;
/**
* If the dev server fails to start up within the given timeout (in milliseconds), the startup will
* be canceled. Set to zero to disable the timeout. Defaults to `15000`.
*/
startupTimeout?: number;
/**
* Whether to use the dev server's websocket client or not. Defaults to `true`.
*/
websocket?: boolean;
/**
* If the dev server should fork a worker for the server process or not. A singled-threaded dev server
* is slower, however it is useful for debugging http requests and responses. Defaults to `true`.
*/
worker?: boolean;
}
export interface DevServerConfig extends StencilDevServerConfig {
browserUrl?: string;
devServerDir?: string;
/**
* A list of glob patterns like `subdir/*.js` to exclude from hot-module
* reloading updates.
*/
excludeHmr?: string[];
historyApiFallback?: HistoryApiFallback;
openBrowser?: boolean;
prerenderConfig?: string;
protocol?: 'http' | 'https';
srcIndexHtml?: string;
}
export interface HistoryApiFallback {
index?: string;
disableDotRule?: boolean;
}
export interface DevServerEditor {
id: string;
name?: string;
supported?: boolean;
priority?: number;
}
export type TaskCommand =
| 'build'
| 'docs'
| 'generate'
| 'g'
| 'help'
| 'info'
| 'prerender'
| 'serve'
| 'telemetry'
| 'test'
| 'version';
export type PageReloadStrategy = 'hmr' | 'pageReload' | null;
/**
* The prerender config is used when prerendering a `www` output target.
* Within `stencil.config.ts`, set the path to the prerendering
* config file path using the `prerenderConfig` property, such as:
*
* ```tsx
* import { Config } from '@stencil/core';
* export const config: Config = {
* outputTargets: [
* {
* type: 'www',
* baseUrl: 'https://stenciljs.com/',
* prerenderConfig: './prerender.config.ts',
* }
* ]
* };
* ```
*
* The `prerender.config.ts` should export a `config` object using
* the `PrerenderConfig` interface.
*
* ```tsx
* import { PrerenderConfig } from '@stencil/core';
* export const config: PrerenderConfig = {
* ...
* };
* ```
*
* For more info: https://stenciljs.com/docs/static-site-generation
*/
export interface PrerenderConfig {
/**
* Run after each `document` is hydrated, but before it is serialized
* into an HTML string. Hook is passed the `document` and its `URL`.
*/
afterHydrate?(document: Document, url: URL, results: PrerenderUrlResults): any | Promise<any>;
/**
* Run before each `document` is hydrated. Hook is passed the `document` it's `URL`.
*/
beforeHydrate?(document: Document, url: URL): any | Promise<any>;
/**
* Runs after the template Document object has serialize into an
* HTML formatted string. Returns an HTML string to be used as the
* base template for all prerendered pages.
*/
afterSerializeTemplate?(html: string): string | Promise<string>;
/**
* Runs before the template Document object is serialize into an
* HTML formatted string. Returns the Document to be serialized which
* will become the base template html for all prerendered pages.
*/
beforeSerializeTemplate?(document: Document): Document | Promise<Document>;
/**
* A hook to be used to generate the canonical `<link>` tag
* which goes in the `<head>` of every prerendered page. Returning `null`
* will not add a canonical url tag to the page.
*/
canonicalUrl?(url: URL): string | null;
/**
* While prerendering, crawl same-origin URLs found within `<a href>` elements.
* Defaults to `true`.
*/
crawlUrls?: boolean;
/**
* URLs to start the prerendering from. By default the root URL of `/` is used.
*/
entryUrls?: string[];
/**
* Return `true` the given `<a>` element should be crawled or not.
*/
filterAnchor?(attrs: { [attrName: string]: string }, base?: URL): boolean;
/**
* Return `true` if the given URL should be prerendered or not.
*/
filterUrl?(url: URL, base: URL): boolean;
/**
* Returns the file path which the prerendered HTML content
* should be written to.
*/
filePath?(url: URL, filePath: string): string;
/**
* Returns the hydrate options to use for each individual prerendered page.
*/
hydrateOptions?(url: URL): PrerenderHydrateOptions;
/**
* Returns the template file's content. The template is the base
* HTML used for all prerendered pages.
*/
loadTemplate?(filePath: string): string | Promise<string>;
/**
* Used to normalize the page's URL from a given a string and the current
* page's base URL. Largely used when reading an anchor's `href` attribute
* value and normalizing it into a `URL`.
*/
normalizeUrl?(href: string, base: URL): URL;
robotsTxt?(opts: RobotsTxtOpts): string | RobotsTxtResults;
sitemapXml?(opts: SitemapXmpOpts): string | SitemapXmpResults;
/**
* Static Site Generated (SSG). Does not include Stencil's clientside
* JavaScript, custom elements or preload modules.
*/
staticSite?: boolean;
/**
* If the prerenndered URLs should have a trailing "/"" or not. Defaults to `false`.
*/
trailingSlash?: boolean;
}
export interface HydrateDocumentOptions {
/**
* Build ID that will be added to `<html data-stencil-build="BUILD_ID">`. By default
* a random ID will be generated
*/
buildId?: string;
/**
* Sets the `href` attribute on the `<link rel="canonical">`
* tag within the `<head>`. If the value is not defined it will
* ensure a canonical link tag is no included in the `<head>`.
*/
canonicalUrl?: string;
/**
* Include the HTML comments and attributes used by the clientside
* JavaScript to read the structure of the HTML and rebuild each
* component. Defaults to `true`.
*/
clientHydrateAnnotations?: boolean;
/**
* Constrain `setTimeout()` to 1ms, but still async. Also
* only allows `setInterval()` to fire once, also constrained to 1ms.
* Defaults to `true`.
*/
constrainTimeouts?: boolean;
/**
* Sets `document.cookie`
*/
cookie?: string;
/**
* Sets the `dir` attribute on the top level `<html>`.
*/
direction?: string;
/**
* Component tag names listed here will not be prerendered, nor will
* hydrated on the clientside. Components listed here will be ignored
* as custom elements and treated no differently than a `<div>`.
*/
excludeComponents?: string[];
/**
* Sets the `lang` attribute on the top level `<html>`.
*/
language?: string;
/**
* Maximum number of components to hydrate on one page. Defaults to `300`.
*/
maxHydrateCount?: number;
/**
* Sets `document.referrer`
*/
referrer?: string;
/**
* Removes every `<script>` element found in the `document`. Defaults to `false`.
*/
removeScripts?: boolean;
/**
* Removes CSS not used by elements within the `document`. Defaults to `true`.
*/
removeUnusedStyles?: boolean;
/**
* The url the runtime uses for the resources, such as the assets directory.
*/
resourcesUrl?: string;
/**
* Prints out runtime console logs to the NodeJS process. Defaults to `false`.
*/
runtimeLogging?: boolean;
/**
* Component tags listed here will only be prerendered or serverside-rendered
* and will not be clientside hydrated. This is useful for components that
* are not dynamic and do not need to be defined as a custom element within the
* browser. For example, a header or footer component would be a good example that
* may not require any clientside JavaScript.
*/
staticComponents?: string[];
/**
* The amount of milliseconds to wait for a page to finish rendering until
* a timeout error is thrown. Defaults to `15000`.
*/
timeout?: number;
/**
* Sets `document.title`.
*/
title?: string;
/**
* Sets `location.href`
*/
url?: string;
/**
* Sets `navigator.userAgent`
*/
userAgent?: string;
}
export interface SerializeDocumentOptions extends HydrateDocumentOptions {
/**
* Runs after the `document` has been hydrated.
*/
afterHydrate?(document: any): any | Promise<any>;
/**
* Sets an approximate line width the HTML should attempt to stay within.
* Note that this is "approximate", in that HTML may often not be able
* to be split at an exact line width. Additionally, new lines created
* is where HTML naturally already has whitespace, such as before an
* attribute or spaces between words. Defaults to `100`.
*/
approximateLineWidth?: number;
/**
* Runs before the `document` has been hydrated.
*/
beforeHydrate?(document: any): any | Promise<any>;
/**
* Format the HTML in a nicely indented format.
* Defaults to `false`.
*/
prettyHtml?: boolean;
/**
* Remove quotes from attribute values when possible.
* Defaults to `true`.
*/
removeAttributeQuotes?: boolean;
/**
* Remove the `=""` from standardized `boolean` attributes,
* such as `hidden` or `checked`. Defaults to `true`.
*/
removeBooleanAttributeQuotes?: boolean;
/**
* Remove these standardized attributes when their value is empty:
* `class`, `dir`, `id`, `lang`, and `name`, `title`. Defaults to `true`.
*/
removeEmptyAttributes?: boolean;
/**
* Remove HTML comments. Defaults to `true`.
*/
removeHtmlComments?: boolean;
}
export interface HydrateFactoryOptions extends SerializeDocumentOptions {
serializeToHtml: boolean;
destroyWindow: boolean;
destroyDocument: boolean;
}
export interface PrerenderHydrateOptions extends SerializeDocumentOptions {
/**
* Adds `<link rel="modulepreload">` for modules that will eventually be requested.
* Defaults to `true`.
*/
addModulePreloads?: boolean;
/**
* Hash the content of assets, such as images, fonts and css files,
* and add the hashed value as `v` querystring. For example,
* `/assets/image.png?v=abcd1234`. This allows for assets to be
* heavily cached by setting the server's response header with
* `Cache-Control: max-age=31536000, immutable`.
*/
hashAssets?: 'querystring';
/**
* External stylesheets from `<link rel="stylesheet">` are instead inlined
* into `<style>` elements. Defaults to `false`.
*/
inlineExternalStyleSheets?: boolean;
/**
* Minify CSS content within `<style>` elements. Defaults to `true`.
*/
minifyStyleElements?: boolean;
/**
* Minify JavaScript content within `<script>` elements. Defaults to `true`.
*/
minifyScriptElements?: boolean;
/**
* Entire `document` should be static. This is useful for specific pages that
* should be static, rather than the entire site. If the whole site should be static,
* use the `staticSite` property on the prerender config instead. If only certain
* components should be static then use `staticComponents` instead.
*/
staticDocument?: boolean;
}
export interface RobotsTxtOpts {
urls: string[];
sitemapUrl: string;
baseUrl: string;
dir: string;
}
export interface RobotsTxtResults {
content: string;
filePath: string;
url: string;
}
export interface SitemapXmpOpts {
urls: string[];
baseUrl: string;
dir: string;
}
export interface SitemapXmpResults {
content: string;
filePath: string;
url: string;
}
/**
* Common system used by the compiler. All file reads, writes, access, etc. will all use
* this system. Additionally, throughout each build, the compiler will use an internal
* in-memory file system as to prevent unnecessary fs reads and writes. At the end of each
* build all actions the in-memory fs performed will be written to disk using this system.
* A NodeJS based system will use APIs such as `fs` and `crypto`, and a web-based system
* will use in-memory Maps and browser APIs. Either way, the compiler itself is unaware
* of the actual platform it's being ran on top of.
*/
export interface CompilerSystem {
name: 'node' | 'in-memory';
version: string;
events?: BuildEvents;
details?: SystemDetails;
/**
* Add a callback which will be ran when destroy() is called.
*/
addDestroy(cb: () => void): void;
/**
* Always returns a boolean, does not throw.
*/
access(p: string): Promise<boolean>;
/**
* SYNC! Always returns a boolean, does not throw.
*/
accessSync(p: string): boolean;
applyGlobalPatch?(fromDir: string): Promise<void>;
applyPrerenderGlobalPatch?(opts: { devServerHostUrl: string; window: any }): void;
cacheStorage?: CacheStorage;
checkVersion?: (logger: Logger, currentVersion: string) => Promise<() => void>;
copy?(copyTasks: Required<CopyTask>[], srcDir: string): Promise<CopyResults>;
/**
* Always returns a boolean if the files were copied or not. Does not throw.
*/
copyFile(src: string, dst: string): Promise<boolean>;
/**
* Used to destroy any listeners, file watchers or child processes.
*/
destroy(): Promise<void>;
/**
* Does not throw.
*/
createDir(p: string, opts?: CompilerSystemCreateDirectoryOptions): Promise<CompilerSystemCreateDirectoryResults>;
/**
* SYNC! Does not throw.