@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.
Files changed (196) hide show
  1. package/README.md +1 -1
  2. package/bin/const.js +5 -0
  3. package/bin/platform.js +12 -6
  4. package/bin/spawn.js +6 -0
  5. package/lib/api/analyze/index.d.ts.map +1 -1
  6. package/lib/api/analyze/index.js +1 -13
  7. package/lib/api/analyze/index.js.map +1 -1
  8. package/lib/api/benchmark/build.d.ts +1 -6
  9. package/lib/api/benchmark/build.d.ts.map +1 -1
  10. package/lib/api/benchmark/build.js +59 -23
  11. package/lib/api/benchmark/build.js.map +1 -1
  12. package/lib/api/benchmark/const.d.ts +2 -0
  13. package/lib/api/benchmark/const.d.ts.map +1 -0
  14. package/lib/api/benchmark/const.js +5 -0
  15. package/lib/api/benchmark/const.js.map +1 -0
  16. package/lib/api/benchmark/index.d.ts +4 -6
  17. package/lib/api/benchmark/index.d.ts.map +1 -1
  18. package/lib/api/benchmark/index.js.map +1 -1
  19. package/lib/api/benchmark/start.d.ts +1 -7
  20. package/lib/api/benchmark/start.d.ts.map +1 -1
  21. package/lib/api/benchmark/start.js +56 -49
  22. package/lib/api/benchmark/start.js.map +1 -1
  23. package/lib/api/benchmark/types.d.ts +76 -12
  24. package/lib/api/benchmark/types.d.ts.map +1 -1
  25. package/lib/api/benchmark/utils/compilationUtils.d.ts +4 -0
  26. package/lib/api/benchmark/utils/compilationUtils.d.ts.map +1 -0
  27. package/lib/api/benchmark/utils/compilationUtils.js +157 -0
  28. package/lib/api/benchmark/utils/compilationUtils.js.map +1 -0
  29. package/lib/api/benchmark/utils/stats.d.ts +2 -7
  30. package/lib/api/benchmark/utils/stats.d.ts.map +1 -1
  31. package/lib/api/benchmark/utils/stats.js +36 -22
  32. package/lib/api/benchmark/utils/stats.js.map +1 -1
  33. package/lib/api/build/index.d.ts +1 -0
  34. package/lib/api/build/index.d.ts.map +1 -1
  35. package/lib/api/build/index.js.map +1 -1
  36. package/lib/api/index.js +1 -1
  37. package/lib/api/index.js.map +1 -1
  38. package/lib/api/start/index.d.ts +1 -0
  39. package/lib/api/start/index.d.ts.map +1 -1
  40. package/lib/api/start/index.js.map +1 -1
  41. package/lib/builder/webpack/analyzePlugins/rsdoctor.d.ts +5 -5
  42. package/lib/builder/webpack/analyzePlugins/rsdoctor.d.ts.map +1 -1
  43. package/lib/builder/webpack/analyzePlugins/rsdoctor.js +7 -9
  44. package/lib/builder/webpack/analyzePlugins/rsdoctor.js.map +1 -1
  45. package/lib/builder/webpack/index.d.ts.map +1 -1
  46. package/lib/builder/webpack/index.js +14 -12
  47. package/lib/builder/webpack/index.js.map +1 -1
  48. package/lib/builder/webpack/providers/build/client.d.ts.map +1 -1
  49. package/lib/builder/webpack/providers/build/client.js +3 -2
  50. package/lib/builder/webpack/providers/build/client.js.map +1 -1
  51. package/lib/builder/webpack/providers/build/server.d.ts.map +1 -1
  52. package/lib/builder/webpack/providers/build/server.js +3 -2
  53. package/lib/builder/webpack/providers/build/server.js.map +1 -1
  54. package/lib/builder/webpack/providers/shared.d.ts.map +1 -1
  55. package/lib/builder/webpack/providers/shared.js +39 -5
  56. package/lib/builder/webpack/providers/shared.js.map +1 -1
  57. package/lib/builder/webpack/providers/start/shared.d.ts.map +1 -1
  58. package/lib/builder/webpack/providers/start/shared.js +6 -2
  59. package/lib/builder/webpack/providers/start/shared.js.map +1 -1
  60. package/lib/builder/webpack/tokens.d.ts +10 -16
  61. package/lib/builder/webpack/tokens.d.ts.map +1 -1
  62. package/lib/cli/index.d.ts.map +1 -1
  63. package/lib/cli/index.js +12 -12
  64. package/lib/cli/index.js.map +1 -1
  65. package/lib/commands/analyze/command.d.ts +1 -1
  66. package/lib/commands/analyze/command.d.ts.map +1 -1
  67. package/lib/commands/benchmark/benchmark.d.ts +3 -1
  68. package/lib/commands/benchmark/benchmark.d.ts.map +1 -1
  69. package/lib/commands/benchmark/benchmark.js +130 -31
  70. package/lib/commands/benchmark/benchmark.js.map +1 -1
  71. package/lib/commands/benchmark/command.d.ts +9 -0
  72. package/lib/commands/benchmark/command.d.ts.map +1 -1
  73. package/lib/commands/benchmark/command.js +12 -0
  74. package/lib/commands/benchmark/command.js.map +1 -1
  75. package/lib/commands/build/command.d.ts.map +1 -1
  76. package/lib/commands/build/command.js +5 -0
  77. package/lib/commands/build/command.js.map +1 -1
  78. package/lib/commands/start/command.d.ts.map +1 -1
  79. package/lib/commands/start/command.js +5 -0
  80. package/lib/commands/start/command.js.map +1 -1
  81. package/lib/commands/update/checkVersionValidator.d.ts +1 -1
  82. package/lib/commands/update/checkVersionValidator.d.ts.map +1 -1
  83. package/lib/commands/update/checkVersionValidator.js +3 -2
  84. package/lib/commands/update/checkVersionValidator.js.map +1 -1
  85. package/lib/commands/update/command.d.ts +1 -1
  86. package/lib/commands/update/dependantLibs.d.ts +1 -1
  87. package/lib/commands/update/dependantLibs.d.ts.map +1 -1
  88. package/lib/commands/update/dependantLibs.js +3 -2
  89. package/lib/commands/update/dependantLibs.js.map +1 -1
  90. package/lib/commands/update/update.d.ts.map +1 -1
  91. package/lib/commands/update/update.js +6 -3
  92. package/lib/commands/update/update.js.map +1 -1
  93. package/lib/commands/update/updatePackageJson.d.ts +1 -1
  94. package/lib/commands/update/updatePackageJson.d.ts.map +1 -1
  95. package/lib/commands/update/updatePackageJson.js +7 -7
  96. package/lib/commands/update/updatePackageJson.js.map +1 -1
  97. package/lib/config/configManager.d.ts +2 -0
  98. package/lib/config/configManager.d.ts.map +1 -1
  99. package/lib/config/configManager.js +2 -0
  100. package/lib/config/configManager.js.map +1 -1
  101. package/lib/di/tokens/config.d.ts +5 -8
  102. package/lib/di/tokens/config.d.ts.map +1 -1
  103. package/lib/library/webpack/blocks/css.d.ts.map +1 -1
  104. package/lib/library/webpack/blocks/css.js +42 -15
  105. package/lib/library/webpack/blocks/css.js.map +1 -1
  106. package/lib/library/webpack/blocks/js.d.ts.map +1 -1
  107. package/lib/library/webpack/blocks/js.js +57 -11
  108. package/lib/library/webpack/blocks/js.js.map +1 -1
  109. package/lib/library/webpack/common/main.d.ts.map +1 -1
  110. package/lib/library/webpack/common/main.js +7 -0
  111. package/lib/library/webpack/common/main.js.map +1 -1
  112. package/lib/library/webpack/utils/browserslist.d.ts +4 -0
  113. package/lib/library/webpack/utils/browserslist.d.ts.map +1 -0
  114. package/lib/library/webpack/utils/browserslist.js +27 -0
  115. package/lib/library/webpack/utils/browserslist.js.map +1 -0
  116. package/lib/library/webpack/utils/rsdoctor.d.ts +2 -0
  117. package/lib/library/webpack/utils/rsdoctor.d.ts.map +1 -0
  118. package/lib/library/webpack/utils/rsdoctor.js +27 -0
  119. package/lib/library/webpack/utils/rsdoctor.js.map +1 -0
  120. package/lib/library/webpack/utils/threadLoader.d.ts.map +1 -1
  121. package/lib/library/webpack/utils/threadLoader.js +3 -3
  122. package/lib/library/webpack/utils/threadLoader.js.map +1 -1
  123. package/lib/library/webpack/utils/transpiler.d.ts.map +1 -1
  124. package/lib/library/webpack/utils/transpiler.js +3 -16
  125. package/lib/library/webpack/utils/transpiler.js.map +1 -1
  126. package/lib/schema/autogeneratedSchema.json +240 -120
  127. package/lib/typings/build/Builder.d.ts +6 -2
  128. package/lib/typings/build/Builder.d.ts.map +1 -1
  129. package/lib/typings/configEntry/cli.d.ts +9 -0
  130. package/lib/typings/configEntry/cli.d.ts.map +1 -1
  131. package/lib/utils/commands/dependencies/getLatestPackageVersion.d.ts +1 -1
  132. package/lib/utils/commands/dependencies/getLatestPackageVersion.d.ts.map +1 -1
  133. package/lib/utils/commands/dependencies/getLatestPackageVersion.js +4 -2
  134. package/lib/utils/commands/dependencies/getLatestPackageVersion.js.map +1 -1
  135. package/lib/utils/commands/dependencies/packageHasVersion.d.ts +1 -1
  136. package/lib/utils/commands/dependencies/packageHasVersion.d.ts.map +1 -1
  137. package/lib/utils/commands/dependencies/packageHasVersion.js +3 -2
  138. package/lib/utils/commands/dependencies/packageHasVersion.js.map +1 -1
  139. package/package.json +19 -18
  140. package/schema.json +240 -120
  141. package/src/api/analyze/index.ts +3 -16
  142. package/src/api/benchmark/__integration__/start.test.ts +10 -12
  143. package/src/api/benchmark/build.ts +75 -30
  144. package/src/api/benchmark/const.ts +1 -0
  145. package/src/api/benchmark/index.ts +4 -6
  146. package/src/api/benchmark/start.ts +69 -65
  147. package/src/api/benchmark/types.ts +82 -14
  148. package/src/api/benchmark/utils/compilationUtils.ts +213 -0
  149. package/src/api/benchmark/utils/stats.ts +45 -28
  150. package/src/api/build/index.ts +1 -0
  151. package/src/api/index.ts +1 -1
  152. package/src/api/start/index.ts +1 -0
  153. package/src/builder/webpack/analyzePlugins/rsdoctor.ts +11 -14
  154. package/src/builder/webpack/index.ts +16 -21
  155. package/src/builder/webpack/providers/build/client.ts +7 -2
  156. package/src/builder/webpack/providers/build/server.ts +7 -2
  157. package/src/builder/webpack/providers/shared.ts +53 -5
  158. package/src/builder/webpack/providers/start/shared.ts +7 -2
  159. package/src/cli/index.ts +3 -2
  160. package/src/commands/analyze/command.ts +1 -1
  161. package/src/commands/benchmark/benchmark.ts +168 -33
  162. package/src/commands/benchmark/command.ts +12 -0
  163. package/src/commands/build/command.ts +6 -0
  164. package/src/commands/new/templates/shared/package.json.hbs +1 -1
  165. package/src/commands/start/command.ts +6 -0
  166. package/src/commands/update/checkVersionValidator.ts +4 -2
  167. package/src/commands/update/dependantLibs.ts +3 -1
  168. package/src/commands/update/update.ts +6 -3
  169. package/src/commands/update/updatePackageJson.spec.ts +19 -3
  170. package/src/commands/update/updatePackageJson.ts +7 -2
  171. package/src/config/configManager.ts +4 -0
  172. package/src/library/webpack/blocks/css.ts +52 -16
  173. package/src/library/webpack/blocks/js.ts +61 -12
  174. package/src/library/webpack/common/main.ts +8 -0
  175. package/src/library/webpack/utils/browserslist.ts +29 -0
  176. package/src/library/webpack/utils/rsdoctor.ts +26 -0
  177. package/src/library/webpack/utils/threadLoader.ts +1 -0
  178. package/src/library/webpack/utils/transpiler.ts +3 -18
  179. package/src/models/config.spec.ts +4 -0
  180. package/src/schema/autogeneratedSchema.json +240 -120
  181. package/src/schema/tramvai.spec.ts +2 -0
  182. package/src/typings/build/Builder.ts +7 -2
  183. package/src/typings/configEntry/cli.ts +11 -0
  184. package/src/utils/commands/dependencies/getLatestPackageVersion.ts +4 -1
  185. package/src/utils/commands/dependencies/packageHasVersion.ts +7 -2
  186. package/lib/api/analyze/providers/shared.d.ts +0 -3
  187. package/lib/api/analyze/providers/shared.d.ts.map +0 -1
  188. package/lib/api/analyze/providers/shared.js +0 -23
  189. package/lib/api/analyze/providers/shared.js.map +0 -1
  190. package/lib/builder/webpack/providers/analyze/shared.d.ts +0 -3
  191. package/lib/builder/webpack/providers/analyze/shared.d.ts.map +0 -1
  192. package/lib/builder/webpack/providers/analyze/shared.js +0 -141
  193. package/lib/builder/webpack/providers/analyze/shared.js.map +0 -1
  194. package/src/api/analyze/providers/shared.ts +0 -26
  195. package/src/api/benchmark/utils/stats.spec.ts +0 -36
  196. package/src/builder/webpack/providers/analyze/shared.ts +0 -160
@@ -6,15 +6,11 @@ const FIXTURES_DIR = resolve(__dirname, '__fixtures__');
6
6
  jest.useRealTimers();
7
7
  jest.setTimeout(120000);
8
8
 
9
- const matchStats = {
10
- samples: expect.any(Array),
11
- mean: expect.any(Number),
12
- std: expect.any(Number),
13
- variance: expect.any(Number),
14
- };
15
- const matchFullStats = {
16
- client: matchStats,
17
- server: matchStats,
9
+ const compilationStats = {
10
+ // TODO: not working in CI, loaders field in report is empty: TCORE-5363
11
+ // loaderBuildCosts: expect.any(Object),
12
+ totalBuildCosts: expect.any(Object),
13
+ pluginBuildCosts: expect.any(Object),
18
14
  };
19
15
 
20
16
  describe('@tramvai/cli benchmark command', () => {
@@ -31,9 +27,11 @@ describe('@tramvai/cli benchmark command', () => {
31
27
  });
32
28
 
33
29
  expect(result).toMatchObject({
34
- cache: matchFullStats,
35
- noCache: matchFullStats,
36
- rebuild: matchFullStats,
30
+ clientBuildTime: expect.any(Number),
31
+ serverBuildTime: expect.any(Number),
32
+ clientCompilationStats: compilationStats,
33
+ serverCompilationStats: compilationStats,
34
+ maxMemoryRss: expect.any(Number),
37
35
  });
38
36
  });
39
37
  });
@@ -1,21 +1,19 @@
1
+ /* eslint-disable max-statements */
1
2
  import type { Container } from '@tinkoff/dippy';
2
3
  import type { Params as OriginalBuildParams, Result as OriginalBuildResult } from '../build/index';
3
4
  import { COMMAND_PARAMETERS_TOKEN, COMMAND_RUNNER_TOKEN } from '../../di/tokens';
4
5
  import type { Params, Result } from './index';
5
- import type { Samples, RunStats } from './types';
6
+ import type { Samples, RunStats, CompilationStats } from './types';
6
7
  import { clearCacheDirectory } from './utils/clearCache';
7
8
  import { getResultStats } from './utils/stats';
9
+ import { getClientCompilationTimings, getServerCompilationTimings } from './utils/compilationUtils';
10
+ import { DEFAULT_TIMES } from './const';
8
11
 
9
12
  export interface BuildParams extends Params {
10
13
  command: 'build';
11
14
  commandOptions: OriginalBuildParams;
12
15
  }
13
16
 
14
- export interface BuildResult extends Result {
15
- noCache?: RunStats;
16
- cache?: RunStats;
17
- }
18
-
19
17
  const runBuildCommand = async (
20
18
  di: Container,
21
19
  {
@@ -26,49 +24,96 @@ const runBuildCommand = async (
26
24
  shouldClearCache: boolean;
27
25
  }
28
26
  ): Promise<Samples> => {
29
- const clientSamples: number[] = Array(times);
30
- const serverSamples: number[] = Array(times);
31
- const maxMemoryRssSamples: number[] = Array(times);
27
+ const clientBuildTimeSamples: number[] = [];
28
+ const serverBuildTimeSamples: number[] = [];
29
+
30
+ const clientMaxMemoryRssSamples: number[] = [];
31
+ const serverMaxMemoryRssSamples: number[] = [];
32
+
33
+ const serverCompilationTimings: CompilationStats[] = [];
34
+ const clientCompilationTimings: CompilationStats[] = [];
35
+
36
+ const maxMemoryRssSamples: number[] = [];
32
37
 
33
38
  const { commandOptions } = di.get(COMMAND_PARAMETERS_TOKEN) as BuildParams;
39
+ commandOptions.benchmark = true;
40
+
41
+ const buildType = commandOptions.buildType ?? 'all';
42
+
43
+ const benchmarkStartTime = new Date().toISOString();
34
44
 
35
45
  for (let i = 0; i < times; i++) {
36
46
  if (shouldClearCache) {
37
47
  await clearCacheDirectory(di);
38
48
  }
39
49
 
40
- const { getBuildStats: getStats } = await (di
50
+ const attemptStartTime = Date.now();
51
+ const { getBuildStats } = await (di
41
52
  .get(COMMAND_RUNNER_TOKEN)
42
53
  .run('build', commandOptions) as OriginalBuildResult);
43
- const stats = getStats();
54
+ const stats = getBuildStats();
55
+
56
+ // at first attempt do not save metrics if cache is used
57
+ if (!shouldClearCache && i === 0) {
58
+ continue;
59
+ }
60
+
61
+ if (buildType === 'all' || buildType === 'server') {
62
+ serverCompilationTimings.push(
63
+ await getServerCompilationTimings(benchmarkStartTime, attemptStartTime, i)
64
+ );
65
+ serverBuildTimeSamples.push(stats.server.buildTime);
44
66
 
45
- clientSamples[i] = stats.clientBuildTime;
46
- serverSamples[i] = stats.serverBuildTime;
47
- maxMemoryRssSamples[i] = stats.maxMemoryRss;
67
+ if (stats.server.maxMemoryRss) {
68
+ clientMaxMemoryRssSamples.push(stats.server.maxMemoryRss);
69
+ }
70
+ }
71
+
72
+ if (buildType === 'all' || buildType === 'client') {
73
+ clientCompilationTimings.push(
74
+ await getClientCompilationTimings(benchmarkStartTime, attemptStartTime, i)
75
+ );
76
+ clientBuildTimeSamples.push(stats.client.buildTime);
77
+
78
+ if (stats.client.maxMemoryRss) {
79
+ clientMaxMemoryRssSamples.push(stats.client.maxMemoryRss);
80
+ }
81
+ }
82
+
83
+ if (stats.maxMemoryRss) {
84
+ maxMemoryRssSamples.push(stats.maxMemoryRss);
85
+ }
48
86
  }
49
87
 
50
88
  return {
51
- clientSamples,
52
- serverSamples,
89
+ serverCompilationTimings,
90
+ clientCompilationTimings,
91
+ clientBuildTimeSamples,
92
+ serverBuildTimeSamples,
53
93
  maxMemoryRssSamples,
94
+ clientMaxMemoryRssSamples,
95
+ serverMaxMemoryRssSamples,
54
96
  };
55
97
  };
56
98
 
57
- export const benchmarkBuild = async (di: Container): Promise<BuildResult> => {
58
- const { times = 5 } = di.get(COMMAND_PARAMETERS_TOKEN) as Params;
99
+ export const benchmarkBuild = async (di: Container): Promise<Result> => {
100
+ const { times = DEFAULT_TIMES, commandOptions } = di.get(COMMAND_PARAMETERS_TOKEN) as Params;
101
+ const noCache = !commandOptions.fileCache;
59
102
 
60
- const noCache = await runBuildCommand(di, {
61
- times: Math.max(Math.floor(times / 2), 2),
62
- shouldClearCache: true,
63
- });
103
+ let result;
64
104
 
65
- const cache = await runBuildCommand(di, {
66
- times,
67
- shouldClearCache: false,
68
- });
105
+ if (noCache) {
106
+ result = await runBuildCommand(di, {
107
+ times,
108
+ shouldClearCache: true,
109
+ });
110
+ } else {
111
+ result = await runBuildCommand(di, {
112
+ // additional first attempt for cache warmup
113
+ times: times + 1,
114
+ shouldClearCache: false,
115
+ });
116
+ }
69
117
 
70
- return {
71
- cache: getResultStats(cache),
72
- noCache: getResultStats(noCache),
73
- };
118
+ return getResultStats(result);
74
119
  };
@@ -0,0 +1 @@
1
+ export const DEFAULT_TIMES = 3;
@@ -1,9 +1,9 @@
1
1
  import type { Provider } from '@tinkoff/dippy';
2
2
  import { createCommand } from '../../commands/createCommand';
3
3
  import { COMMAND_PARAMETERS_TOKEN, WITH_BUILD_STATS_TOKEN } from '../../di/tokens';
4
- import type { BuildParams, BuildResult } from './build';
4
+ import type { BuildParams } from './build';
5
5
  import { benchmarkBuild } from './build';
6
- import type { StartParams, StartResult } from './start';
6
+ import type { StartParams } from './start';
7
7
  import { benchmarkStart } from './start';
8
8
  import type { RunStats } from './types';
9
9
 
@@ -13,14 +13,12 @@ export interface Params {
13
13
  times?: number;
14
14
  }
15
15
 
16
- export interface Result {
17
- [key: string]: RunStats | undefined;
18
- }
16
+ export type Result = RunStats;
19
17
 
20
18
  export type BenchmarkCommand = (
21
19
  params: StartParams | BuildParams,
22
20
  providers?: Provider[]
23
- ) => Promise<StartResult | BuildResult>;
21
+ ) => Promise<Result>;
24
22
 
25
23
  export default createCommand({
26
24
  name: 'benchmark',
@@ -1,24 +1,19 @@
1
+ /* eslint-disable max-statements */
1
2
  import type { Container } from '@tinkoff/dippy';
2
3
  import type { Params as OriginalStartParams, Result as OriginalStartResult } from '../start/index';
3
4
  import { COMMAND_PARAMETERS_TOKEN, COMMAND_RUNNER_TOKEN } from '../../di/tokens';
4
5
  import type { Params, Result } from './index';
5
- import type { Samples, RunStats } from './types';
6
+ import type { Samples, CompilationStats } from './types';
6
7
  import { clearCacheDirectory } from './utils/clearCache';
7
8
  import { getResultStats } from './utils/stats';
8
-
9
- const REBUILD_WARMUP_TIMES = 3;
9
+ import { getClientCompilationTimings, getServerCompilationTimings } from './utils/compilationUtils';
10
+ import { DEFAULT_TIMES } from './const';
10
11
 
11
12
  export interface StartParams extends Params {
12
13
  command: 'start';
13
14
  commandOptions: OriginalStartParams;
14
15
  }
15
16
 
16
- export interface StartResult extends Result {
17
- noCache?: RunStats;
18
- cache?: RunStats;
19
- rebuild?: RunStats;
20
- }
21
-
22
17
  const runStartCommand = async (
23
18
  di: Container,
24
19
  {
@@ -29,17 +24,29 @@ const runStartCommand = async (
29
24
  shouldClearCache: boolean;
30
25
  }
31
26
  ): Promise<Samples> => {
32
- const clientSamples: number[] = Array(times);
33
- const serverSamples: number[] = Array(times);
34
- const maxMemoryRssSamples: number[] = Array(times);
27
+ const clientBuildTimeSamples: number[] = [];
28
+ const serverBuildTimeSamples: number[] = [];
29
+ const clientMaxMemoryRssSamples: number[] = [];
30
+ const serverMaxMemoryRssSamples: number[] = [];
31
+
32
+ const serverCompilationTimings: CompilationStats[] = [];
33
+ const clientCompilationTimings: CompilationStats[] = [];
34
+
35
+ const maxMemoryRssSamples: number[] = [];
35
36
 
36
37
  const { commandOptions } = di.get(COMMAND_PARAMETERS_TOKEN) as StartParams;
38
+ commandOptions.benchmark = true;
39
+
40
+ const buildType = commandOptions.buildType ?? 'all';
41
+
42
+ const benchmarkStartTime = new Date().toISOString();
37
43
 
38
44
  for (let i = 0; i < times; i++) {
39
45
  if (shouldClearCache) {
40
46
  await clearCacheDirectory(di);
41
47
  }
42
48
 
49
+ const attemptStartTime = Date.now();
43
50
  const { close, getBuildStats } = await (di
44
51
  .get(COMMAND_RUNNER_TOKEN)
45
52
  .run('start', commandOptions) as OriginalStartResult);
@@ -47,70 +54,67 @@ const runStartCommand = async (
47
54
 
48
55
  await close();
49
56
 
50
- clientSamples[i] = stats.clientBuildTime;
51
- serverSamples[i] = stats.serverBuildTime;
52
- maxMemoryRssSamples[i] = stats.maxMemoryRss;
53
- }
54
-
55
- return {
56
- clientSamples,
57
- serverSamples,
58
- maxMemoryRssSamples,
59
- };
60
- };
61
-
62
- const runRebuild = async (di: Container, { times }: { times: number }): Promise<Samples> => {
63
- const clientSamples: number[] = Array(times);
64
- const serverSamples: number[] = Array(times);
65
- const maxMemoryRssSamples: number[] = Array(times);
66
- const { commandOptions } = di.get(COMMAND_PARAMETERS_TOKEN) as StartParams;
57
+ // at first attempt do not save metrics if cache is used
58
+ if (!shouldClearCache && i === 0) {
59
+ continue;
60
+ }
67
61
 
68
- const { close, invalidate, getBuildStats } = await (di
69
- .get(COMMAND_RUNNER_TOKEN)
70
- .run('start', commandOptions) as OriginalStartResult);
62
+ if (buildType === 'all' || buildType === 'server') {
63
+ serverCompilationTimings.push(
64
+ await getServerCompilationTimings(benchmarkStartTime, attemptStartTime, i)
65
+ );
66
+ serverBuildTimeSamples.push(stats.server.buildTime);
71
67
 
72
- // warmup rebuild as it usually pretty slow at first runs
73
- for (let i = 0; i < REBUILD_WARMUP_TIMES; i++) {
74
- await invalidate();
75
- }
68
+ if (stats.server.maxMemoryRss) {
69
+ serverMaxMemoryRssSamples.push(stats.server.maxMemoryRss);
70
+ }
71
+ }
76
72
 
77
- for (let i = 0; i < times; i++) {
78
- await invalidate();
73
+ if (buildType === 'all' || buildType === 'client') {
74
+ clientCompilationTimings.push(
75
+ await getClientCompilationTimings(benchmarkStartTime, attemptStartTime, i)
76
+ );
77
+ clientBuildTimeSamples.push(stats.client.buildTime);
79
78
 
80
- const stats = getBuildStats();
79
+ if (stats.client.maxMemoryRss) {
80
+ clientMaxMemoryRssSamples.push(stats.client.maxMemoryRss);
81
+ }
82
+ }
81
83
 
82
- clientSamples[i] = stats.clientBuildTime;
83
- serverSamples[i] = stats.serverBuildTime;
84
- maxMemoryRssSamples[i] = stats.maxMemoryRss;
84
+ if (stats.maxMemoryRss) {
85
+ maxMemoryRssSamples.push(stats.maxMemoryRss);
86
+ }
85
87
  }
86
88
 
87
- await close();
88
-
89
89
  return {
90
- clientSamples,
91
- serverSamples,
90
+ serverCompilationTimings,
91
+ clientCompilationTimings,
92
+ clientMaxMemoryRssSamples,
93
+ serverMaxMemoryRssSamples,
94
+ clientBuildTimeSamples,
95
+ serverBuildTimeSamples,
92
96
  maxMemoryRssSamples,
93
97
  };
94
98
  };
95
99
 
96
- export const benchmarkStart = async (di: Container): Promise<StartResult> => {
97
- const { times = 5 } = di.get(COMMAND_PARAMETERS_TOKEN) as Params;
98
-
99
- const noCache = await runStartCommand(di, {
100
- times: Math.max(Math.floor(times / 3), 2),
101
- shouldClearCache: true,
102
- });
103
-
104
- const cache = await runStartCommand(di, {
105
- times: Math.max(Math.floor(times / 2), 2),
106
- shouldClearCache: false,
107
- });
108
-
109
- const rebuild = await runRebuild(di, { times });
100
+ export const benchmarkStart = async (di: Container): Promise<Result> => {
101
+ const { times = DEFAULT_TIMES, commandOptions } = di.get(COMMAND_PARAMETERS_TOKEN) as Params;
102
+ const noCache = !commandOptions.fileCache;
103
+
104
+ let result;
105
+
106
+ if (noCache) {
107
+ result = await runStartCommand(di, {
108
+ times,
109
+ shouldClearCache: true,
110
+ });
111
+ } else {
112
+ result = await runStartCommand(di, {
113
+ // additional first attempt for cache warmup
114
+ times: times + 1,
115
+ shouldClearCache: false,
116
+ });
117
+ }
110
118
 
111
- return {
112
- cache: getResultStats(cache),
113
- noCache: getResultStats(noCache),
114
- rebuild: getResultStats(rebuild),
115
- };
119
+ return getResultStats(result);
116
120
  };
@@ -1,19 +1,87 @@
1
- export interface Stats {
2
- samples: number[];
3
- mean: number;
4
- std: number;
5
-
6
- variance: number;
7
- }
8
-
9
1
  export type Samples = {
10
- clientSamples: Stats['samples'];
11
- serverSamples: Stats['samples'];
12
- maxMemoryRssSamples: Stats['samples'];
2
+ serverCompilationTimings: CompilationStats[];
3
+ serverBuildTimeSamples: number[];
4
+ clientCompilationTimings: CompilationStats[];
5
+ clientBuildTimeSamples: number[];
6
+ maxMemoryRssSamples: number[];
7
+ clientMaxMemoryRssSamples: number[];
8
+ serverMaxMemoryRssSamples: number[];
9
+ };
10
+
11
+ export type CompilationStats = {
12
+ totalBuildCosts: Record<string, number>;
13
+ loaderBuildCosts: Record<string, number>;
14
+ pluginBuildCosts: Record<string, number>;
13
15
  };
14
16
 
15
17
  export type RunStats = {
16
- client: Stats;
17
- server: Stats;
18
- maxMemoryRss: Stats;
18
+ serverCompilationStats: CompilationStats | undefined;
19
+ clientCompilationStats: CompilationStats | undefined;
20
+ clientBuildTime: number | undefined;
21
+ serverBuildTime: number | undefined;
22
+ clientMaxMemoryRss: number | undefined;
23
+ serverMaxMemoryRss: number | undefined;
24
+ maxMemoryRss: number | undefined;
25
+ };
26
+
27
+ type PlainObject<T = any> = {
28
+ [key: string]: T;
19
29
  };
30
+
31
+ interface ProcessData {
32
+ /**
33
+ * process id
34
+ */
35
+ pid: number;
36
+ /**
37
+ * parent process id
38
+ */
39
+ ppid: number | null;
40
+ }
41
+
42
+ export interface LoaderTransformData extends ProcessData {
43
+ /** loader name */
44
+ loader: string;
45
+ /**
46
+ * loader index
47
+ */
48
+ loaderIndex: number;
49
+ /** loader path */
50
+ path: string;
51
+ input: string | null | undefined;
52
+ /**
53
+ * - isPitch: true: the result of loader.pitch()
54
+ * - isPitch: false: the code result of loader()
55
+ */
56
+ result: string | null | undefined;
57
+ /** Timestamp when called */
58
+ startAt: number;
59
+ endAt: number;
60
+ /** loader configuration */
61
+ options: PlainObject;
62
+ /** pitching loader */
63
+ isPitch: boolean;
64
+ /**
65
+ * is sync
66
+ */
67
+ sync: boolean;
68
+ /** Error during conversion */
69
+ // errors: DevToolErrorInstance[];
70
+ /** module layer */
71
+ layer?: string;
72
+ }
73
+
74
+ export type MinimalLoaderData = Pick<LoaderTransformData, 'startAt' | 'endAt' | 'pid' | 'loader'>;
75
+
76
+ export interface PluginData {
77
+ /** hook tap name */
78
+ tapName: string;
79
+ /** hook call time-consuming */
80
+ costs: number;
81
+ startAt: number;
82
+ endAt: number;
83
+ /** hook function type */
84
+ type: 'sync' | 'async' | 'promise';
85
+ /** hook function result */
86
+ result: any;
87
+ }