@stencil/cli 5.0.0-alpha.4 → 5.0.0-alpha.5
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/dist/index.d.mts +1 -1
- package/dist/index.mjs +579 -24
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -11,7 +11,7 @@ type TaskCommand = 'build' | 'docs' | 'generate' | 'g' | 'help' | 'info' | 'migr
|
|
|
11
11
|
/**
|
|
12
12
|
* All the Boolean options supported by the Stencil CLI
|
|
13
13
|
*/
|
|
14
|
-
declare const BOOLEAN_CLI_FLAGS: readonly ["build", "cache", "checkVersion", "ci", "compare", "debug", "dev", "devtools", "docs", "dryRun", "
|
|
14
|
+
declare const BOOLEAN_CLI_FLAGS: readonly ["build", "cache", "checkVersion", "ci", "compare", "debug", "dev", "devtools", "docs", "dryRun", "help", "log", "open", "prerender", "prerenderExternal", "profile", "serviceWorker", "serve", "skipNodeCheck", "ssr", "verbose", "version", "watch"];
|
|
15
15
|
/**
|
|
16
16
|
* All the Number options supported by the Stencil CLI
|
|
17
17
|
*/
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LOG_LEVELS } from "@stencil/core/compiler";
|
|
2
|
-
import { buildError, catchError, hasError, isFunction, isOutputTargetDocs,
|
|
2
|
+
import { buildError, catchError, hasError, isFunction, isOutputTargetDocs, isOutputTargetSsr, isOutputTargetWww, isString, normalizePath, readOnlyArrayHasStringMember, result, shouldIgnoreError, toCamelCase, validateComponentTag } from "@stencil/core/compiler/utils";
|
|
3
3
|
import { isAbsolute, join, parse, relative } from "path";
|
|
4
4
|
import ts from "typescript";
|
|
5
5
|
import { start } from "@stencil/dev-server";
|
|
@@ -18,13 +18,11 @@ const BOOLEAN_CLI_FLAGS = [
|
|
|
18
18
|
"devtools",
|
|
19
19
|
"docs",
|
|
20
20
|
"dryRun",
|
|
21
|
-
"esm",
|
|
22
21
|
"help",
|
|
23
22
|
"log",
|
|
24
23
|
"open",
|
|
25
24
|
"prerender",
|
|
26
25
|
"prerenderExternal",
|
|
27
|
-
"prod",
|
|
28
26
|
"profile",
|
|
29
27
|
"serviceWorker",
|
|
30
28
|
"serve",
|
|
@@ -561,7 +559,7 @@ const startupCompilerLog = (coreCompiler, config) => {
|
|
|
561
559
|
*
|
|
562
560
|
* This function applies command-line flags to the config, with CLI flags
|
|
563
561
|
* taking precedence over config file values. This is the canonical place
|
|
564
|
-
* where flag values are translated into config properties
|
|
562
|
+
* where flag values are translated into config properties.
|
|
565
563
|
*
|
|
566
564
|
* @param config The config object (from stencil.config.ts or empty)
|
|
567
565
|
* @param flags The parsed CLI flags
|
|
@@ -569,13 +567,11 @@ const startupCompilerLog = (coreCompiler, config) => {
|
|
|
569
567
|
*/
|
|
570
568
|
const mergeFlags = (config, flags) => {
|
|
571
569
|
const merged = { ...config };
|
|
572
|
-
if (flags.
|
|
573
|
-
else if (flags.dev === true) merged.devMode = true;
|
|
570
|
+
if (flags.dev === true) merged.devMode = true;
|
|
574
571
|
if (flags.debug === true || flags.verbose === true) merged.logLevel = "debug";
|
|
575
572
|
else if (flags.logLevel) merged.logLevel = flags.logLevel;
|
|
576
573
|
if (typeof flags.watch === "boolean") merged.watch = flags.watch;
|
|
577
|
-
if (
|
|
578
|
-
if (typeof flags.esm === "boolean") merged.buildDist = flags.esm;
|
|
574
|
+
if (flags.docs === true) merged._docsFlag = true;
|
|
579
575
|
if (typeof flags.profile === "boolean") merged.profile = flags.profile;
|
|
580
576
|
if (typeof flags.log === "boolean") merged.writeLog = flags.log;
|
|
581
577
|
if (typeof flags.cache === "boolean") merged.enableCache = flags.cache;
|
|
@@ -618,6 +614,164 @@ const printCheckVersionResults = async (versionChecker) => {
|
|
|
618
614
|
}
|
|
619
615
|
};
|
|
620
616
|
//#endregion
|
|
617
|
+
//#region src/migrations/rules/build-dist-docs.ts
|
|
618
|
+
/**
|
|
619
|
+
* Migration rule for buildDist and buildDocs removal.
|
|
620
|
+
*
|
|
621
|
+
* In Stencil v5, these global config options are replaced with per-output-target
|
|
622
|
+
* `skipInDev` property. This migration:
|
|
623
|
+
* - Detects `buildDist` or `buildDocs` in stencil.config.ts
|
|
624
|
+
* - Removes the property
|
|
625
|
+
* - For `buildDist: true` or `buildDocs: true`, adds `skipInDev: false` to relevant output targets
|
|
626
|
+
*/
|
|
627
|
+
const buildDistDocsRule = {
|
|
628
|
+
id: "build-dist-docs",
|
|
629
|
+
name: "buildDist/buildDocs Removal",
|
|
630
|
+
description: "Remove deprecated buildDist and buildDocs config options",
|
|
631
|
+
fromVersion: "4.x",
|
|
632
|
+
toVersion: "5.x",
|
|
633
|
+
detect(sourceFile) {
|
|
634
|
+
const matches = [];
|
|
635
|
+
const visit = (node) => {
|
|
636
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name)) {
|
|
637
|
+
const propName = node.name.text;
|
|
638
|
+
if (propName === "buildDist" || propName === "buildDocs") {
|
|
639
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
640
|
+
const isTrue = node.initializer.kind === ts.SyntaxKind.TrueKeyword;
|
|
641
|
+
matches.push({
|
|
642
|
+
node,
|
|
643
|
+
message: `Deprecated '${propName}' found${isTrue ? " (set to true)" : ""} - will be removed and skipInDev added to output targets`,
|
|
644
|
+
line: line + 1,
|
|
645
|
+
column: character + 1
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
ts.forEachChild(node, visit);
|
|
650
|
+
};
|
|
651
|
+
visit(sourceFile);
|
|
652
|
+
return matches;
|
|
653
|
+
},
|
|
654
|
+
transform(sourceFile, matches) {
|
|
655
|
+
if (matches.length === 0) return sourceFile.getFullText();
|
|
656
|
+
let text = sourceFile.getFullText();
|
|
657
|
+
const targetTypesNeedingSkipInDev = [];
|
|
658
|
+
for (const match of matches) {
|
|
659
|
+
const prop = match.node;
|
|
660
|
+
const propName = prop.name.text;
|
|
661
|
+
if (prop.initializer.kind === ts.SyntaxKind.TrueKeyword) {
|
|
662
|
+
if (propName === "buildDist") targetTypesNeedingSkipInDev.push("dist", "dist-custom-elements", "dist-hydrate-script", "loader-bundle", "standalone", "ssr");
|
|
663
|
+
else if (propName === "buildDocs") targetTypesNeedingSkipInDev.push("docs-readme", "docs-json", "docs-custom", "docs-vscode", "docs-custom-elements-manifest");
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
const outputTargetsToModify = [];
|
|
667
|
+
const findOutputTargets = (node) => {
|
|
668
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === "outputTargets" && ts.isArrayLiteralExpression(node.initializer)) {
|
|
669
|
+
for (const element of node.initializer.elements) if (ts.isObjectLiteralExpression(element)) {
|
|
670
|
+
const typeProp = element.properties.find((p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === "type");
|
|
671
|
+
if (typeProp && ts.isStringLiteral(typeProp.initializer)) {
|
|
672
|
+
const targetType = typeProp.initializer.text;
|
|
673
|
+
if (targetTypesNeedingSkipInDev.includes(targetType)) {
|
|
674
|
+
if (!element.properties.some((p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === "skipInDev")) outputTargetsToModify.push(element);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
ts.forEachChild(node, findOutputTargets);
|
|
680
|
+
};
|
|
681
|
+
findOutputTargets(sourceFile);
|
|
682
|
+
const allModifications = [];
|
|
683
|
+
for (const match of matches) {
|
|
684
|
+
const prop = match.node;
|
|
685
|
+
const start = prop.getStart();
|
|
686
|
+
let end = prop.getEnd();
|
|
687
|
+
const afterProp = text.slice(end).match(/^\s*,/);
|
|
688
|
+
if (afterProp) end = end + afterProp[0].length;
|
|
689
|
+
allModifications.push({
|
|
690
|
+
type: "remove",
|
|
691
|
+
start,
|
|
692
|
+
end,
|
|
693
|
+
node: prop
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
for (const target of outputTargetsToModify) {
|
|
697
|
+
const lastProp = target.properties[target.properties.length - 1];
|
|
698
|
+
if (lastProp) allModifications.push({
|
|
699
|
+
type: "addSkipInDev",
|
|
700
|
+
start: lastProp.getEnd(),
|
|
701
|
+
end: lastProp.getEnd(),
|
|
702
|
+
node: target
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
allModifications.sort((a, b) => b.start - a.start);
|
|
706
|
+
for (const mod of allModifications) if (mod.type === "remove") text = text.slice(0, mod.start) + text.slice(mod.end);
|
|
707
|
+
else if (mod.type === "addSkipInDev") {
|
|
708
|
+
const firstProp = mod.node.properties[0];
|
|
709
|
+
let indent = " ";
|
|
710
|
+
if (firstProp) {
|
|
711
|
+
const propStart = firstProp.getStart();
|
|
712
|
+
const lineStart = text.lastIndexOf("\n", propStart) + 1;
|
|
713
|
+
const leadingWhitespace = text.slice(lineStart, propStart);
|
|
714
|
+
if (/^\s+$/.test(leadingWhitespace)) indent = leadingWhitespace;
|
|
715
|
+
}
|
|
716
|
+
const afterLastProp = text.slice(mod.start).match(/^(\s*,)?/);
|
|
717
|
+
const skipLength = afterLastProp && afterLastProp[1] ? afterLastProp[0].length : 0;
|
|
718
|
+
text = text.slice(0, mod.start) + `,\n${indent}skipInDev: false,` + text.slice(mod.start + skipLength);
|
|
719
|
+
}
|
|
720
|
+
text = text.replace(/,\s*\n\s*\n/g, ",\n");
|
|
721
|
+
text = text.replace(/{\s*\n\s*\n/g, "{\n");
|
|
722
|
+
return text;
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
//#endregion
|
|
726
|
+
//#region src/migrations/rules/dev-mode.ts
|
|
727
|
+
/**
|
|
728
|
+
* Migration rule for `devMode` config option removal.
|
|
729
|
+
*
|
|
730
|
+
* In Stencil v5, `devMode` is no longer a user-settable config option in `stencil.config.ts`.
|
|
731
|
+
* Build mode is controlled exclusively by the `--dev` CLI flag (default is production).
|
|
732
|
+
* This migration removes `devMode` from the config object.
|
|
733
|
+
*/
|
|
734
|
+
const devModeRule = {
|
|
735
|
+
id: "dev-mode",
|
|
736
|
+
name: "devMode Config Removal",
|
|
737
|
+
description: "Remove deprecated devMode config option - use --dev CLI flag instead",
|
|
738
|
+
fromVersion: "4.x",
|
|
739
|
+
toVersion: "5.x",
|
|
740
|
+
detect(sourceFile) {
|
|
741
|
+
const matches = [];
|
|
742
|
+
const visit = (node) => {
|
|
743
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name)) {
|
|
744
|
+
if (node.name.text === "devMode") {
|
|
745
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
746
|
+
matches.push({
|
|
747
|
+
node,
|
|
748
|
+
message: `Deprecated 'devMode' config option found - build mode is now set via the --dev CLI flag (production is the default)`,
|
|
749
|
+
line: line + 1,
|
|
750
|
+
column: character + 1
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
ts.forEachChild(node, visit);
|
|
755
|
+
};
|
|
756
|
+
visit(sourceFile);
|
|
757
|
+
return matches;
|
|
758
|
+
},
|
|
759
|
+
transform(sourceFile, matches) {
|
|
760
|
+
if (matches.length === 0) return sourceFile.getFullText();
|
|
761
|
+
let text = sourceFile.getFullText();
|
|
762
|
+
for (const match of [...matches].reverse()) {
|
|
763
|
+
const node = match.node;
|
|
764
|
+
const start = node.getFullStart();
|
|
765
|
+
const end = node.getEnd();
|
|
766
|
+
let removeEnd = end;
|
|
767
|
+
const trailingComma = text.slice(end).match(/^\s*,/);
|
|
768
|
+
if (trailingComma) removeEnd = end + trailingComma[0].length;
|
|
769
|
+
text = text.slice(0, start) + text.slice(removeEnd);
|
|
770
|
+
}
|
|
771
|
+
return text;
|
|
772
|
+
}
|
|
773
|
+
};
|
|
774
|
+
//#endregion
|
|
621
775
|
//#region src/migrations/rules/encapsulation-api.ts
|
|
622
776
|
/**
|
|
623
777
|
* Migration rule for the @Component encapsulation API change.
|
|
@@ -820,6 +974,376 @@ const formAssociatedRule = {
|
|
|
820
974
|
}
|
|
821
975
|
};
|
|
822
976
|
//#endregion
|
|
977
|
+
//#region src/migrations/rules/global-style-inject.ts
|
|
978
|
+
/**
|
|
979
|
+
* Migration rule for `extras.addGlobalStyleToComponents` → `global-style` output target `inject`.
|
|
980
|
+
*
|
|
981
|
+
* In v5, the `addGlobalStyleToComponents` extras option is removed. Instead, configure
|
|
982
|
+
* the `inject` option on the `global-style` output target.
|
|
983
|
+
*
|
|
984
|
+
* Migration mapping:
|
|
985
|
+
* - `addGlobalStyleToComponents: true` → `inject: 'all'`
|
|
986
|
+
* - `addGlobalStyleToComponents: 'client'` → `inject: 'client'`
|
|
987
|
+
* - `addGlobalStyleToComponents: false` → omit (default is 'none')
|
|
988
|
+
*
|
|
989
|
+
* Note: This migration only acts on explicitly set `addGlobalStyleToComponents`.
|
|
990
|
+
* Users who relied on the implicit v4 default ('client') will need to manually
|
|
991
|
+
* add `inject: 'client'` to their global-style output target if desired.
|
|
992
|
+
*/
|
|
993
|
+
const globalStyleInjectRule = {
|
|
994
|
+
id: "global-style-inject",
|
|
995
|
+
name: "Global Style Inject Migration",
|
|
996
|
+
description: "Migrate extras.addGlobalStyleToComponents to global-style output target inject option",
|
|
997
|
+
fromVersion: "4.x",
|
|
998
|
+
toVersion: "5.x",
|
|
999
|
+
detect(sourceFile) {
|
|
1000
|
+
const matches = [];
|
|
1001
|
+
const visit = (node) => {
|
|
1002
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === "addGlobalStyleToComponents") {
|
|
1003
|
+
const parent = node.parent;
|
|
1004
|
+
if (ts.isObjectLiteralExpression(parent)) {
|
|
1005
|
+
const grandparent = parent.parent;
|
|
1006
|
+
if (ts.isPropertyAssignment(grandparent) && ts.isIdentifier(grandparent.name) && grandparent.name.text === "extras") {
|
|
1007
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
1008
|
+
matches.push({
|
|
1009
|
+
node,
|
|
1010
|
+
message: `extras.addGlobalStyleToComponents is removed. Use 'inject' on global-style output target instead.`,
|
|
1011
|
+
line: line + 1,
|
|
1012
|
+
column: character + 1
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
ts.forEachChild(node, visit);
|
|
1018
|
+
};
|
|
1019
|
+
visit(sourceFile);
|
|
1020
|
+
return matches;
|
|
1021
|
+
},
|
|
1022
|
+
transform(sourceFile, matches) {
|
|
1023
|
+
if (matches.length === 0) return sourceFile.getFullText();
|
|
1024
|
+
let text = sourceFile.getFullText();
|
|
1025
|
+
const matchNode = matches[0].node;
|
|
1026
|
+
if (!ts.isPropertyAssignment(matchNode)) return text;
|
|
1027
|
+
let injectValue = null;
|
|
1028
|
+
if (matchNode.initializer.kind === ts.SyntaxKind.TrueKeyword) injectValue = "all";
|
|
1029
|
+
else if (ts.isStringLiteral(matchNode.initializer) && matchNode.initializer.text === "client") injectValue = "client";
|
|
1030
|
+
let insertionOffset = 0;
|
|
1031
|
+
if (injectValue) {
|
|
1032
|
+
const result = addGlobalStyleOutputTarget(text, sourceFile, injectValue);
|
|
1033
|
+
insertionOffset = result.length - text.length;
|
|
1034
|
+
text = result;
|
|
1035
|
+
}
|
|
1036
|
+
let start = matchNode.getStart();
|
|
1037
|
+
let end = matchNode.getEnd();
|
|
1038
|
+
const outputTargetsEnd = findOutputTargetsEnd(sourceFile);
|
|
1039
|
+
if (insertionOffset !== 0 && outputTargetsEnd !== null && matchNode.getStart() > outputTargetsEnd) {
|
|
1040
|
+
start += insertionOffset;
|
|
1041
|
+
end += insertionOffset;
|
|
1042
|
+
}
|
|
1043
|
+
const afterProp = text.slice(end).match(/^\s*,/);
|
|
1044
|
+
if (afterProp) end = end + afterProp[0].length;
|
|
1045
|
+
else {
|
|
1046
|
+
const beforeProp = text.slice(0, start).match(/,\s*$/);
|
|
1047
|
+
if (beforeProp) {
|
|
1048
|
+
text = text.slice(0, start - beforeProp[0].length) + text.slice(end);
|
|
1049
|
+
end = -1;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
if (end !== -1) text = text.slice(0, start) + text.slice(end);
|
|
1053
|
+
text = cleanupEmptyExtras(text);
|
|
1054
|
+
return text;
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
/**
|
|
1058
|
+
* Find the end position of the outputTargets array in the source file.
|
|
1059
|
+
* @param sourceFile The source file to search
|
|
1060
|
+
* @returns The end position of the outputTargets array, or null if not found
|
|
1061
|
+
*/
|
|
1062
|
+
function findOutputTargetsEnd(sourceFile) {
|
|
1063
|
+
let endPos = null;
|
|
1064
|
+
const visit = (node) => {
|
|
1065
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === "outputTargets") endPos = node.getEnd();
|
|
1066
|
+
ts.forEachChild(node, visit);
|
|
1067
|
+
};
|
|
1068
|
+
visit(sourceFile);
|
|
1069
|
+
return endPos;
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Clean up empty extras object after removing addGlobalStyleToComponents.
|
|
1073
|
+
* @param text The source text to clean up
|
|
1074
|
+
* @returns The cleaned up text with empty extras removed
|
|
1075
|
+
*/
|
|
1076
|
+
function cleanupEmptyExtras(text) {
|
|
1077
|
+
return text.replace(/,?\s*extras\s*:\s*\{\s*\},?/g, "");
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Add a global-style output target with the specified inject value.
|
|
1081
|
+
* @param text The source text to modify
|
|
1082
|
+
* @param sourceFile The source file for position info
|
|
1083
|
+
* @param injectValue The inject value to set on the new global-style output target
|
|
1084
|
+
* @returns The modified text with the new global-style output target added
|
|
1085
|
+
*/
|
|
1086
|
+
function addGlobalStyleOutputTarget(text, sourceFile, injectValue) {
|
|
1087
|
+
if (text.includes("type: 'global-style'")) return text;
|
|
1088
|
+
let outputTargetsArray = null;
|
|
1089
|
+
const findOutputTargets = (node) => {
|
|
1090
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === "outputTargets" && ts.isArrayLiteralExpression(node.initializer)) outputTargetsArray = node.initializer;
|
|
1091
|
+
ts.forEachChild(node, findOutputTargets);
|
|
1092
|
+
};
|
|
1093
|
+
findOutputTargets(sourceFile);
|
|
1094
|
+
if (!outputTargetsArray) return text;
|
|
1095
|
+
const array = outputTargetsArray;
|
|
1096
|
+
let indent = " ";
|
|
1097
|
+
if (array.elements.length > 0) {
|
|
1098
|
+
const elemStart = array.elements[0].getStart();
|
|
1099
|
+
const lineStart = text.lastIndexOf("\n", elemStart) + 1;
|
|
1100
|
+
const leadingWhitespace = text.slice(lineStart, elemStart);
|
|
1101
|
+
if (/^\s+$/.test(leadingWhitespace)) indent = leadingWhitespace;
|
|
1102
|
+
}
|
|
1103
|
+
const lastElement = array.elements[array.elements.length - 1];
|
|
1104
|
+
if (!lastElement) {
|
|
1105
|
+
const arrayStart = array.getStart() + 1;
|
|
1106
|
+
const newTarget = `\n${indent}{\n${indent} type: 'global-style',\n${indent} inject: '${injectValue}',\n${indent}}\n${indent.slice(2)}`;
|
|
1107
|
+
return text.slice(0, arrayStart) + newTarget + text.slice(arrayStart);
|
|
1108
|
+
}
|
|
1109
|
+
let insertPos = lastElement.getEnd();
|
|
1110
|
+
const afterLastElement = text.slice(insertPos).match(/^(\s*,)?/);
|
|
1111
|
+
const hasTrailingComma = afterLastElement && afterLastElement[1];
|
|
1112
|
+
if (hasTrailingComma) insertPos += afterLastElement[0].length;
|
|
1113
|
+
const newTarget = `{\n${indent} type: 'global-style',\n${indent} inject: '${injectValue}',\n${indent}}`;
|
|
1114
|
+
const insertion = (hasTrailingComma ? "" : ",") + "\n" + indent + newTarget;
|
|
1115
|
+
return text.slice(0, insertPos) + insertion + text.slice(insertPos);
|
|
1116
|
+
}
|
|
1117
|
+
//#endregion
|
|
1118
|
+
//#region src/migrations/rules/output-target-renames.ts
|
|
1119
|
+
/**
|
|
1120
|
+
* Migration rule for output target renames in Stencil v5.
|
|
1121
|
+
*
|
|
1122
|
+
* This migration:
|
|
1123
|
+
* - Renames `dist` → `loader-bundle`
|
|
1124
|
+
* - Renames `dist-custom-elements` → `standalone`
|
|
1125
|
+
* - Renames `dist-hydrate-script` → `ssr`
|
|
1126
|
+
* - Renames `dist-collection` → `stencil-rebundle`
|
|
1127
|
+
* - Renames `dist-types` → `types`
|
|
1128
|
+
* - Extracts `collectionDir` from loader-bundle into separate `stencil-rebundle` output
|
|
1129
|
+
* - Extracts `typesDir` from loader-bundle into separate `types` output
|
|
1130
|
+
* - Renames `esmLoaderPath` → `loaderPath` (applies to all module formats, not just ESM)
|
|
1131
|
+
* - Removes `isPrimaryPackageOutputTarget` (no longer needed, package.json validation auto-detects)
|
|
1132
|
+
* - Removes `generateTypeDeclarations` (types are now auto-generated via the `types` output target)
|
|
1133
|
+
*/
|
|
1134
|
+
const outputTargetRenamesRule = {
|
|
1135
|
+
id: "output-target-renames",
|
|
1136
|
+
name: "Output Target Renames",
|
|
1137
|
+
description: "Rename output targets to new v5 names",
|
|
1138
|
+
fromVersion: "4.x",
|
|
1139
|
+
toVersion: "5.x",
|
|
1140
|
+
detect(sourceFile) {
|
|
1141
|
+
const matches = [];
|
|
1142
|
+
const oldToNewNames = {
|
|
1143
|
+
dist: "loader-bundle",
|
|
1144
|
+
"dist-custom-elements": "standalone",
|
|
1145
|
+
"dist-hydrate-script": "ssr",
|
|
1146
|
+
"dist-collection": "stencil-rebundle",
|
|
1147
|
+
"dist-types": "types"
|
|
1148
|
+
};
|
|
1149
|
+
const visit = (node) => {
|
|
1150
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === "type" && ts.isStringLiteral(node.initializer)) {
|
|
1151
|
+
const typeValue = node.initializer.text;
|
|
1152
|
+
if (typeValue in oldToNewNames) {
|
|
1153
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
1154
|
+
matches.push({
|
|
1155
|
+
node,
|
|
1156
|
+
message: `Output target type '${typeValue}' → '${oldToNewNames[typeValue]}'`,
|
|
1157
|
+
line: line + 1,
|
|
1158
|
+
column: character + 1
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && (node.name.text === "collectionDir" || node.name.text === "typesDir")) {
|
|
1163
|
+
const parent = node.parent;
|
|
1164
|
+
if (ts.isObjectLiteralExpression(parent)) {
|
|
1165
|
+
if (parent.properties.some((p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === "type")) {
|
|
1166
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
1167
|
+
const propName = node.name.text;
|
|
1168
|
+
const newType = propName === "collectionDir" ? "stencil-rebundle" : "types";
|
|
1169
|
+
matches.push({
|
|
1170
|
+
node,
|
|
1171
|
+
message: `Property '${propName}' will be extracted to separate '${newType}' output target`,
|
|
1172
|
+
line: line + 1,
|
|
1173
|
+
column: character + 1
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === "esmLoaderPath") {
|
|
1179
|
+
const parent = node.parent;
|
|
1180
|
+
if (ts.isObjectLiteralExpression(parent)) {
|
|
1181
|
+
if (parent.properties.some((p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === "type")) {
|
|
1182
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
1183
|
+
matches.push({
|
|
1184
|
+
node,
|
|
1185
|
+
message: `Property 'esmLoaderPath' renamed to 'loaderPath' (applies to all module formats)`,
|
|
1186
|
+
line: line + 1,
|
|
1187
|
+
column: character + 1
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && (node.name.text === "isPrimaryPackageOutputTarget" || node.name.text === "generateTypeDeclarations")) {
|
|
1193
|
+
const parent = node.parent;
|
|
1194
|
+
if (ts.isObjectLiteralExpression(parent)) {
|
|
1195
|
+
if (parent.properties.some((p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === "type")) {
|
|
1196
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
1197
|
+
const propName = node.name.text;
|
|
1198
|
+
const reason = propName === "isPrimaryPackageOutputTarget" ? "Package.json validation now auto-detects based on configured outputs" : "Types are now auto-generated via the 'types' output target";
|
|
1199
|
+
matches.push({
|
|
1200
|
+
node,
|
|
1201
|
+
message: `Property '${propName}' is removed in v5. ${reason}`,
|
|
1202
|
+
line: line + 1,
|
|
1203
|
+
column: character + 1
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
ts.forEachChild(node, visit);
|
|
1209
|
+
};
|
|
1210
|
+
visit(sourceFile);
|
|
1211
|
+
return matches;
|
|
1212
|
+
},
|
|
1213
|
+
transform(sourceFile, matches) {
|
|
1214
|
+
if (matches.length === 0) return sourceFile.getFullText();
|
|
1215
|
+
let text = sourceFile.getFullText();
|
|
1216
|
+
const oldToNewNames = {
|
|
1217
|
+
dist: "loader-bundle",
|
|
1218
|
+
"dist-custom-elements": "standalone",
|
|
1219
|
+
"dist-hydrate-script": "ssr",
|
|
1220
|
+
"dist-collection": "stencil-rebundle",
|
|
1221
|
+
"dist-types": "types"
|
|
1222
|
+
};
|
|
1223
|
+
const outputTargetsToExtract = [];
|
|
1224
|
+
const findOutputTargetsToExtract = (node) => {
|
|
1225
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === "outputTargets" && ts.isArrayLiteralExpression(node.initializer)) {
|
|
1226
|
+
for (const element of node.initializer.elements) if (ts.isObjectLiteralExpression(element)) {
|
|
1227
|
+
let collectionDir;
|
|
1228
|
+
let typesDir;
|
|
1229
|
+
for (const prop of element.properties) if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
|
1230
|
+
if (prop.name.text === "collectionDir" && ts.isStringLiteral(prop.initializer)) collectionDir = prop.initializer.text;
|
|
1231
|
+
else if (prop.name.text === "typesDir" && ts.isStringLiteral(prop.initializer)) typesDir = prop.initializer.text;
|
|
1232
|
+
}
|
|
1233
|
+
if (collectionDir || typesDir) outputTargetsToExtract.push({
|
|
1234
|
+
targetNode: element,
|
|
1235
|
+
collectionDir,
|
|
1236
|
+
typesDir
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
ts.forEachChild(node, findOutputTargetsToExtract);
|
|
1241
|
+
};
|
|
1242
|
+
findOutputTargetsToExtract(sourceFile);
|
|
1243
|
+
const modifications = [];
|
|
1244
|
+
for (const match of matches) {
|
|
1245
|
+
const prop = match.node;
|
|
1246
|
+
const propName = prop.name.text;
|
|
1247
|
+
if (propName === "type" && ts.isStringLiteral(prop.initializer)) {
|
|
1248
|
+
const newType = oldToNewNames[prop.initializer.text];
|
|
1249
|
+
if (newType) {
|
|
1250
|
+
const start = prop.initializer.getStart() + 1;
|
|
1251
|
+
const end = prop.initializer.getEnd() - 1;
|
|
1252
|
+
modifications.push({
|
|
1253
|
+
type: "replace",
|
|
1254
|
+
start,
|
|
1255
|
+
end,
|
|
1256
|
+
replacement: newType
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
} else if (propName === "esmLoaderPath") {
|
|
1260
|
+
const nameNode = prop.name;
|
|
1261
|
+
modifications.push({
|
|
1262
|
+
type: "replace",
|
|
1263
|
+
start: nameNode.getStart(),
|
|
1264
|
+
end: nameNode.getEnd(),
|
|
1265
|
+
replacement: "loaderPath"
|
|
1266
|
+
});
|
|
1267
|
+
if (ts.isStringLiteral(prop.initializer)) {
|
|
1268
|
+
const newPath = "../" + prop.initializer.text;
|
|
1269
|
+
modifications.push({
|
|
1270
|
+
type: "replace",
|
|
1271
|
+
start: prop.initializer.getStart() + 1,
|
|
1272
|
+
end: prop.initializer.getEnd() - 1,
|
|
1273
|
+
replacement: newPath
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
} else if (propName === "collectionDir" || propName === "typesDir" || propName === "isPrimaryPackageOutputTarget" || propName === "generateTypeDeclarations") {
|
|
1277
|
+
const start = prop.getStart();
|
|
1278
|
+
let end = prop.getEnd();
|
|
1279
|
+
const beforeProp = text.slice(0, start).match(/,\s*$/);
|
|
1280
|
+
const afterProp = text.slice(end).match(/^\s*,/);
|
|
1281
|
+
if (afterProp) end = end + afterProp[0].length;
|
|
1282
|
+
else if (beforeProp) {
|
|
1283
|
+
const commaStart = start - beforeProp[0].length;
|
|
1284
|
+
modifications.push({
|
|
1285
|
+
type: "remove",
|
|
1286
|
+
start: commaStart,
|
|
1287
|
+
end
|
|
1288
|
+
});
|
|
1289
|
+
continue;
|
|
1290
|
+
}
|
|
1291
|
+
modifications.push({
|
|
1292
|
+
type: "remove",
|
|
1293
|
+
start,
|
|
1294
|
+
end
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
modifications.sort((a, b) => b.start - a.start);
|
|
1299
|
+
for (const mod of modifications) if (mod.type === "replace") text = text.slice(0, mod.start) + mod.replacement + text.slice(mod.end);
|
|
1300
|
+
else if (mod.type === "remove") text = text.slice(0, mod.start) + text.slice(mod.end);
|
|
1301
|
+
if (outputTargetsToExtract.length > 0) text = addExtractedOutputTargets(text, sourceFile, outputTargetsToExtract);
|
|
1302
|
+
text = text.replace(/,\s*\n\s*\n/g, ",\n");
|
|
1303
|
+
text = text.replace(/{\s*\n\s*\n/g, "{\n");
|
|
1304
|
+
text = text.replace(/,\s*,/g, ",");
|
|
1305
|
+
return text;
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
/**
|
|
1309
|
+
* Add new output targets for extracted collectionDir and typesDir.
|
|
1310
|
+
* @param text The original source text
|
|
1311
|
+
* @param sourceFile The TypeScript source file object
|
|
1312
|
+
* @param toExtract An array of objects containing the output target nodes and their collectionDir/typesDir values to extract
|
|
1313
|
+
* @returns The modified source text with new output targets added
|
|
1314
|
+
*/
|
|
1315
|
+
function addExtractedOutputTargets(text, sourceFile, toExtract) {
|
|
1316
|
+
let outputTargetsArray = null;
|
|
1317
|
+
const findOutputTargets = (node) => {
|
|
1318
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === "outputTargets" && ts.isArrayLiteralExpression(node.initializer)) outputTargetsArray = node.initializer;
|
|
1319
|
+
ts.forEachChild(node, findOutputTargets);
|
|
1320
|
+
};
|
|
1321
|
+
findOutputTargets(sourceFile);
|
|
1322
|
+
if (!outputTargetsArray || toExtract.length === 0) return text;
|
|
1323
|
+
const array = outputTargetsArray;
|
|
1324
|
+
let indent = " ";
|
|
1325
|
+
if (array.elements.length > 0) {
|
|
1326
|
+
const elemStart = array.elements[0].getStart();
|
|
1327
|
+
const lineStart = text.lastIndexOf("\n", elemStart) + 1;
|
|
1328
|
+
const leadingWhitespace = text.slice(lineStart, elemStart);
|
|
1329
|
+
if (/^\s+$/.test(leadingWhitespace)) indent = leadingWhitespace;
|
|
1330
|
+
}
|
|
1331
|
+
const lastElement = array.elements[array.elements.length - 1];
|
|
1332
|
+
if (!lastElement) return text;
|
|
1333
|
+
let insertPos = lastElement.getEnd();
|
|
1334
|
+
const afterLastElement = text.slice(insertPos).match(/^(\s*,)?/);
|
|
1335
|
+
if (afterLastElement && afterLastElement[1]) insertPos += afterLastElement[0].length;
|
|
1336
|
+
const newTargets = [];
|
|
1337
|
+
for (const extracted of toExtract) {
|
|
1338
|
+
if (extracted.collectionDir) newTargets.push(`{\n${indent} type: 'stencil-rebundle',\n${indent} dir: '${extracted.collectionDir}',\n${indent}}`);
|
|
1339
|
+
if (extracted.typesDir) newTargets.push(`{\n${indent} type: 'types',\n${indent} dir: '${extracted.typesDir}',\n${indent}}`);
|
|
1340
|
+
}
|
|
1341
|
+
if (newTargets.length === 0) return text;
|
|
1342
|
+
const insertion = ",\n" + newTargets.map((t) => `${indent}${t}`).join(",\n");
|
|
1343
|
+
text = text.slice(0, insertPos) + insertion + text.slice(insertPos);
|
|
1344
|
+
return text;
|
|
1345
|
+
}
|
|
1346
|
+
//#endregion
|
|
823
1347
|
//#region src/migrations/index.ts
|
|
824
1348
|
/**
|
|
825
1349
|
* Build a map of local import names to their original names from @stencil/core.
|
|
@@ -857,7 +1381,14 @@ const isStencilDecorator = (decoratorName, expectedOriginalName, importMap) => {
|
|
|
857
1381
|
* Registry of all available migration rules.
|
|
858
1382
|
* Rules are applied in order, so add new rules at the end.
|
|
859
1383
|
*/
|
|
860
|
-
const migrationRules = [
|
|
1384
|
+
const migrationRules = [
|
|
1385
|
+
encapsulationApiRule,
|
|
1386
|
+
formAssociatedRule,
|
|
1387
|
+
buildDistDocsRule,
|
|
1388
|
+
outputTargetRenamesRule,
|
|
1389
|
+
devModeRule,
|
|
1390
|
+
globalStyleInjectRule
|
|
1391
|
+
];
|
|
861
1392
|
/**
|
|
862
1393
|
* Get all migration rules for a specific version upgrade.
|
|
863
1394
|
* @param fromVersion Source version (e.g., '4')
|
|
@@ -1041,27 +1572,32 @@ async function getTypeScriptFiles(config, sys, logger) {
|
|
|
1041
1572
|
return [];
|
|
1042
1573
|
}
|
|
1043
1574
|
if (results.errors && results.errors.length > 0) for (const err of results.errors) logger.warn(ts.flattenDiagnosticMessageText(err.messageText, "\n"));
|
|
1044
|
-
|
|
1575
|
+
const files = results.fileNames.filter((f) => (f.endsWith(".ts") || f.endsWith(".tsx")) && !f.endsWith(".d.ts"));
|
|
1576
|
+
const configFile = config.configPath;
|
|
1577
|
+
if (configFile && (configFile.endsWith(".ts") || configFile.endsWith(".mts"))) {
|
|
1578
|
+
if (!files.includes(configFile)) files.push(configFile);
|
|
1579
|
+
}
|
|
1580
|
+
return files;
|
|
1045
1581
|
}
|
|
1046
1582
|
//#endregion
|
|
1047
1583
|
//#region src/task-prerender.ts
|
|
1048
1584
|
const taskPrerender = async (coreCompiler, config, flags) => {
|
|
1049
1585
|
startupCompilerLog(coreCompiler, config);
|
|
1050
|
-
const
|
|
1051
|
-
if (typeof
|
|
1586
|
+
const ssrAppFilePath = flags.unknownArgs[0];
|
|
1587
|
+
if (typeof ssrAppFilePath !== "string") {
|
|
1052
1588
|
config.logger.error(`Missing hydrate app script path`);
|
|
1053
1589
|
return config.sys.exit(1);
|
|
1054
1590
|
}
|
|
1055
1591
|
const srcIndexHtmlPath = config.srcIndexHtml;
|
|
1056
|
-
const diagnostics = await runPrerenderTask(coreCompiler, config,
|
|
1592
|
+
const diagnostics = await runPrerenderTask(coreCompiler, config, ssrAppFilePath, void 0, srcIndexHtmlPath);
|
|
1057
1593
|
config.logger.printDiagnostics(diagnostics);
|
|
1058
1594
|
if (diagnostics.some((d) => d.level === "error")) return config.sys.exit(1);
|
|
1059
1595
|
};
|
|
1060
|
-
const runPrerenderTask = async (coreCompiler, config,
|
|
1596
|
+
const runPrerenderTask = async (coreCompiler, config, ssrAppFilePath, componentGraph, srcIndexHtmlPath) => {
|
|
1061
1597
|
const diagnostics = [];
|
|
1062
1598
|
try {
|
|
1063
1599
|
const results = await (await coreCompiler.createPrerenderer(config)).start({
|
|
1064
|
-
|
|
1600
|
+
ssrAppFilePath,
|
|
1065
1601
|
componentGraph,
|
|
1066
1602
|
srcIndexHtmlPath
|
|
1067
1603
|
});
|
|
@@ -1393,7 +1929,7 @@ const anonymizeConfigForTelemetry = (config) => {
|
|
|
1393
1929
|
if (OUTPUT_TARGET_KEYS_TO_KEEP.includes(key)) return value;
|
|
1394
1930
|
return "omitted";
|
|
1395
1931
|
}));
|
|
1396
|
-
if (
|
|
1932
|
+
if (isOutputTargetSsr(target) && target.external) anonymizedOT["external"] = target.external.concat();
|
|
1397
1933
|
return anonymizedOT;
|
|
1398
1934
|
});
|
|
1399
1935
|
for (const prop of CONFIG_PROPS_TO_DELETE) delete anonymizedConfig[prop];
|
|
@@ -1587,6 +2123,23 @@ const taskBuild = async (coreCompiler, config, flags) => {
|
|
|
1587
2123
|
let exitCode = 0;
|
|
1588
2124
|
try {
|
|
1589
2125
|
startupCompilerLog(coreCompiler, config);
|
|
2126
|
+
const preBuildMigrationResult = await detectMigrations(coreCompiler, config);
|
|
2127
|
+
if (preBuildMigrationResult.hasMigrations) {
|
|
2128
|
+
const action = await promptForMigration(config, preBuildMigrationResult, "pre-build");
|
|
2129
|
+
if (action === "run") {
|
|
2130
|
+
await taskMigrate(coreCompiler, config, {
|
|
2131
|
+
...flags,
|
|
2132
|
+
dryRun: false
|
|
2133
|
+
});
|
|
2134
|
+
config.logger.info("\nMigrations applied. Starting build...\n");
|
|
2135
|
+
} else if (action === "dry-run") {
|
|
2136
|
+
await taskMigrate(coreCompiler, config, {
|
|
2137
|
+
...flags,
|
|
2138
|
+
dryRun: true
|
|
2139
|
+
});
|
|
2140
|
+
return config.sys.exit(1);
|
|
2141
|
+
} else return config.sys.exit(1);
|
|
2142
|
+
}
|
|
1590
2143
|
const versionChecker = startCheckVersion(config, coreCompiler.version, flags);
|
|
1591
2144
|
const compiler = await coreCompiler.createCompiler(config);
|
|
1592
2145
|
const results = await compiler.build();
|
|
@@ -1595,7 +2148,7 @@ const taskBuild = async (coreCompiler, config, flags) => {
|
|
|
1595
2148
|
if (results.hasError) {
|
|
1596
2149
|
const migrationResult = await detectMigrations(coreCompiler, config);
|
|
1597
2150
|
if (migrationResult.hasMigrations) {
|
|
1598
|
-
const action = await
|
|
2151
|
+
const action = await promptForMigration(config, migrationResult, "post-error");
|
|
1599
2152
|
if (action === "run") {
|
|
1600
2153
|
await taskMigrate(coreCompiler, config, {
|
|
1601
2154
|
...flags,
|
|
@@ -1608,7 +2161,7 @@ const taskBuild = async (coreCompiler, config, flags) => {
|
|
|
1608
2161
|
if (!newResults.hasError) {
|
|
1609
2162
|
exitCode = 0;
|
|
1610
2163
|
if (flags.prerender) {
|
|
1611
|
-
const prerenderDiagnostics = await runPrerenderTask(coreCompiler, config, newResults.
|
|
2164
|
+
const prerenderDiagnostics = await runPrerenderTask(coreCompiler, config, newResults.ssrAppFilePath, newResults.componentGraph, void 0);
|
|
1612
2165
|
config.logger.printDiagnostics(prerenderDiagnostics);
|
|
1613
2166
|
if (prerenderDiagnostics.some((d) => d.level === "error")) exitCode = 1;
|
|
1614
2167
|
}
|
|
@@ -1622,7 +2175,7 @@ const taskBuild = async (coreCompiler, config, flags) => {
|
|
|
1622
2175
|
} else exitCode = 1;
|
|
1623
2176
|
} else exitCode = 1;
|
|
1624
2177
|
} else if (flags.prerender) {
|
|
1625
|
-
const prerenderDiagnostics = await runPrerenderTask(coreCompiler, config, results.
|
|
2178
|
+
const prerenderDiagnostics = await runPrerenderTask(coreCompiler, config, results.ssrAppFilePath, results.componentGraph, void 0);
|
|
1626
2179
|
config.logger.printDiagnostics(prerenderDiagnostics);
|
|
1627
2180
|
if (prerenderDiagnostics.some((d) => d.level === "error")) exitCode = 1;
|
|
1628
2181
|
}
|
|
@@ -1634,24 +2187,26 @@ const taskBuild = async (coreCompiler, config, flags) => {
|
|
|
1634
2187
|
if (exitCode > 0) return config.sys.exit(exitCode);
|
|
1635
2188
|
};
|
|
1636
2189
|
/**
|
|
1637
|
-
* Prompt the user about available migrations
|
|
2190
|
+
* Prompt the user about available migrations.
|
|
1638
2191
|
* Shows what migrations are available and lets them choose to run them.
|
|
1639
2192
|
* @param config the Stencil config
|
|
1640
2193
|
* @param migrationResult the result of migration detection with available migrations
|
|
2194
|
+
* @param context whether this is a pre-build check or post-error check
|
|
1641
2195
|
* @returns the user's chosen action for handling migrations
|
|
1642
2196
|
*/
|
|
1643
|
-
async function
|
|
2197
|
+
async function promptForMigration(config, migrationResult, context) {
|
|
1644
2198
|
const logger = config.logger;
|
|
1645
2199
|
logger.info("");
|
|
1646
|
-
logger.info(logger.bold(logger.yellow("Migrations
|
|
2200
|
+
logger.info(logger.bold(logger.yellow("Migrations Required")));
|
|
1647
2201
|
logger.info("─".repeat(40));
|
|
1648
|
-
logger.info(`Found ${migrationResult.totalMatches} item(s) in ${migrationResult.filesAffected} file(s) that
|
|
2202
|
+
logger.info(`Found ${migrationResult.totalMatches} item(s) in ${migrationResult.filesAffected} file(s) that need to be migrated for Stencil v5.`);
|
|
1649
2203
|
for (const migration of migrationResult.migrations) {
|
|
1650
2204
|
const relPath = relative(config.rootDir, migration.filePath);
|
|
1651
2205
|
logger.info(` ${logger.cyan(relPath)}: ${migration.matches.length} item(s)`);
|
|
1652
2206
|
}
|
|
1653
2207
|
logger.info("");
|
|
1654
|
-
logger.info("
|
|
2208
|
+
if (context === "pre-build") logger.info("Your config contains deprecated options that must be migrated before building.");
|
|
2209
|
+
else logger.info("These migrations may help resolve the build errors above.");
|
|
1655
2210
|
const prompt = (await import("prompts")).default;
|
|
1656
2211
|
const response = await prompt({
|
|
1657
2212
|
name: "action",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stencil/cli",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.5",
|
|
4
4
|
"description": "CLI for Stencil - Web component compiler",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"components",
|
|
@@ -38,14 +38,14 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"prompts": "^2.4.2",
|
|
41
|
-
"@stencil/dev-server": "5.0.0-alpha.
|
|
41
|
+
"@stencil/dev-server": "5.0.0-alpha.5"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/prompts": "^2.4.9",
|
|
45
|
-
"tsdown": "^0.21.
|
|
46
|
-
"typescript": "
|
|
45
|
+
"tsdown": "^0.21.7",
|
|
46
|
+
"typescript": ">4.0.0",
|
|
47
47
|
"vitest": "^4.1.1",
|
|
48
|
-
"@stencil/core": "5.0.0-alpha.
|
|
48
|
+
"@stencil/core": "5.0.0-alpha.5"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"@stencil/core": "^5.0.0-0"
|