@tramvai/cli 5.53.80 → 5.53.94
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/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 +8 -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/new/steps/installDependencies.js +1 -1
- package/lib/commands/new/steps/installDependencies.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/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 +4 -8
- package/lib/di/tokens/config.d.ts.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/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/schema/autogeneratedSchema.json +228 -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 +5 -0
- package/lib/typings/configEntry/cli.d.ts.map +1 -1
- package/package.json +16 -17
- package/schema.json +228 -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/steps/installDependencies.ts +1 -1
- package/src/commands/new/templates/shared/_prettierrc.js.hbs +1 -1
- package/src/commands/new/templates/shared/package.json.hbs +1 -1
- package/src/commands/start/command.ts +6 -0
- package/src/config/configManager.ts +4 -0
- package/src/library/webpack/blocks/js.ts +61 -12
- package/src/library/webpack/common/main.ts +8 -0
- package/src/library/webpack/utils/rsdoctor.ts +26 -0
- package/src/library/webpack/utils/threadLoader.ts +1 -0
- package/src/models/config.spec.ts +4 -0
- package/src/schema/autogeneratedSchema.json +228 -120
- package/src/schema/tramvai.spec.ts +2 -0
- package/src/typings/build/Builder.ts +7 -2
- package/src/typings/configEntry/cli.ts +6 -0
- 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]',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require('prettier-config
|
|
1
|
+
module.exports = require('@tramvai/prettier-config');
|
|
@@ -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]',
|
|
@@ -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,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
|
+
};
|
|
@@ -3,6 +3,7 @@ import type Config from 'webpack-chain';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { existsSync } from 'fs-extra';
|
|
5
5
|
import findCacheDir from 'find-cache-dir';
|
|
6
|
+
import { RsdoctorWebpackMultiplePlugin } from '@rsdoctor/webpack-plugin';
|
|
6
7
|
import { ignoreWarnings } from '../utils/warningsFilter';
|
|
7
8
|
import resolve from '../blocks/resolve';
|
|
8
9
|
import ignoreLocales from '../blocks/ignoreLocales';
|
|
@@ -10,6 +11,7 @@ import type { ConfigManager } from '../../../config/configManager';
|
|
|
10
11
|
import { safeRequireResolve } from '../../../utils/safeRequire';
|
|
11
12
|
import type { CliConfigEntry } from '../../../typings/configEntry/cli';
|
|
12
13
|
import { getPostcssConfigPath } from '../blocks/css';
|
|
14
|
+
import { getRsdoctorOptions } from '../utils/rsdoctor';
|
|
13
15
|
|
|
14
16
|
const filterNonExisted = (filePaths: string[]) => {
|
|
15
17
|
return filePaths.filter((filePath) => {
|
|
@@ -126,6 +128,12 @@ export default (configManager: ConfigManager<CliConfigEntry>) => (config: Config
|
|
|
126
128
|
},
|
|
127
129
|
]);
|
|
128
130
|
|
|
131
|
+
if (configManager.benchmark) {
|
|
132
|
+
config
|
|
133
|
+
.plugin('rsdoctor-benchmark')
|
|
134
|
+
.use(RsdoctorWebpackMultiplePlugin, [getRsdoctorOptions(configManager.buildType)]);
|
|
135
|
+
}
|
|
136
|
+
|
|
129
137
|
// TODO: remove after dropping support for node@14
|
|
130
138
|
if (configManager.buildType === 'server') {
|
|
131
139
|
config.plugin('node-performance').use(webpack.ProvidePlugin, [
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { RsdoctorWebpackPlugin } from '@rsdoctor/webpack-plugin';
|
|
2
|
+
|
|
3
|
+
type options = ConstructorParameters<typeof RsdoctorWebpackPlugin<[]>>[0];
|
|
4
|
+
|
|
5
|
+
export const getRsdoctorOptions = (buildType: 'client' | 'server'): options => ({
|
|
6
|
+
disableClientServer: true,
|
|
7
|
+
features: ['plugins', 'loader'],
|
|
8
|
+
linter: {
|
|
9
|
+
level: 'Ignore',
|
|
10
|
+
},
|
|
11
|
+
output: {
|
|
12
|
+
reportDir: './.rsdoctor',
|
|
13
|
+
mode: 'brief',
|
|
14
|
+
options: {
|
|
15
|
+
type: ['json'],
|
|
16
|
+
jsonOptions: {
|
|
17
|
+
fileName: `${buildType}-rsdoctor-data.json`,
|
|
18
|
+
sections: {
|
|
19
|
+
moduleGraph: false,
|
|
20
|
+
chunkGraph: false,
|
|
21
|
+
rules: false,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -23,6 +23,7 @@ const createWorkerPoolConfig = (configManager: ConfigManager<CliConfigEntry>) =>
|
|
|
23
23
|
|
|
24
24
|
const isApplicable = (configManager: ConfigManager<CliConfigEntry>) => {
|
|
25
25
|
return (
|
|
26
|
+
!configManager.benchmark &&
|
|
26
27
|
// thread-loader uses child_process.fork under the hood, and sometimes (50/50) work in these processes does not get into inspector.Session profile
|
|
27
28
|
!process.env.TRAMVAI_CPU_PROFILE &&
|
|
28
29
|
!process.env.TRAMVAI_DEBUG_BUILD &&
|
|
@@ -76,6 +76,7 @@ it('should populate defaults for config', () => {
|
|
|
76
76
|
"runtimeChunk": false,
|
|
77
77
|
"serverRunner": "thread",
|
|
78
78
|
"transpilation": {
|
|
79
|
+
"include": "only-modern",
|
|
79
80
|
"loader": "babel",
|
|
80
81
|
},
|
|
81
82
|
"viewTransitions": false,
|
|
@@ -152,6 +153,7 @@ it('should populate defaults for config', () => {
|
|
|
152
153
|
"minifier": "terser",
|
|
153
154
|
"reactCompiler": false,
|
|
154
155
|
"transpilation": {
|
|
156
|
+
"include": "only-modern",
|
|
155
157
|
"loader": "babel",
|
|
156
158
|
},
|
|
157
159
|
"webpack": {
|
|
@@ -325,6 +327,7 @@ it('should populate defaults for overridable options', () => {
|
|
|
325
327
|
"runtimeChunk": false,
|
|
326
328
|
"serverRunner": "thread",
|
|
327
329
|
"transpilation": {
|
|
330
|
+
"include": "only-modern",
|
|
328
331
|
"loader": {
|
|
329
332
|
"development": "swc",
|
|
330
333
|
"production": "babel",
|
|
@@ -419,6 +422,7 @@ it('should populate defaults for overridable options', () => {
|
|
|
419
422
|
"minifier": "terser",
|
|
420
423
|
"reactCompiler": false,
|
|
421
424
|
"transpilation": {
|
|
425
|
+
"include": "only-modern",
|
|
422
426
|
"loader": {
|
|
423
427
|
"development": "babel",
|
|
424
428
|
"production": "babel",
|