@tramvai/cli 2.119.5 → 2.121.2

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 (43) hide show
  1. package/lib/builder/webpack/devServer/server.js +10 -0
  2. package/lib/builder/webpack/devServer/server.js.map +1 -1
  3. package/lib/builder/webpack/tokens.d.ts +3 -0
  4. package/lib/config/configManager.js +12 -13
  5. package/lib/config/configManager.js.map +1 -1
  6. package/lib/di/tokens/config.d.ts +1 -0
  7. package/lib/library/webpack/application/client/dev.js +6 -14
  8. package/lib/library/webpack/application/client/dev.js.map +1 -1
  9. package/lib/library/webpack/application/client/prod/optimization/splitChunks.js +14 -1
  10. package/lib/library/webpack/application/client/prod/optimization/splitChunks.js.map +1 -1
  11. package/lib/library/webpack/blocks/configToEnv.js +6 -3
  12. package/lib/library/webpack/blocks/configToEnv.js.map +1 -1
  13. package/lib/library/webpack/blocks/pwa/client.js +24 -2
  14. package/lib/library/webpack/blocks/pwa/client.js.map +1 -1
  15. package/lib/library/webpack/common/main.js +3 -1
  16. package/lib/library/webpack/common/main.js.map +1 -1
  17. package/lib/library/webpack/plugins/PwaIconsPlugin.d.ts +3 -1
  18. package/lib/library/webpack/plugins/PwaIconsPlugin.js +7 -6
  19. package/lib/library/webpack/plugins/PwaIconsPlugin.js.map +1 -1
  20. package/lib/library/webpack/plugins/WebManifestPlugin.d.ts +6 -2
  21. package/lib/library/webpack/plugins/WebManifestPlugin.js +23 -3
  22. package/lib/library/webpack/plugins/WebManifestPlugin.js.map +1 -1
  23. package/lib/schema/autogeneratedSchema.json +43 -16
  24. package/lib/typings/configEntry/cli.d.ts +7 -0
  25. package/lib/typings/pwa/index.d.ts +1 -1
  26. package/package.json +5 -5
  27. package/schema.json +43 -16
  28. package/src/api/start/__integration__/__fixtures__/app/server.tsx +1 -0
  29. package/src/api/start/__integration__/start.test.ts +2 -0
  30. package/src/builder/webpack/devServer/server.ts +13 -0
  31. package/src/config/configManager.ts +10 -13
  32. package/src/library/webpack/application/client/dev.ts +9 -17
  33. package/src/library/webpack/application/client/prod/optimization/splitChunks.ts +18 -1
  34. package/src/library/webpack/blocks/configToEnv.ts +6 -2
  35. package/src/library/webpack/blocks/pwa/client.ts +36 -2
  36. package/src/library/webpack/common/main.ts +3 -1
  37. package/src/library/webpack/plugins/PwaIconsPlugin.ts +14 -7
  38. package/src/library/webpack/plugins/WebManifestPlugin.ts +35 -5
  39. package/src/models/config.spec.ts +4 -0
  40. package/src/schema/autogeneratedSchema.json +43 -16
  41. package/src/schema/tramvai.spec.ts +2 -0
  42. package/src/typings/configEntry/cli.ts +7 -0
  43. package/src/typings/pwa/index.ts +1 -1
@@ -652,7 +652,7 @@
652
652
  "type": "boolean"
653
653
  },
654
654
  "dest": {
655
- "title": "Name of generated manifest file (will be placed in \"output.client\" directory). You can use `[hash]` placeholder for manifest cache busting",
655
+ "title": "Name of generated manifest file (will be placed in \"output.client\" directory). You can use `[hash]` placeholder for manifest cache busting in production mode",
656
656
  "default": "/manifest.[hash].json",
657
657
  "type": "string"
658
658
  },
@@ -1122,23 +1122,23 @@
1122
1122
  "dotAll": {
1123
1123
  "type": "boolean"
1124
1124
  },
1125
- "__@match@8167": {
1125
+ "__@match@8168": {
1126
1126
  "type": "object",
1127
1127
  "additionalProperties": false
1128
1128
  },
1129
- "__@replace@8169": {
1129
+ "__@replace@8170": {
1130
1130
  "type": "object",
1131
1131
  "additionalProperties": false
1132
1132
  },
1133
- "__@search@8172": {
1133
+ "__@search@8173": {
1134
1134
  "type": "object",
1135
1135
  "additionalProperties": false
1136
1136
  },
1137
- "__@split@8174": {
1137
+ "__@split@8175": {
1138
1138
  "type": "object",
1139
1139
  "additionalProperties": false
1140
1140
  },
1141
- "__@matchAll@8176": {
1141
+ "__@matchAll@8177": {
1142
1142
  "type": "object",
1143
1143
  "additionalProperties": false
1144
1144
  }
@@ -1344,6 +1344,15 @@
1344
1344
  "default": true,
1345
1345
  "type": "boolean"
1346
1346
  },
1347
+ "criticalChunks": {
1348
+ "title": "add chunks to preload as critical in-parallel with \"platform.js\"",
1349
+ "description": "this option is useful when you need to create async boundary for app dependencies.\nMore info - https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption",
1350
+ "default": [],
1351
+ "type": "array",
1352
+ "items": {
1353
+ "type": "string"
1354
+ }
1355
+ },
1347
1356
  "deps": {
1348
1357
  "title": "list of the dependencies that will be shared",
1349
1358
  "default": [],
@@ -1755,23 +1764,23 @@
1755
1764
  "dotAll": {
1756
1765
  "type": "boolean"
1757
1766
  },
1758
- "__@match@8167": {
1767
+ "__@match@8168": {
1759
1768
  "type": "object",
1760
1769
  "additionalProperties": false
1761
1770
  },
1762
- "__@replace@8169": {
1771
+ "__@replace@8170": {
1763
1772
  "type": "object",
1764
1773
  "additionalProperties": false
1765
1774
  },
1766
- "__@search@8172": {
1775
+ "__@search@8173": {
1767
1776
  "type": "object",
1768
1777
  "additionalProperties": false
1769
1778
  },
1770
- "__@split@8174": {
1779
+ "__@split@8175": {
1771
1780
  "type": "object",
1772
1781
  "additionalProperties": false
1773
1782
  },
1774
- "__@matchAll@8176": {
1783
+ "__@matchAll@8177": {
1775
1784
  "type": "object",
1776
1785
  "additionalProperties": false
1777
1786
  }
@@ -1977,6 +1986,15 @@
1977
1986
  "default": true,
1978
1987
  "type": "boolean"
1979
1988
  },
1989
+ "criticalChunks": {
1990
+ "title": "add chunks to preload as critical in-parallel with \"platform.js\"",
1991
+ "description": "this option is useful when you need to create async boundary for app dependencies.\nMore info - https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption",
1992
+ "default": [],
1993
+ "type": "array",
1994
+ "items": {
1995
+ "type": "string"
1996
+ }
1997
+ },
1980
1998
  "deps": {
1981
1999
  "title": "list of the dependencies that will be shared",
1982
2000
  "default": [],
@@ -2388,23 +2406,23 @@
2388
2406
  "dotAll": {
2389
2407
  "type": "boolean"
2390
2408
  },
2391
- "__@match@8167": {
2409
+ "__@match@8168": {
2392
2410
  "type": "object",
2393
2411
  "additionalProperties": false
2394
2412
  },
2395
- "__@replace@8169": {
2413
+ "__@replace@8170": {
2396
2414
  "type": "object",
2397
2415
  "additionalProperties": false
2398
2416
  },
2399
- "__@search@8172": {
2417
+ "__@search@8173": {
2400
2418
  "type": "object",
2401
2419
  "additionalProperties": false
2402
2420
  },
2403
- "__@split@8174": {
2421
+ "__@split@8175": {
2404
2422
  "type": "object",
2405
2423
  "additionalProperties": false
2406
2424
  },
2407
- "__@matchAll@8176": {
2425
+ "__@matchAll@8177": {
2408
2426
  "type": "object",
2409
2427
  "additionalProperties": false
2410
2428
  }
@@ -2610,6 +2628,15 @@
2610
2628
  "default": true,
2611
2629
  "type": "boolean"
2612
2630
  },
2631
+ "criticalChunks": {
2632
+ "title": "add chunks to preload as critical in-parallel with \"platform.js\"",
2633
+ "description": "this option is useful when you need to create async boundary for app dependencies.\nMore info - https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption",
2634
+ "default": [],
2635
+ "type": "array",
2636
+ "items": {
2637
+ "type": "string"
2638
+ }
2639
+ },
2613
2640
  "deps": {
2614
2641
  "title": "list of the dependencies that will be shared",
2615
2642
  "default": [],
@@ -284,6 +284,13 @@ export interface CliConfigEntry extends ConfigEntry {
284
284
  * @default true
285
285
  */
286
286
  flexibleTramvaiVersions: boolean;
287
+ /**
288
+ * @title add chunks to preload as critical in-parallel with "platform.js"
289
+ * @description this option is useful when you need to create async boundary for app dependencies.
290
+ * More info - https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption
291
+ * @default []
292
+ */
293
+ criticalChunks: string[];
287
294
  /**
288
295
  * @title list of the dependencies that will be shared
289
296
  * @default []
@@ -5,7 +5,7 @@ export type WebManifestOptions = {
5
5
  */
6
6
  enabled?: boolean;
7
7
  /**
8
- * @title Name of generated manifest file (will be placed in "output.client" directory). You can use `[hash]` placeholder for manifest cache busting
8
+ * @title Name of generated manifest file (will be placed in "output.client" directory). You can use `[hash]` placeholder for manifest cache busting in production mode
9
9
  * @default "/manifest.[hash].json"
10
10
  */
11
11
  dest?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tramvai/cli",
3
- "version": "2.119.5",
3
+ "version": "2.121.2",
4
4
  "description": "Cli инструмент для сборки и запуска приложений",
5
5
  "files": [
6
6
  "src",
@@ -63,7 +63,7 @@
63
63
  "@tinkoff/browserslist-config": "0.2.5",
64
64
  "@tinkoff/dippy": "0.8.15",
65
65
  "@tinkoff/is-modern-lib": "2.0.10",
66
- "@tinkoff/logger": "0.10.63",
66
+ "@tinkoff/logger": "0.10.64",
67
67
  "@tinkoff/minicss-class-generator": "0.2.5",
68
68
  "@tinkoff/package-manager-wrapper": "0.1.9",
69
69
  "@tinkoff/request-core": "^0.9.2",
@@ -71,9 +71,9 @@
71
71
  "@tinkoff/utils": "^2.1.3",
72
72
  "@tinkoff/webpack-dedupe-plugin": "1.0.5",
73
73
  "@tramvai/build": "3.1.3",
74
- "@tramvai/react": "2.119.5",
75
- "@tramvai/tools-check-versions": "0.4.14",
76
- "@tramvai/tools-migrate": "0.6.18",
74
+ "@tramvai/react": "2.121.2",
75
+ "@tramvai/tools-check-versions": "0.4.15",
76
+ "@tramvai/tools-migrate": "0.6.19",
77
77
  "ajv": "^6.12.6",
78
78
  "ansi-escapes": "^4.3.2",
79
79
  "autoprefixer": "^10.4.8",
package/schema.json CHANGED
@@ -673,7 +673,7 @@
673
673
  "type": "boolean"
674
674
  },
675
675
  "dest": {
676
- "title": "Name of generated manifest file (will be placed in \"output.client\" directory). You can use `[hash]` placeholder for manifest cache busting",
676
+ "title": "Name of generated manifest file (will be placed in \"output.client\" directory). You can use `[hash]` placeholder for manifest cache busting in production mode",
677
677
  "default": "/manifest.[hash].json",
678
678
  "type": "string"
679
679
  },
@@ -1143,23 +1143,23 @@
1143
1143
  "dotAll": {
1144
1144
  "type": "boolean"
1145
1145
  },
1146
- "__@match@8167": {
1146
+ "__@match@8168": {
1147
1147
  "type": "object",
1148
1148
  "additionalProperties": false
1149
1149
  },
1150
- "__@replace@8169": {
1150
+ "__@replace@8170": {
1151
1151
  "type": "object",
1152
1152
  "additionalProperties": false
1153
1153
  },
1154
- "__@search@8172": {
1154
+ "__@search@8173": {
1155
1155
  "type": "object",
1156
1156
  "additionalProperties": false
1157
1157
  },
1158
- "__@split@8174": {
1158
+ "__@split@8175": {
1159
1159
  "type": "object",
1160
1160
  "additionalProperties": false
1161
1161
  },
1162
- "__@matchAll@8176": {
1162
+ "__@matchAll@8177": {
1163
1163
  "type": "object",
1164
1164
  "additionalProperties": false
1165
1165
  }
@@ -1365,6 +1365,15 @@
1365
1365
  "default": true,
1366
1366
  "type": "boolean"
1367
1367
  },
1368
+ "criticalChunks": {
1369
+ "title": "add chunks to preload as critical in-parallel with \"platform.js\"",
1370
+ "description": "this option is useful when you need to create async boundary for app dependencies.\nMore info - https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption",
1371
+ "default": [],
1372
+ "type": "array",
1373
+ "items": {
1374
+ "type": "string"
1375
+ }
1376
+ },
1368
1377
  "deps": {
1369
1378
  "title": "list of the dependencies that will be shared",
1370
1379
  "default": [],
@@ -1784,23 +1793,23 @@
1784
1793
  "dotAll": {
1785
1794
  "type": "boolean"
1786
1795
  },
1787
- "__@match@8167": {
1796
+ "__@match@8168": {
1788
1797
  "type": "object",
1789
1798
  "additionalProperties": false
1790
1799
  },
1791
- "__@replace@8169": {
1800
+ "__@replace@8170": {
1792
1801
  "type": "object",
1793
1802
  "additionalProperties": false
1794
1803
  },
1795
- "__@search@8172": {
1804
+ "__@search@8173": {
1796
1805
  "type": "object",
1797
1806
  "additionalProperties": false
1798
1807
  },
1799
- "__@split@8174": {
1808
+ "__@split@8175": {
1800
1809
  "type": "object",
1801
1810
  "additionalProperties": false
1802
1811
  },
1803
- "__@matchAll@8176": {
1812
+ "__@matchAll@8177": {
1804
1813
  "type": "object",
1805
1814
  "additionalProperties": false
1806
1815
  }
@@ -2006,6 +2015,15 @@
2006
2015
  "default": true,
2007
2016
  "type": "boolean"
2008
2017
  },
2018
+ "criticalChunks": {
2019
+ "title": "add chunks to preload as critical in-parallel with \"platform.js\"",
2020
+ "description": "this option is useful when you need to create async boundary for app dependencies.\nMore info - https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption",
2021
+ "default": [],
2022
+ "type": "array",
2023
+ "items": {
2024
+ "type": "string"
2025
+ }
2026
+ },
2009
2027
  "deps": {
2010
2028
  "title": "list of the dependencies that will be shared",
2011
2029
  "default": [],
@@ -2425,23 +2443,23 @@
2425
2443
  "dotAll": {
2426
2444
  "type": "boolean"
2427
2445
  },
2428
- "__@match@8167": {
2446
+ "__@match@8168": {
2429
2447
  "type": "object",
2430
2448
  "additionalProperties": false
2431
2449
  },
2432
- "__@replace@8169": {
2450
+ "__@replace@8170": {
2433
2451
  "type": "object",
2434
2452
  "additionalProperties": false
2435
2453
  },
2436
- "__@search@8172": {
2454
+ "__@search@8173": {
2437
2455
  "type": "object",
2438
2456
  "additionalProperties": false
2439
2457
  },
2440
- "__@split@8174": {
2458
+ "__@split@8175": {
2441
2459
  "type": "object",
2442
2460
  "additionalProperties": false
2443
2461
  },
2444
- "__@matchAll@8176": {
2462
+ "__@matchAll@8177": {
2445
2463
  "type": "object",
2446
2464
  "additionalProperties": false
2447
2465
  }
@@ -2647,6 +2665,15 @@
2647
2665
  "default": true,
2648
2666
  "type": "boolean"
2649
2667
  },
2668
+ "criticalChunks": {
2669
+ "title": "add chunks to preload as critical in-parallel with \"platform.js\"",
2670
+ "description": "this option is useful when you need to create async boundary for app dependencies.\nMore info - https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption",
2671
+ "default": [],
2672
+ "type": "array",
2673
+ "items": {
2674
+ "type": "string"
2675
+ }
2676
+ },
2650
2677
  "deps": {
2651
2678
  "title": "list of the dependencies that will be shared",
2652
2679
  "default": [],
@@ -50,6 +50,7 @@ app.get<{ Querystring: Querystring }>(
50
50
  return `<html>
51
51
  <head>
52
52
  <link rel="stylesheet" href="http://localhost:${appConfig.staticPort}/dist/client/platform.css">
53
+ <script src="http://localhost:${appConfig.staticPort}/dist/client/react.js" defer></script>
53
54
  <script src="http://localhost:${appConfig.staticPort}/dist/client/hmr.js" defer></script>
54
55
  <script src="http://localhost:${appConfig.staticPort}/dist/client/platform.js" defer></script>
55
56
  </head>
@@ -79,6 +79,7 @@ describe('@tramvai/cli start command', () => {
79
79
 
80
80
  expect(responseServer.text)
81
81
  .toMatch(`<link rel="stylesheet" href="http://localhost:${staticServerPort}/dist/client/platform.css">
82
+ <script src="http://localhost:${staticServerPort}/dist/client/react.js" defer></script>
82
83
  <script src="http://localhost:${staticServerPort}/dist/client/hmr.js" defer></script>
83
84
  <script src="http://localhost:${staticServerPort}/dist/client/platform.js" defer></script>`);
84
85
  expect(responseServer.text).toMatch(`this is App`);
@@ -188,6 +189,7 @@ describe('@tramvai/cli start command', () => {
188
189
 
189
190
  expect(responseServer.text)
190
191
  .toMatch(`<link rel="stylesheet" href="http://localhost:${staticServerPort}/dist/client/platform.css">
192
+ <script src="http://localhost:${staticServerPort}/dist/client/react.js" defer></script>
191
193
  <script src="http://localhost:${staticServerPort}/dist/client/hmr.js" defer></script>
192
194
  <script src="http://localhost:${staticServerPort}/dist/client/platform.js" defer></script>`);
193
195
  expect(responseServer.text).toMatch(`this is App`);
@@ -86,6 +86,7 @@ export const serverRunner = ({
86
86
  let resolveWorkerPort: () => void | null;
87
87
  let workerPortPromise: Promise<void> | null;
88
88
  let hasExitedUnexpectedly = false;
89
+ let proxyErrorCount = 0;
89
90
 
90
91
  const proxy = createProxyServer({
91
92
  // указываем, что сами обработаем ответ
@@ -157,6 +158,8 @@ export const serverRunner = ({
157
158
  // делаем запросы к дочернему процессу и пытаемся полностью получить его ответ
158
159
  // если всё ок, то просто отправляем полученные данные клиенту
159
160
  proxy.on('proxyRes', (proxyRes, req, res) => {
161
+ proxyErrorCount--;
162
+
160
163
  if (!res.headersSent) {
161
164
  // дублируем всю логику прокси и отправляем ответ
162
165
  // немного костыль по мотивам https://github.com/http-party/node-http-proxy/issues/1263#issuecomment-394758768
@@ -197,7 +200,17 @@ export const serverRunner = ({
197
200
  return;
198
201
  }
199
202
 
203
+ if (proxyErrorCount > 10) {
204
+ console.error('[dev-server-error] looping of request proxying to worker', err);
205
+ // @ts-ignore
206
+ res.statusCode = 500;
207
+ res.end(EXITED_UNEXPECTEDLY);
208
+ return;
209
+ }
210
+
200
211
  if (pool.state !== PoolState.CLOSED) {
212
+ proxyErrorCount++;
213
+
201
214
  await waitWorkerPort();
202
215
 
203
216
  proxy.web(req, res as any, { target: `http://localhost:${workerPort}` });
@@ -197,13 +197,6 @@ export const createConfigManager = <C extends ConfigEntry = ConfigEntry, E exten
197
197
 
198
198
  if (pwa.webmanifest?.enabled) {
199
199
  pwa.webmanifest = {
200
- icons: pwa.icon?.src
201
- ? pwa.icon.sizes.map((size) => ({
202
- src: `${config.assetsPrefix}${pwa.icon.dest}/${size}x${size}.png`,
203
- sizes: `${size}x${size}`,
204
- type: 'image/png',
205
- }))
206
- : [],
207
200
  ...pwa.webmanifest,
208
201
  scope: pwa.webmanifest.scope ?? pwa.sw?.scope,
209
202
  name: pwa.webmanifest.name ?? config.name,
@@ -212,12 +205,16 @@ export const createConfigManager = <C extends ConfigEntry = ConfigEntry, E exten
212
205
  };
213
206
 
214
207
  if (pwa.webmanifest.dest.includes('[hash]')) {
215
- const crypto = require('crypto');
216
- const hashSum = crypto.createHash('sha256');
217
- hashSum.update(JSON.stringify(pwa.webmanifest));
218
- const currentHash = hashSum.digest('hex');
219
-
220
- pwa.webmanifest.dest = pwa.webmanifest.dest.replace('[hash]', currentHash.substr(0, 8));
208
+ if (env === 'production') {
209
+ const crypto = require('crypto');
210
+ const hashSum = crypto.createHash('sha256');
211
+ hashSum.update(JSON.stringify(pwa.webmanifest));
212
+ const currentHash = hashSum.digest('hex');
213
+
214
+ pwa.webmanifest.dest = pwa.webmanifest.dest.replace('[hash]', currentHash.substr(0, 8));
215
+ } else {
216
+ pwa.webmanifest.dest = pwa.webmanifest.dest.replace('.[hash]', '').replace('[hash].', '');
217
+ }
221
218
  }
222
219
  }
223
220
  } else if (isChildApp(config)) {
@@ -21,7 +21,7 @@ import sourcemaps from '../../blocks/sourcemaps';
21
21
  import FancyReporter from '../../plugins/WebpackBar/reporters/fancy';
22
22
  import { extendEntry } from '../../utils/extendEntry';
23
23
  import { extractCssPluginFactory } from '../../blocks/extractCssPlugin';
24
- import type { SplitChunksOptions } from '../../types/webpack';
24
+ import { splitChunksConfig } from './prod/optimization/splitChunks';
25
25
 
26
26
  // eslint-disable-next-line max-statements
27
27
  export const webpackClientConfig = ({
@@ -78,7 +78,12 @@ export const webpackClientConfig = ({
78
78
 
79
79
  config.optimization.set('emitOnErrors', false);
80
80
 
81
- config.batch(extractCssPluginFactory(configManager));
81
+ config.batch(
82
+ extractCssPluginFactory(configManager, {
83
+ filename: '[name].css',
84
+ chunkFilename: '[name].chunk.css',
85
+ })
86
+ );
82
87
 
83
88
  if (showProgress) {
84
89
  config.plugin('progress').use(WebpackBar, [
@@ -136,24 +141,11 @@ export const webpackClientConfig = ({
136
141
  },
137
142
  ]);
138
143
 
144
+ config.batch(splitChunksConfig(configManager));
145
+
139
146
  const { hotRefresh } = configManager;
140
147
 
141
148
  if (hotRefresh?.enabled) {
142
- const splitChunks: SplitChunksOptions = {
143
- cacheGroups: {
144
- default: false,
145
- defaultVendors: false,
146
- commons: {
147
- name: 'hmr',
148
- enforce: true,
149
- test: /[\\/]node_modules[\\/](react-refresh|webpack-hot-middleware|@pmmmwh[\\/]react-refresh-webpack-plugin)[\\/]/,
150
- chunks: 'all',
151
- },
152
- },
153
- };
154
-
155
- config.optimization.splitChunks(splitChunks).set('chunkIds', 'named');
156
-
157
149
  extendEntry(config.entry('platform'), {
158
150
  import: [
159
151
  'webpack-hot-middleware/client?name=client&dynamicPublicPath=true&path=__webpack_hmr',
@@ -73,7 +73,10 @@ export const splitChunksConfig =
73
73
  return false;
74
74
  }
75
75
 
76
- return topLevelFrameworkPaths.some((packagePath) => resource.startsWith(packagePath));
76
+ return (
77
+ !resource.startsWith('react-refresh') &&
78
+ topLevelFrameworkPaths.some((packagePath) => resource.startsWith(packagePath))
79
+ );
77
80
  },
78
81
  priority: 40,
79
82
  // Don't let webpack eliminate this chunk (prevents this chunk from becoming a part of the commons chunk)
@@ -96,6 +99,7 @@ export const splitChunksConfig =
96
99
  minChunks: splitChunks.granularChunksSplitNumber,
97
100
  minSize: splitChunks.granularChunksMinSize,
98
101
  reuseExistingChunk: true,
102
+ priority: 30,
99
103
  name(module: any, chunks: webpack.Chunk[]) {
100
104
  return crypto
101
105
  .createHash('sha1')
@@ -119,12 +123,25 @@ export const splitChunksConfig =
119
123
  commons: {
120
124
  name: 'common-chunk',
121
125
  minChunks: splitChunks.commonChunkSplitNumber,
126
+ priority: 30,
122
127
  },
123
128
  },
124
129
  };
125
130
  break;
126
131
  }
127
132
 
133
+ const { hotRefresh } = configManager;
134
+
135
+ if (hotRefresh?.enabled && webpackSplitChunks) {
136
+ webpackSplitChunks.cacheGroups.hmr = {
137
+ name: 'hmr',
138
+ enforce: true,
139
+ test: /[\\/]node_modules[\\/](react-refresh|webpack-hot-middleware|@pmmmwh[\\/]react-refresh-webpack-plugin)[\\/]/,
140
+ chunks: 'all',
141
+ priority: 20,
142
+ };
143
+ }
144
+
128
145
  config.optimization
129
146
  .splitChunks(webpackSplitChunks)
130
147
  // namedChunks должно быть включено, чтобы webpack-flush-chunks смог определить имена чанков от которых зависит чанк бандла после обработчки через splitChunks
@@ -5,9 +5,12 @@ import type { ConfigEntry } from '../../../typings/configEntry/common';
5
5
  import { shouldUseReactRoot } from '../../../utils/shouldUseReactRoot';
6
6
 
7
7
  export const configToEnv = (configManager: ConfigManager<ConfigEntry>) => (config: Config) => {
8
- const { fileSystemPages } = isApplication(configManager)
8
+ const { fileSystemPages, shared } = isApplication(configManager)
9
9
  ? configManager
10
- : { fileSystemPages: { enabled: false, routesDir: false, pagesDir: false } };
10
+ : {
11
+ fileSystemPages: { enabled: false, routesDir: false, pagesDir: false },
12
+ shared: { criticalChunks: [] },
13
+ };
11
14
 
12
15
  config.plugin('define').tap((args) => [
13
16
  {
@@ -22,6 +25,7 @@ export const configToEnv = (configManager: ConfigManager<ConfigEntry>) => (confi
22
25
  fileSystemPages.pagesDir
23
26
  ),
24
27
  'process.env.__TRAMVAI_CONCURRENT_FEATURES': JSON.stringify(shouldUseReactRoot()),
28
+ 'process.env.__TRAMVAI_CRITICAL_CHUNKS': `'${JSON.stringify(shared.criticalChunks)}'`,
25
29
  },
26
30
  ]);
27
31
  };
@@ -54,6 +54,25 @@ export const pwaBlock =
54
54
  // @todo CSR fallback or all static pages?
55
55
  // do not forget about revision and possible conflict with modifyURLPrefix
56
56
  ],
57
+ manifestTransforms: [
58
+ (manifest, compilation: any) => {
59
+ return {
60
+ // we need to have a relative webmanifest url for precaching
61
+ manifest: manifest.map((asset) => {
62
+ const assetName = asset.url.replace(assetsPrefix, '');
63
+ const assetInfo = compilation.assetsInfo.get(asset.url.replace(assetsPrefix, ''));
64
+
65
+ if (assetInfo._webmanifestFilename) {
66
+ return {
67
+ ...asset,
68
+ url: `${pwa.sw.scope}${assetName}`,
69
+ };
70
+ }
71
+ return asset;
72
+ }),
73
+ };
74
+ },
75
+ ],
57
76
  };
58
77
 
59
78
  if (pwa.workbox.include) {
@@ -104,18 +123,33 @@ export const pwaBlock =
104
123
  config.output.set('devtoolNamespace', 'tramvai');
105
124
  }
106
125
 
126
+ config.plugin('define').tap((args) => [
127
+ {
128
+ ...args[0],
129
+ 'process.env.ASSETS_PREFIX': JSON.stringify(assetsPrefix),
130
+ },
131
+ ]);
132
+
107
133
  config.plugin('workbox').use(workboxPlugin);
108
134
  }
109
135
 
110
136
  if (pwa.webmanifest?.enabled) {
111
- const webmanifestPlugin = new WebManifestPlugin(pwa.webmanifest);
137
+ const webmanifestPlugin = new WebManifestPlugin({
138
+ manifest: pwa.webmanifest,
139
+ icon: pwa.icon,
140
+ assetsPrefix,
141
+ });
112
142
 
113
143
  config.plugin('webmanifest').use(webmanifestPlugin);
114
144
  }
115
145
 
116
146
  if (pwa.icon?.src) {
117
147
  const iconSrc = path.join(rootDir, root, pwa.icon.src);
118
- const pwaIconsPlugin = new PwaIconsPlugin({ ...pwa.icon, src: iconSrc });
148
+ const pwaIconsPlugin = new PwaIconsPlugin({
149
+ ...pwa.icon,
150
+ src: iconSrc,
151
+ mode: configManager.env,
152
+ });
119
153
 
120
154
  config.plugin('pwa-icons').use(pwaIconsPlugin);
121
155
  }
@@ -99,7 +99,9 @@ export default (configManager: ConfigManager<CliConfigEntry>) => (config: Config
99
99
  ...configManager.define[configManager.env],
100
100
 
101
101
  'process.env.APP_ID': JSON.stringify(configManager.name || 'common'),
102
- 'process.env.APP_VERSION': JSON.stringify(process.env.APP_VERSION),
102
+ 'process.env.APP_VERSION': process.env.APP_VERSION
103
+ ? JSON.stringify(process.env.APP_VERSION)
104
+ : undefined,
103
105
 
104
106
  'process.env.ENABLE_DEVTOOLS':
105
107
  process.env.ENABLE_DEVTOOLS || configManager.env === 'development',