@tramvai/cli 5.53.81 → 5.53.111
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/README.md +1 -1
- package/bin/const.js +5 -0
- package/bin/platform.js +12 -6
- package/bin/spawn.js +6 -0
- package/lib/api/analyze/index.d.ts.map +1 -1
- package/lib/api/analyze/index.js +1 -13
- package/lib/api/analyze/index.js.map +1 -1
- package/lib/api/benchmark/build.d.ts +1 -6
- package/lib/api/benchmark/build.d.ts.map +1 -1
- package/lib/api/benchmark/build.js +59 -23
- package/lib/api/benchmark/build.js.map +1 -1
- package/lib/api/benchmark/const.d.ts +2 -0
- package/lib/api/benchmark/const.d.ts.map +1 -0
- package/lib/api/benchmark/const.js +5 -0
- package/lib/api/benchmark/const.js.map +1 -0
- package/lib/api/benchmark/index.d.ts +4 -6
- package/lib/api/benchmark/index.d.ts.map +1 -1
- package/lib/api/benchmark/index.js.map +1 -1
- package/lib/api/benchmark/start.d.ts +1 -7
- package/lib/api/benchmark/start.d.ts.map +1 -1
- package/lib/api/benchmark/start.js +56 -49
- package/lib/api/benchmark/start.js.map +1 -1
- package/lib/api/benchmark/types.d.ts +76 -12
- package/lib/api/benchmark/types.d.ts.map +1 -1
- package/lib/api/benchmark/utils/compilationUtils.d.ts +4 -0
- package/lib/api/benchmark/utils/compilationUtils.d.ts.map +1 -0
- package/lib/api/benchmark/utils/compilationUtils.js +157 -0
- package/lib/api/benchmark/utils/compilationUtils.js.map +1 -0
- package/lib/api/benchmark/utils/stats.d.ts +2 -7
- package/lib/api/benchmark/utils/stats.d.ts.map +1 -1
- package/lib/api/benchmark/utils/stats.js +36 -22
- package/lib/api/benchmark/utils/stats.js.map +1 -1
- package/lib/api/build/index.d.ts +1 -0
- package/lib/api/build/index.d.ts.map +1 -1
- package/lib/api/build/index.js.map +1 -1
- package/lib/api/index.js +1 -1
- package/lib/api/index.js.map +1 -1
- package/lib/api/start/index.d.ts +1 -0
- package/lib/api/start/index.d.ts.map +1 -1
- package/lib/api/start/index.js.map +1 -1
- package/lib/builder/webpack/analyzePlugins/rsdoctor.d.ts +5 -5
- package/lib/builder/webpack/analyzePlugins/rsdoctor.d.ts.map +1 -1
- package/lib/builder/webpack/analyzePlugins/rsdoctor.js +7 -9
- package/lib/builder/webpack/analyzePlugins/rsdoctor.js.map +1 -1
- package/lib/builder/webpack/index.d.ts.map +1 -1
- package/lib/builder/webpack/index.js +14 -12
- package/lib/builder/webpack/index.js.map +1 -1
- package/lib/builder/webpack/providers/build/client.d.ts.map +1 -1
- package/lib/builder/webpack/providers/build/client.js +3 -2
- package/lib/builder/webpack/providers/build/client.js.map +1 -1
- package/lib/builder/webpack/providers/build/server.d.ts.map +1 -1
- package/lib/builder/webpack/providers/build/server.js +3 -2
- package/lib/builder/webpack/providers/build/server.js.map +1 -1
- package/lib/builder/webpack/providers/shared.d.ts.map +1 -1
- package/lib/builder/webpack/providers/shared.js +39 -5
- package/lib/builder/webpack/providers/shared.js.map +1 -1
- package/lib/builder/webpack/providers/start/shared.d.ts.map +1 -1
- package/lib/builder/webpack/providers/start/shared.js +6 -2
- package/lib/builder/webpack/providers/start/shared.js.map +1 -1
- package/lib/builder/webpack/tokens.d.ts +10 -16
- package/lib/builder/webpack/tokens.d.ts.map +1 -1
- package/lib/cli/index.d.ts.map +1 -1
- package/lib/cli/index.js +12 -12
- package/lib/cli/index.js.map +1 -1
- package/lib/commands/analyze/command.d.ts +1 -1
- package/lib/commands/analyze/command.d.ts.map +1 -1
- package/lib/commands/benchmark/benchmark.d.ts +3 -1
- package/lib/commands/benchmark/benchmark.d.ts.map +1 -1
- package/lib/commands/benchmark/benchmark.js +130 -31
- package/lib/commands/benchmark/benchmark.js.map +1 -1
- package/lib/commands/benchmark/command.d.ts +9 -0
- package/lib/commands/benchmark/command.d.ts.map +1 -1
- package/lib/commands/benchmark/command.js +12 -0
- package/lib/commands/benchmark/command.js.map +1 -1
- package/lib/commands/build/command.d.ts.map +1 -1
- package/lib/commands/build/command.js +5 -0
- package/lib/commands/build/command.js.map +1 -1
- package/lib/commands/start/command.d.ts.map +1 -1
- package/lib/commands/start/command.js +5 -0
- package/lib/commands/start/command.js.map +1 -1
- package/lib/commands/update/checkVersionValidator.d.ts +1 -1
- package/lib/commands/update/checkVersionValidator.d.ts.map +1 -1
- package/lib/commands/update/checkVersionValidator.js +3 -2
- package/lib/commands/update/checkVersionValidator.js.map +1 -1
- package/lib/commands/update/command.d.ts +1 -1
- package/lib/commands/update/dependantLibs.d.ts +1 -1
- package/lib/commands/update/dependantLibs.d.ts.map +1 -1
- package/lib/commands/update/dependantLibs.js +3 -2
- package/lib/commands/update/dependantLibs.js.map +1 -1
- package/lib/commands/update/update.d.ts.map +1 -1
- package/lib/commands/update/update.js +6 -3
- package/lib/commands/update/update.js.map +1 -1
- package/lib/commands/update/updatePackageJson.d.ts +1 -1
- package/lib/commands/update/updatePackageJson.d.ts.map +1 -1
- package/lib/commands/update/updatePackageJson.js +7 -7
- package/lib/commands/update/updatePackageJson.js.map +1 -1
- package/lib/config/configManager.d.ts +2 -0
- package/lib/config/configManager.d.ts.map +1 -1
- package/lib/config/configManager.js +2 -0
- package/lib/config/configManager.js.map +1 -1
- package/lib/di/tokens/config.d.ts +5 -8
- package/lib/di/tokens/config.d.ts.map +1 -1
- package/lib/library/webpack/blocks/css.d.ts.map +1 -1
- package/lib/library/webpack/blocks/css.js +42 -15
- package/lib/library/webpack/blocks/css.js.map +1 -1
- package/lib/library/webpack/blocks/js.d.ts.map +1 -1
- package/lib/library/webpack/blocks/js.js +57 -11
- package/lib/library/webpack/blocks/js.js.map +1 -1
- package/lib/library/webpack/common/main.d.ts.map +1 -1
- package/lib/library/webpack/common/main.js +7 -0
- package/lib/library/webpack/common/main.js.map +1 -1
- package/lib/library/webpack/utils/browserslist.d.ts +4 -0
- package/lib/library/webpack/utils/browserslist.d.ts.map +1 -0
- package/lib/library/webpack/utils/browserslist.js +27 -0
- package/lib/library/webpack/utils/browserslist.js.map +1 -0
- package/lib/library/webpack/utils/rsdoctor.d.ts +2 -0
- package/lib/library/webpack/utils/rsdoctor.d.ts.map +1 -0
- package/lib/library/webpack/utils/rsdoctor.js +27 -0
- package/lib/library/webpack/utils/rsdoctor.js.map +1 -0
- package/lib/library/webpack/utils/threadLoader.d.ts.map +1 -1
- package/lib/library/webpack/utils/threadLoader.js +3 -3
- package/lib/library/webpack/utils/threadLoader.js.map +1 -1
- package/lib/library/webpack/utils/transpiler.d.ts.map +1 -1
- package/lib/library/webpack/utils/transpiler.js +3 -16
- package/lib/library/webpack/utils/transpiler.js.map +1 -1
- package/lib/schema/autogeneratedSchema.json +240 -120
- package/lib/typings/build/Builder.d.ts +6 -2
- package/lib/typings/build/Builder.d.ts.map +1 -1
- package/lib/typings/configEntry/cli.d.ts +9 -0
- package/lib/typings/configEntry/cli.d.ts.map +1 -1
- package/lib/utils/commands/dependencies/getLatestPackageVersion.d.ts +1 -1
- package/lib/utils/commands/dependencies/getLatestPackageVersion.d.ts.map +1 -1
- package/lib/utils/commands/dependencies/getLatestPackageVersion.js +4 -2
- package/lib/utils/commands/dependencies/getLatestPackageVersion.js.map +1 -1
- package/lib/utils/commands/dependencies/packageHasVersion.d.ts +1 -1
- package/lib/utils/commands/dependencies/packageHasVersion.d.ts.map +1 -1
- package/lib/utils/commands/dependencies/packageHasVersion.js +3 -2
- package/lib/utils/commands/dependencies/packageHasVersion.js.map +1 -1
- package/package.json +19 -18
- package/schema.json +240 -120
- package/src/api/analyze/index.ts +3 -16
- package/src/api/benchmark/__integration__/start.test.ts +10 -12
- package/src/api/benchmark/build.ts +75 -30
- package/src/api/benchmark/const.ts +1 -0
- package/src/api/benchmark/index.ts +4 -6
- package/src/api/benchmark/start.ts +69 -65
- package/src/api/benchmark/types.ts +82 -14
- package/src/api/benchmark/utils/compilationUtils.ts +213 -0
- package/src/api/benchmark/utils/stats.ts +45 -28
- package/src/api/build/index.ts +1 -0
- package/src/api/index.ts +1 -1
- package/src/api/start/index.ts +1 -0
- package/src/builder/webpack/analyzePlugins/rsdoctor.ts +11 -14
- package/src/builder/webpack/index.ts +16 -21
- package/src/builder/webpack/providers/build/client.ts +7 -2
- package/src/builder/webpack/providers/build/server.ts +7 -2
- package/src/builder/webpack/providers/shared.ts +53 -5
- package/src/builder/webpack/providers/start/shared.ts +7 -2
- package/src/cli/index.ts +3 -2
- package/src/commands/analyze/command.ts +1 -1
- package/src/commands/benchmark/benchmark.ts +168 -33
- package/src/commands/benchmark/command.ts +12 -0
- package/src/commands/build/command.ts +6 -0
- package/src/commands/new/templates/shared/package.json.hbs +1 -1
- package/src/commands/start/command.ts +6 -0
- package/src/commands/update/checkVersionValidator.ts +4 -2
- package/src/commands/update/dependantLibs.ts +3 -1
- package/src/commands/update/update.ts +6 -3
- package/src/commands/update/updatePackageJson.spec.ts +19 -3
- package/src/commands/update/updatePackageJson.ts +7 -2
- package/src/config/configManager.ts +4 -0
- package/src/library/webpack/blocks/css.ts +52 -16
- package/src/library/webpack/blocks/js.ts +61 -12
- package/src/library/webpack/common/main.ts +8 -0
- package/src/library/webpack/utils/browserslist.ts +29 -0
- package/src/library/webpack/utils/rsdoctor.ts +26 -0
- package/src/library/webpack/utils/threadLoader.ts +1 -0
- package/src/library/webpack/utils/transpiler.ts +3 -18
- package/src/models/config.spec.ts +4 -0
- package/src/schema/autogeneratedSchema.json +240 -120
- package/src/schema/tramvai.spec.ts +2 -0
- package/src/typings/build/Builder.ts +7 -2
- package/src/typings/configEntry/cli.ts +11 -0
- package/src/utils/commands/dependencies/getLatestPackageVersion.ts +4 -1
- package/src/utils/commands/dependencies/packageHasVersion.ts +7 -2
- package/lib/api/analyze/providers/shared.d.ts +0 -3
- package/lib/api/analyze/providers/shared.d.ts.map +0 -1
- package/lib/api/analyze/providers/shared.js +0 -23
- package/lib/api/analyze/providers/shared.js.map +0 -1
- package/lib/builder/webpack/providers/analyze/shared.d.ts +0 -3
- package/lib/builder/webpack/providers/analyze/shared.d.ts.map +0 -1
- package/lib/builder/webpack/providers/analyze/shared.js +0 -141
- package/lib/builder/webpack/providers/analyze/shared.js.map +0 -1
- package/src/api/analyze/providers/shared.ts +0 -26
- package/src/api/benchmark/utils/stats.spec.ts +0 -36
- package/src/builder/webpack/providers/analyze/shared.ts +0 -160
|
@@ -1,59 +1,194 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { table, TableUserConfig } from 'table';
|
|
2
|
+
import isEmpty from '@tinkoff/utils/is/empty';
|
|
3
|
+
|
|
3
4
|
import type { Context } from '../../models/context';
|
|
4
5
|
import type { CommandResult } from '../../models/command';
|
|
5
6
|
import type { Result } from '../../api/benchmark';
|
|
7
|
+
import type { CompilationStats } from '../../api/benchmark/types';
|
|
8
|
+
import { DEFAULT_TIMES } from '../../api/benchmark/const';
|
|
6
9
|
|
|
7
10
|
import { app } from '../index';
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
export function toFixedDigits(num: number, digits = 2): number {
|
|
13
|
+
if (digits === 0) {
|
|
14
|
+
return Math.floor(num);
|
|
15
|
+
}
|
|
16
|
+
return +num.toFixed(digits);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const getUnit = (num: number) => (num > 1 ? 'mins' : 'min');
|
|
20
|
+
|
|
21
|
+
export function formatCosts(costs: number): string {
|
|
22
|
+
// more than 1s
|
|
23
|
+
if (costs >= 1000) {
|
|
24
|
+
const sec = costs / 1000;
|
|
25
|
+
// more than 1min
|
|
26
|
+
if (sec >= 60) {
|
|
27
|
+
let mins = sec / 60;
|
|
28
|
+
|
|
29
|
+
mins = toFixedDigits(mins, 0);
|
|
30
|
+
const mUnit = getUnit(mins);
|
|
31
|
+
const restSec = toFixedDigits(sec % 60, 0);
|
|
32
|
+
|
|
33
|
+
if (restSec > 0) {
|
|
34
|
+
return `${mins}${mUnit} ${restSec}s`;
|
|
35
|
+
}
|
|
36
|
+
return `${mins}${mUnit}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return `${toFixedDigits(sec, 1)}s`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (costs >= 10) {
|
|
43
|
+
return `${+toFixedDigits(costs, 0)}ms`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (costs >= 1) {
|
|
47
|
+
return `${+toFixedDigits(costs, 1)}ms`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let r = +toFixedDigits(costs, 2);
|
|
51
|
+
|
|
52
|
+
if (r === 0) {
|
|
53
|
+
r = +toFixedDigits(costs, 3);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return `${r}ms`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const formatValues = (measures: Record<string, number>) => {
|
|
60
|
+
const result: [string, string][] = [];
|
|
61
|
+
|
|
62
|
+
for (const measureName in measures) {
|
|
63
|
+
const measureValue = measures[measureName];
|
|
64
|
+
result.push([measureName, formatCosts(measureValue)]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return result;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const filterStats = (measures: Record<string, number>) => {
|
|
71
|
+
const entries = Object.entries(measures);
|
|
72
|
+
entries.sort((a, b) => b[1] - a[1]);
|
|
10
73
|
|
|
11
|
-
|
|
12
|
-
|
|
74
|
+
return entries.slice(0, 5).reduce((acc, [key, value]) => {
|
|
75
|
+
acc[key] = value;
|
|
76
|
+
return acc;
|
|
77
|
+
}, {});
|
|
13
78
|
};
|
|
14
79
|
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
80
|
+
const getInfo = (compilationStats: CompilationStats) => {
|
|
81
|
+
const { totalBuildCosts, loaderBuildCosts, pluginBuildCosts } = compilationStats;
|
|
82
|
+
|
|
83
|
+
const totalBuildInfo = formatValues(totalBuildCosts);
|
|
84
|
+
const loaderInfo = formatValues(filterStats(loaderBuildCosts));
|
|
85
|
+
const pluginInfo = formatValues(filterStats(pluginBuildCosts));
|
|
19
86
|
|
|
20
|
-
return
|
|
87
|
+
return { totalBuildInfo, loaderInfo, pluginInfo };
|
|
21
88
|
};
|
|
22
89
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
90
|
+
const mergeTotalInfo = (
|
|
91
|
+
server?: [string, string][] | undefined,
|
|
92
|
+
client?: [string, string][] | undefined
|
|
93
|
+
) => {
|
|
94
|
+
const result = [];
|
|
27
95
|
|
|
28
|
-
for (
|
|
29
|
-
|
|
30
|
-
|
|
96
|
+
for (let i = 0; i < (server?.length ?? client?.length); i++) {
|
|
97
|
+
result.push([
|
|
98
|
+
server?.[i][0] ?? client?.[i][0] ?? '-',
|
|
99
|
+
server?.[i][1] ?? '0',
|
|
100
|
+
client?.[i][1] ?? '0',
|
|
101
|
+
]);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return result;
|
|
105
|
+
};
|
|
31
106
|
|
|
32
|
-
|
|
107
|
+
const mergeAdditionalInfo = (
|
|
108
|
+
server?: [string, string][] | undefined,
|
|
109
|
+
client?: [string, string][] | undefined
|
|
110
|
+
) => {
|
|
111
|
+
const result = [];
|
|
33
112
|
|
|
34
|
-
|
|
35
|
-
|
|
113
|
+
for (let i = 0; i < (server?.length ?? client?.length); i++) {
|
|
114
|
+
result.push([
|
|
115
|
+
server?.[i][0] ?? '-',
|
|
116
|
+
server?.[i][1] ?? '0',
|
|
117
|
+
client?.[i][0] ?? '-',
|
|
118
|
+
client?.[i][1] ?? 0,
|
|
119
|
+
]);
|
|
36
120
|
}
|
|
37
121
|
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
122
|
+
return result;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const formatBuildTime = (totalBuildTime) =>
|
|
126
|
+
totalBuildTime ? `${(totalBuildTime / 1000).toFixed(2)}s` : '-';
|
|
127
|
+
|
|
128
|
+
const formatMemoryRss = (memoryRss) => (memoryRss ? `${(memoryRss / 1000000).toFixed(2)}mb` : '-');
|
|
129
|
+
|
|
130
|
+
const formatStatsTables = (stats: Result, times: number | undefined = DEFAULT_TIMES) => {
|
|
131
|
+
const {
|
|
132
|
+
clientBuildTime,
|
|
133
|
+
clientCompilationStats,
|
|
134
|
+
serverBuildTime,
|
|
135
|
+
serverCompilationStats,
|
|
136
|
+
maxMemoryRss,
|
|
137
|
+
clientMaxMemoryRss,
|
|
138
|
+
serverMaxMemoryRss,
|
|
139
|
+
} = stats;
|
|
140
|
+
const serverInfo = !isEmpty(serverCompilationStats) && getInfo(serverCompilationStats);
|
|
141
|
+
const clientInfo = !isEmpty(clientCompilationStats) && getInfo(clientCompilationStats);
|
|
142
|
+
|
|
143
|
+
const totalBuildData = [
|
|
144
|
+
[`Mean durations (${times} times)`, 'server', 'client'],
|
|
145
|
+
['Total build time', formatBuildTime(serverBuildTime), formatBuildTime(clientBuildTime)],
|
|
146
|
+
maxMemoryRss
|
|
147
|
+
? ['Total memory', formatMemoryRss(maxMemoryRss), '']
|
|
148
|
+
: ['Total memory', formatMemoryRss(serverMaxMemoryRss), formatMemoryRss(clientMaxMemoryRss)],
|
|
149
|
+
...mergeTotalInfo(serverInfo.totalBuildInfo, clientInfo.totalBuildInfo),
|
|
150
|
+
].filter(Boolean);
|
|
151
|
+
|
|
152
|
+
const totalBuildTableConfig: TableUserConfig = {
|
|
153
|
+
columns: [{ alignment: 'left' }, { alignment: 'center' }, { alignment: 'center' }],
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
if (maxMemoryRss) {
|
|
157
|
+
// @ts-expect-error
|
|
158
|
+
totalBuildTableConfig.spanningCells = [{ col: 1, row: 2, colSpan: 2, alignment: 'center' }];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const mergedLoadersInfo = mergeAdditionalInfo(serverInfo.loaderInfo, clientInfo.loaderInfo);
|
|
162
|
+
const mergedPluginsInfo = mergeAdditionalInfo(serverInfo.pluginInfo, clientInfo.pluginInfo);
|
|
163
|
+
const additionalBuildData = [
|
|
164
|
+
['server', '', 'client', ''],
|
|
165
|
+
['Loaders', '', '', ''],
|
|
166
|
+
...mergedLoadersInfo,
|
|
167
|
+
['Plugins', '', '', ''],
|
|
168
|
+
...mergedPluginsInfo,
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
const additionalBuildTableConfig: TableUserConfig = {
|
|
172
|
+
spanningCells: [
|
|
173
|
+
{ col: 0, row: 0, colSpan: 2, alignment: 'center' },
|
|
174
|
+
{ col: 2, row: 0, colSpan: 2, alignment: 'center' },
|
|
175
|
+
{ col: 0, row: 1, colSpan: 4, alignment: 'center' },
|
|
176
|
+
{ col: 0, row: mergedLoadersInfo.length + 2, colSpan: 4, alignment: 'center' },
|
|
177
|
+
],
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
return [
|
|
181
|
+
table(totalBuildData, totalBuildTableConfig),
|
|
182
|
+
table(additionalBuildData, additionalBuildTableConfig),
|
|
183
|
+
];
|
|
49
184
|
};
|
|
50
185
|
|
|
51
|
-
export default async (
|
|
186
|
+
export default async (_context: Context, parameters): Promise<CommandResult | any> => {
|
|
52
187
|
const { command, times, ...commandOptions } = parameters;
|
|
53
188
|
|
|
54
189
|
const stats = await app.run('benchmark', { command, times, commandOptions });
|
|
55
190
|
|
|
56
|
-
console.log(
|
|
191
|
+
formatStatsTables(stats, times).forEach((buildTable) => console.log(buildTable));
|
|
57
192
|
|
|
58
193
|
return Promise.resolve({
|
|
59
194
|
status: 'ok',
|
|
@@ -36,6 +36,18 @@ export class BenchmarkCommand extends CLICommand<Params> {
|
|
|
36
36
|
description:
|
|
37
37
|
'Specify the names of the bundles that need to be collected, other bundles will not be collected and their request will fail with an error',
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
name: '--fileCache',
|
|
41
|
+
value: '[fileCache]',
|
|
42
|
+
transformer: (value: string) => value !== 'false',
|
|
43
|
+
description: 'Enable/disable persistent file cache for used cli builder',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: '-t, --buildType',
|
|
47
|
+
value: '[type]',
|
|
48
|
+
description: 'Build type <client|server>',
|
|
49
|
+
defaultValue: 'client',
|
|
50
|
+
},
|
|
39
51
|
{
|
|
40
52
|
name: '--times',
|
|
41
53
|
value: '[times]',
|
|
@@ -54,6 +54,12 @@ class BuildCommand extends CLICommand<Params> {
|
|
|
54
54
|
value: '[forPublish]',
|
|
55
55
|
description: '<package> Prepare library package.json for publication',
|
|
56
56
|
},
|
|
57
|
+
{
|
|
58
|
+
name: '--analyze',
|
|
59
|
+
value: '[analyze]',
|
|
60
|
+
description:
|
|
61
|
+
'Run build with analyze, supported plugins: <bundle|whybundled|statoscope|rsdoctor>',
|
|
62
|
+
},
|
|
57
63
|
{
|
|
58
64
|
name: '--fileCache',
|
|
59
65
|
value: '[fileCache]',
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"start": "tramvai start {{configEntry.name}}",
|
|
10
10
|
"build": "tramvai build {{configEntry.name}}",
|
|
11
11
|
"preview": "tramvai start-prod {{configEntry.name}}",
|
|
12
|
-
"analyze": "tramvai
|
|
12
|
+
"analyze": "tramvai {{configEntry.name}} --analyze=statoscope",
|
|
13
13
|
"lint": "eslint --ext .ts,.tsx --ignore-path .gitignore ."{{#if isJest}},
|
|
14
14
|
"test": "jest --passWithNoTests",
|
|
15
15
|
"test:watch": "jest --watch",
|
|
@@ -95,6 +95,12 @@ export class StartCommand extends CLICommand<Params> {
|
|
|
95
95
|
value: '[showConfig]',
|
|
96
96
|
description: 'Show config with which cli was launched',
|
|
97
97
|
},
|
|
98
|
+
{
|
|
99
|
+
name: '--analyze',
|
|
100
|
+
value: '[analyze]',
|
|
101
|
+
description:
|
|
102
|
+
'Run build with analyze, supported plugins: <bundle|whybundled|statoscope|rsdoctor>',
|
|
103
|
+
},
|
|
98
104
|
{
|
|
99
105
|
name: '--onlyBundles',
|
|
100
106
|
value: '[onlyBundles]',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { packageHasVersion } from '../../utils/commands/dependencies/packageHasVersion';
|
|
2
2
|
import type { Params } from './update';
|
|
3
3
|
|
|
4
|
-
export const checkVersion = async (
|
|
4
|
+
export const checkVersion = async (context, { to: version = 'latest' }: Params) => {
|
|
5
5
|
if (version === 'latest') {
|
|
6
6
|
return {
|
|
7
7
|
name: 'checkVersion',
|
|
@@ -9,7 +9,9 @@ export const checkVersion = async (_, { to: version = 'latest' }: Params) => {
|
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
const registryUrl = await context.packageManager.getRegistryUrl();
|
|
13
|
+
|
|
14
|
+
if (await packageHasVersion('@tramvai/core', version, registryUrl)) {
|
|
13
15
|
return {
|
|
14
16
|
name: 'checkVersion',
|
|
15
17
|
status: 'ok',
|
|
@@ -7,13 +7,15 @@ export const getLibPackageVersion = async (
|
|
|
7
7
|
name: string,
|
|
8
8
|
version: string,
|
|
9
9
|
resolvedVersion: string,
|
|
10
|
+
registryUrl: string,
|
|
10
11
|
spinner: Ora
|
|
11
12
|
): Promise<string | undefined> => {
|
|
12
13
|
const unifiedModule = DEPENDANT_LIBS_MAP.get(name);
|
|
13
14
|
|
|
14
15
|
if (!unifiedModule) {
|
|
15
16
|
try {
|
|
16
|
-
|
|
17
|
+
// @ts-expect-error uncomplete type definition, `registryUrl` is supported
|
|
18
|
+
return await getLatestPackageVersion(name, { version, registryUrl });
|
|
17
19
|
} catch (e) {
|
|
18
20
|
// clear the spinner to be able to log info that should be preserved in the output
|
|
19
21
|
// the idea borrowed from [here](https://github.com/sindresorhus/ora/issues/120)
|
|
@@ -16,7 +16,10 @@ export default async (
|
|
|
16
16
|
context: Context,
|
|
17
17
|
{ to: version = 'latest', tag }: Params
|
|
18
18
|
): Promise<CommandResult> => {
|
|
19
|
-
const
|
|
19
|
+
const registry = await context.packageManager.getRegistryUrl();
|
|
20
|
+
const resolvedVersion = tag
|
|
21
|
+
? version
|
|
22
|
+
: await getLatestPackageVersion('@tramvai/cli', registry, version);
|
|
20
23
|
const currentVersion = await findTramvaiVersion();
|
|
21
24
|
|
|
22
25
|
if (!currentVersion) {
|
|
@@ -40,12 +43,12 @@ export default async (
|
|
|
40
43
|
if (context.packageManager.workspaces) {
|
|
41
44
|
await Promise.all(
|
|
42
45
|
context.packageManager.workspaces.map((directory) =>
|
|
43
|
-
updatePackageJson(version, resolvedVersion, currentVersion, tag, directory)
|
|
46
|
+
updatePackageJson(version, resolvedVersion, currentVersion, registry, tag, directory)
|
|
44
47
|
)
|
|
45
48
|
);
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
await updatePackageJson(version, resolvedVersion, currentVersion, tag);
|
|
51
|
+
await updatePackageJson(version, resolvedVersion, currentVersion, registry, tag);
|
|
49
52
|
|
|
50
53
|
context.logger.event({
|
|
51
54
|
type: 'info',
|
|
@@ -76,7 +76,12 @@ it('should update tramvai deps to latest versions', async () => {
|
|
|
76
76
|
return {};
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
await updatePackageJson(
|
|
79
|
+
await updatePackageJson(
|
|
80
|
+
LATEST_TRAMVAI_VERSION,
|
|
81
|
+
LATEST_TRAMVAI_VERSION,
|
|
82
|
+
CURRENT_TRAMVAI_VERSION,
|
|
83
|
+
'fake-registry'
|
|
84
|
+
);
|
|
80
85
|
|
|
81
86
|
// eslint-disable-next-line jest/no-interpolation-in-snapshots
|
|
82
87
|
expect(mockFsWrite.mock.calls[0]).toMatchInlineSnapshot(`
|
|
@@ -138,7 +143,12 @@ it('prerelease should be resolved and used for dependant libs', async () => {
|
|
|
138
143
|
return {};
|
|
139
144
|
});
|
|
140
145
|
|
|
141
|
-
await updatePackageJson(
|
|
146
|
+
await updatePackageJson(
|
|
147
|
+
'prerelease',
|
|
148
|
+
LATEST_TRAMVAI_VERSION,
|
|
149
|
+
CURRENT_TRAMVAI_VERSION,
|
|
150
|
+
'fake-registry'
|
|
151
|
+
);
|
|
142
152
|
|
|
143
153
|
// eslint-disable-next-line jest/no-interpolation-in-snapshots
|
|
144
154
|
expect(mockFsWrite.mock.calls[0]).toMatchInlineSnapshot(`
|
|
@@ -201,7 +211,13 @@ it('dist tag should be used for dependant libs', async () => {
|
|
|
201
211
|
return {};
|
|
202
212
|
});
|
|
203
213
|
|
|
204
|
-
await updatePackageJson(
|
|
214
|
+
await updatePackageJson(
|
|
215
|
+
'prerelease',
|
|
216
|
+
'prerelease',
|
|
217
|
+
CURRENT_TRAMVAI_VERSION,
|
|
218
|
+
'fake-registry',
|
|
219
|
+
true
|
|
220
|
+
);
|
|
205
221
|
|
|
206
222
|
// eslint-disable-next-line jest/no-interpolation-in-snapshots
|
|
207
223
|
expect(mockFsWrite.mock.calls[0]).toMatchInlineSnapshot(`
|
|
@@ -13,6 +13,7 @@ const updateDependencies = (
|
|
|
13
13
|
resolvedVersion: string,
|
|
14
14
|
currentVersion: string,
|
|
15
15
|
tag: boolean,
|
|
16
|
+
registryUrl: string,
|
|
16
17
|
spinner: Ora
|
|
17
18
|
) => {
|
|
18
19
|
return pMap<string, void>(
|
|
@@ -25,12 +26,12 @@ const updateDependencies = (
|
|
|
25
26
|
} else if (isDependantLib(dep)) {
|
|
26
27
|
const libVersion = tag
|
|
27
28
|
? resolvedVersion
|
|
28
|
-
: await getLibPackageVersion(dep, version, resolvedVersion, spinner);
|
|
29
|
+
: await getLibPackageVersion(dep, version, resolvedVersion, registryUrl, spinner);
|
|
29
30
|
nextVersion = libVersion;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
if (nextVersion) {
|
|
33
|
-
const depHasVersion = await packageHasVersion(dep, nextVersion);
|
|
34
|
+
const depHasVersion = await packageHasVersion(dep, nextVersion, registryUrl);
|
|
34
35
|
|
|
35
36
|
// clear the spinner to be able to log info that should be preserved in the output
|
|
36
37
|
// the idea borrowed from [here](https://github.com/sindresorhus/ora/issues/120)
|
|
@@ -62,6 +63,7 @@ export const updatePackageJson = async (
|
|
|
62
63
|
version: string,
|
|
63
64
|
resolvedVersion: string,
|
|
64
65
|
currentVersion: string,
|
|
66
|
+
registryUrl: string,
|
|
65
67
|
tag?: boolean,
|
|
66
68
|
path = '.'
|
|
67
69
|
) => {
|
|
@@ -78,6 +80,7 @@ export const updatePackageJson = async (
|
|
|
78
80
|
resolvedVersion,
|
|
79
81
|
currentVersion,
|
|
80
82
|
tag,
|
|
83
|
+
registryUrl,
|
|
81
84
|
spinner
|
|
82
85
|
);
|
|
83
86
|
await updateDependencies(
|
|
@@ -86,6 +89,7 @@ export const updatePackageJson = async (
|
|
|
86
89
|
resolvedVersion,
|
|
87
90
|
currentVersion,
|
|
88
91
|
tag,
|
|
92
|
+
registryUrl,
|
|
89
93
|
spinner
|
|
90
94
|
);
|
|
91
95
|
await updateDependencies(
|
|
@@ -94,6 +98,7 @@ export const updatePackageJson = async (
|
|
|
94
98
|
resolvedVersion,
|
|
95
99
|
currentVersion,
|
|
96
100
|
tag,
|
|
101
|
+
registryUrl,
|
|
97
102
|
spinner
|
|
98
103
|
);
|
|
99
104
|
|
|
@@ -37,9 +37,11 @@ export interface Settings<E extends Env> {
|
|
|
37
37
|
profile?: boolean;
|
|
38
38
|
noServerRebuild?: boolean;
|
|
39
39
|
noClientRebuild?: boolean;
|
|
40
|
+
benchmark?: boolean;
|
|
40
41
|
resolveSymlinks?: boolean;
|
|
41
42
|
showConfig?: boolean;
|
|
42
43
|
onlyBundles?: string[];
|
|
44
|
+
analyze?: false | 'bundle' | 'whybundled' | 'statoscope' | 'rsdoctor';
|
|
43
45
|
disableProdOptimization?: boolean;
|
|
44
46
|
fileCache?: boolean;
|
|
45
47
|
}
|
|
@@ -131,8 +133,10 @@ export const createConfigManager = <C extends ConfigEntry = ConfigEntry, E exten
|
|
|
131
133
|
profile: false,
|
|
132
134
|
noClientRebuild: false,
|
|
133
135
|
noServerRebuild: false,
|
|
136
|
+
benchmark: false,
|
|
134
137
|
resolveSymlinks: true,
|
|
135
138
|
disableProdOptimization: false,
|
|
139
|
+
analyze: false,
|
|
136
140
|
onlyBundles: [],
|
|
137
141
|
// according to measures fileCache in webpack doesn't affect
|
|
138
142
|
// performance much so enable it by default as it always was before
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import applyOrReturn from '@tinkoff/utils/function/applyOrReturn';
|
|
2
1
|
import path from 'path';
|
|
3
2
|
import type Config from 'webpack-chain';
|
|
4
3
|
import ExtractCssChunks from 'mini-css-extract-plugin';
|
|
5
4
|
import { createGenerator } from '@tinkoff/minicss-class-generator';
|
|
5
|
+
|
|
6
6
|
import { safeRequire } from '../../../utils/safeRequire';
|
|
7
7
|
import type { ConfigManager } from '../../../config/configManager';
|
|
8
8
|
import type { CliConfigEntry } from '../../../typings/configEntry/cli';
|
|
9
|
+
import { getActualTarget, getBrowserslistTargets } from '../utils/browserslist';
|
|
9
10
|
|
|
10
11
|
const cssLocalIdentNameDevDefault = '[name]__[local]_[minicss]';
|
|
11
12
|
const cssLocalIdentNameProdDefault = '[minicss]';
|
|
@@ -21,8 +22,9 @@ interface Options {
|
|
|
21
22
|
export const cssWebpackRulesFactory =
|
|
22
23
|
(configManager: ConfigManager<CliConfigEntry>, options: Options = {}) =>
|
|
23
24
|
(config: Config) => {
|
|
24
|
-
const { env, sourceMap, buildType } = configManager;
|
|
25
|
+
const { env, sourceMap, buildType, experiments, target } = configManager;
|
|
25
26
|
const {
|
|
27
|
+
rootDir,
|
|
26
28
|
postcss: {
|
|
27
29
|
config: postcssConfig,
|
|
28
30
|
cssLocalIdentName = env === 'production'
|
|
@@ -31,6 +33,9 @@ export const cssWebpackRulesFactory =
|
|
|
31
33
|
cssModulePattern,
|
|
32
34
|
},
|
|
33
35
|
} = configManager;
|
|
36
|
+
const isServer = configManager.buildType === 'server';
|
|
37
|
+
const actualTarget = getActualTarget(target, isServer);
|
|
38
|
+
const browsersListTargets = getBrowserslistTargets(rootDir, actualTarget);
|
|
34
39
|
const localIdentName = options.localIdentName ?? cssLocalIdentName;
|
|
35
40
|
|
|
36
41
|
const configCssLoader = (cfg) => {
|
|
@@ -73,17 +78,33 @@ export const cssWebpackRulesFactory =
|
|
|
73
78
|
typeof postcssConfig === 'undefined'
|
|
74
79
|
) ?? {};
|
|
75
80
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
// https://github.com/webpack-contrib/postcss-loader/blob/master/src/config.d.ts
|
|
82
|
+
const postcssOptionsFn = (loaderContext: any) => {
|
|
83
|
+
const isFnConfig = typeof postcssCfg === 'function';
|
|
84
|
+
// TODO: async config fn support?
|
|
85
|
+
const defaultConfig = isFnConfig ? postcssCfg(loaderContext) : postcssCfg;
|
|
86
|
+
// eslint-disable-next-line no-nested-ternary
|
|
87
|
+
const defaultPlugins = defaultConfig.plugins ? defaultConfig.plugins : [];
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
config: false,
|
|
91
|
+
...defaultConfig,
|
|
81
92
|
// TODO: придумать как прокинуть настройки browserslist в autoprefixer - сейчас autoprefixer добавляется в самом приложении и из
|
|
82
93
|
// конфига нет возможности задавать динамический env в зависимости от сборки. Подсунуть в сам autoprefixer после его инициализации тоже
|
|
83
94
|
// тоже не получится - https://github.com/postcss/autoprefixer/blob/10.3.1/lib/autoprefixer.js#L108
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
95
|
+
plugins: Array.isArray(defaultPlugins)
|
|
96
|
+
? [
|
|
97
|
+
require('postcss-modules-tilda'),
|
|
98
|
+
require('postcss-modules-values-replace')({ importsAsModuleRequests: true }),
|
|
99
|
+
...defaultPlugins,
|
|
100
|
+
]
|
|
101
|
+
: {
|
|
102
|
+
'postcss-modules-tilda': {},
|
|
103
|
+
'postcss-modules-values-replace': { importsAsModuleRequests: true },
|
|
104
|
+
...defaultPlugins,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
};
|
|
87
108
|
|
|
88
109
|
// otherwise postcss-loader will use cosmiconfig to resolve postcss configuration file
|
|
89
110
|
// https://github.com/webpack-contrib/postcss-loader/blob/6f470db420f6febbea729080921050e8fe353226/src/index.js#L38
|
|
@@ -93,12 +114,27 @@ export const cssWebpackRulesFactory =
|
|
|
93
114
|
.rule('css')
|
|
94
115
|
.test(/\.css$/)
|
|
95
116
|
.batch(configCssLoader)
|
|
96
|
-
.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
117
|
+
.when(
|
|
118
|
+
experiments.lightningcss,
|
|
119
|
+
(cfg) => {
|
|
120
|
+
const lightningcss = require('lightningcss');
|
|
121
|
+
|
|
122
|
+
return cfg
|
|
123
|
+
.use('lightningcss')
|
|
124
|
+
.loader('lightningcss-loader')
|
|
125
|
+
.options({
|
|
126
|
+
options: {
|
|
127
|
+
implementation: lightningcss,
|
|
128
|
+
targets: browsersListTargets,
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
},
|
|
132
|
+
(cfg) =>
|
|
133
|
+
cfg.use('postcss').loader('postcss-loader').options({
|
|
134
|
+
sourceMap,
|
|
135
|
+
postcssOptions: postcssOptionsFn,
|
|
136
|
+
})
|
|
137
|
+
);
|
|
102
138
|
};
|
|
103
139
|
|
|
104
140
|
export default cssWebpackRulesFactory;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
import type Config from 'webpack-chain';
|
|
2
3
|
import { modernLibsFilter } from '@tinkoff/is-modern-lib';
|
|
3
4
|
import { applyThreadLoader } from '../utils/threadLoader';
|
|
@@ -5,25 +6,22 @@ import type { ConfigManager } from '../../../config/configManager';
|
|
|
5
6
|
import { getTranspilerConfig, addTranspilerLoader } from '../utils/transpiler';
|
|
6
7
|
import type { CliConfigEntry } from '../../../typings/configEntry/cli';
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const { transpileOnlyModernLibs } = configManager;
|
|
11
|
-
|
|
12
|
-
const rule = config.module
|
|
13
|
-
.rule('js')
|
|
14
|
-
.test(/\.[cm]?js[x]?$/)
|
|
15
|
-
.batch(applyThreadLoader(configManager));
|
|
9
|
+
const projectRulesName = 'project';
|
|
10
|
+
const nodeModuleRulesName = 'node_module';
|
|
16
11
|
|
|
12
|
+
const applyProjectRules = (rule, configManager) => {
|
|
17
13
|
rule
|
|
18
|
-
.oneOf(
|
|
14
|
+
.oneOf(projectRulesName)
|
|
19
15
|
.exclude.add(/node_modules/)
|
|
20
16
|
.end()
|
|
21
17
|
.use('transpiler')
|
|
22
|
-
.batch(addTranspilerLoader(configManager, getTranspilerConfig(configManager)))
|
|
18
|
+
.batch(addTranspilerLoader(configManager, getTranspilerConfig(configManager)))
|
|
19
|
+
.end();
|
|
20
|
+
};
|
|
23
21
|
|
|
22
|
+
const applyNodeModulesRules = (rule, configManager) => {
|
|
24
23
|
rule
|
|
25
|
-
.oneOf(
|
|
26
|
-
.when(transpileOnlyModernLibs, (cfg) => cfg.include.add(modernLibsFilter))
|
|
24
|
+
.oneOf(nodeModuleRulesName)
|
|
27
25
|
.merge({
|
|
28
26
|
// true value forces to use file extensions for importing mjs modules
|
|
29
27
|
// but we want to use mjs if it exists anyway
|
|
@@ -32,3 +30,54 @@ export default (configManager: ConfigManager<CliConfigEntry>) => (config: Config
|
|
|
32
30
|
.use('transpiler')
|
|
33
31
|
.batch(addTranspilerLoader(configManager, getTranspilerConfig(configManager, { hot: false })));
|
|
34
32
|
};
|
|
33
|
+
|
|
34
|
+
// eslint-disable-next-line import/no-default-export
|
|
35
|
+
export default (configManager: ConfigManager<CliConfigEntry>) => (config: Config) => {
|
|
36
|
+
const { transpileOnlyModernLibs } = configManager;
|
|
37
|
+
const { include } = configManager.experiments.transpilation;
|
|
38
|
+
const shouldTranspileOnlyModern = transpileOnlyModernLibs || include === 'only-modern';
|
|
39
|
+
|
|
40
|
+
const rule = config.module
|
|
41
|
+
.rule('js')
|
|
42
|
+
.test(/\.[cm]?js[x]?$/)
|
|
43
|
+
.batch(applyThreadLoader(configManager));
|
|
44
|
+
|
|
45
|
+
if (configManager.env === 'production') {
|
|
46
|
+
applyProjectRules(rule, configManager);
|
|
47
|
+
applyNodeModulesRules(rule, configManager);
|
|
48
|
+
|
|
49
|
+
if (shouldTranspileOnlyModern) {
|
|
50
|
+
rule.oneOf(nodeModuleRulesName).include.add(modernLibsFilter);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
const shouldSkipTranspiling = include === 'none';
|
|
54
|
+
const shouldSelectiveTranspile = Array.isArray(include);
|
|
55
|
+
|
|
56
|
+
if (shouldSkipTranspiling) {
|
|
57
|
+
rule.exclude
|
|
58
|
+
.add(/node_modules/)
|
|
59
|
+
.end()
|
|
60
|
+
.use('transpiler')
|
|
61
|
+
.batch(addTranspilerLoader(configManager, getTranspilerConfig(configManager)));
|
|
62
|
+
} else {
|
|
63
|
+
applyProjectRules(rule, configManager);
|
|
64
|
+
applyNodeModulesRules(rule, configManager);
|
|
65
|
+
|
|
66
|
+
if (shouldSelectiveTranspile) {
|
|
67
|
+
const includeForTranspiling = (<string[]>include).map((includePath) =>
|
|
68
|
+
// require.resolve return absolute path to entrypoint of dependency
|
|
69
|
+
// but we need root dirname of dependency inside node_modules
|
|
70
|
+
path.dirname(require.resolve(`${includePath}/package.json`))
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
includeForTranspiling.forEach((includePath) => {
|
|
74
|
+
rule.oneOf(nodeModuleRulesName).include.add(includePath);
|
|
75
|
+
});
|
|
76
|
+
} else if (shouldTranspileOnlyModern) {
|
|
77
|
+
if (shouldTranspileOnlyModern) {
|
|
78
|
+
rule.oneOf(nodeModuleRulesName).include.add(modernLibsFilter);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|