@tramvai/cli 5.45.2 → 5.47.0

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 (56) hide show
  1. package/lib/library/babel/index.d.ts +1 -1
  2. package/lib/library/babel/index.d.ts.map +1 -1
  3. package/lib/library/babel/index.js +12 -27
  4. package/lib/library/babel/index.js.map +1 -1
  5. package/lib/library/swc/index.d.ts.map +1 -1
  6. package/lib/library/swc/index.js +9 -22
  7. package/lib/library/swc/index.js.map +1 -1
  8. package/lib/library/webpack/application/client/common.d.ts.map +1 -1
  9. package/lib/library/webpack/application/client/common.js +6 -1
  10. package/lib/library/webpack/application/client/common.js.map +1 -1
  11. package/lib/library/webpack/blocks/serverInline.d.ts.map +1 -1
  12. package/lib/library/webpack/blocks/serverInline.js +7 -1
  13. package/lib/library/webpack/blocks/serverInline.js.map +1 -1
  14. package/lib/library/webpack/plugins/PolyfillCondition.d.ts +8 -0
  15. package/lib/library/webpack/plugins/PolyfillCondition.d.ts.map +1 -0
  16. package/lib/library/webpack/plugins/PolyfillCondition.js +46 -0
  17. package/lib/library/webpack/plugins/PolyfillCondition.js.map +1 -0
  18. package/lib/library/webpack/utils/polyfills/const.d.ts +3 -0
  19. package/lib/library/webpack/utils/polyfills/const.d.ts.map +1 -0
  20. package/lib/library/webpack/utils/polyfills/const.js +49 -0
  21. package/lib/library/webpack/utils/polyfills/const.js.map +1 -0
  22. package/lib/library/webpack/utils/polyfills/polyfillCondition.d.ts +8 -0
  23. package/lib/library/webpack/utils/polyfills/polyfillCondition.d.ts.map +1 -0
  24. package/lib/library/webpack/utils/polyfills/polyfillCondition.js +51 -0
  25. package/lib/library/webpack/utils/polyfills/polyfillCondition.js.map +1 -0
  26. package/lib/library/webpack/utils/polyfills/specToFeature.d.ts +7 -0
  27. package/lib/library/webpack/utils/polyfills/specToFeature.d.ts.map +1 -0
  28. package/lib/library/webpack/utils/polyfills/specToFeature.js +207 -0
  29. package/lib/library/webpack/utils/polyfills/specToFeature.js.map +1 -0
  30. package/lib/library/webpack/utils/transpiler.d.ts +14 -0
  31. package/lib/library/webpack/utils/transpiler.d.ts.map +1 -1
  32. package/lib/library/webpack/utils/transpiler.js +25 -3
  33. package/lib/library/webpack/utils/transpiler.js.map +1 -1
  34. package/lib/schema/autogeneratedSchema.json +3 -6
  35. package/lib/typings/configEntry/cli.d.ts +1 -2
  36. package/lib/typings/configEntry/cli.d.ts.map +1 -1
  37. package/package.json +5 -3
  38. package/schema.json +3 -6
  39. package/src/library/babel/index.ts +14 -32
  40. package/src/library/babel/plugins/lazy-component/lazy-component.spec.ts +2 -1
  41. package/src/library/babel/plugins/lazy-component/legacy-universal-replace.spec.ts +2 -1
  42. package/src/library/swc/__integration__/__snapshots__/swc.build.test.ts.snap +20 -13
  43. package/src/library/swc/__integration__/__snapshots__/swc.start.test.ts.snap +13 -16
  44. package/src/library/swc/__integration__/server.inline.ts +4 -0
  45. package/src/library/swc/index.ts +11 -28
  46. package/src/library/webpack/application/client/common.ts +7 -1
  47. package/src/library/webpack/blocks/serverInline.ts +7 -1
  48. package/src/library/webpack/plugins/PolyfillCondition.ts +62 -0
  49. package/src/library/webpack/utils/polyfills/__integration__/__snapshots__/condition.test.ts.snap +1348 -0
  50. package/src/library/webpack/utils/polyfills/__integration__/condition.test.ts +128 -0
  51. package/src/library/webpack/utils/polyfills/const.ts +46 -0
  52. package/src/library/webpack/utils/polyfills/polyfillCondition.ts +63 -0
  53. package/src/library/webpack/utils/polyfills/specToFeature.ts +243 -0
  54. package/src/library/webpack/utils/transpiler.ts +44 -2
  55. package/src/schema/autogeneratedSchema.json +3 -6
  56. package/src/typings/configEntry/cli.ts +1 -2
@@ -414,6 +414,11 @@ class ForBrowser {
414
414
  test() {
415
415
  console.log("Ok");
416
416
  }
417
+ constructor(){
418
+ (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__._)(this, "property", ()=>{
419
+ console.log("Ok");
420
+ });
421
+ }
417
422
  }
418
423
  (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__._)(ForBrowser, "prop", "static");
419
424
 
@@ -730,28 +735,20 @@ exports[`server: server.inline.ts 1`] = `
730
735
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
731
736
  /* harmony export */ ForBrowser: function() { return /* binding */ ForBrowser; }
732
737
  /* harmony export */ });
733
- /* harmony import */ var _swc_helpers_class_call_check__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("../../node_modules/@swc/helpers/esm/_class_call_check.js");
734
- /* harmony import */ var _swc_helpers_create_class__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("../../node_modules/@swc/helpers/esm/_create_class.js");
735
- /* harmony import */ var _swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("../../node_modules/@swc/helpers/esm/_define_property.js");
736
-
737
-
738
-
739
738
  var ForBrowser = /*#__PURE__*/ function() {
740
739
  "use strict";
741
740
  function ForBrowser() {
742
- (0,_swc_helpers_class_call_check__WEBPACK_IMPORTED_MODULE_0__._)(this, ForBrowser);
741
+ this.property = function() {
742
+ console.log("Ok");
743
+ };
743
744
  }
744
- (0,_swc_helpers_create_class__WEBPACK_IMPORTED_MODULE_1__._)(ForBrowser, [
745
- {
746
- key: "test",
747
- value: function test() {
748
- console.log("Ok");
749
- }
750
- }
751
- ]);
745
+ var _proto = ForBrowser.prototype;
746
+ _proto.test = function test() {
747
+ console.log("Ok");
748
+ };
752
749
  return ForBrowser;
753
750
  }();
754
- (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_2__._)(ForBrowser, "prop", "static");
751
+ ForBrowser.prop = "static";
755
752
 
756
753
 
757
754
  "
@@ -1,6 +1,10 @@
1
1
  export class ForBrowser {
2
2
  static prop = 'static';
3
3
 
4
+ property = () => {
5
+ console.log('Ok');
6
+ };
7
+
4
8
  test() {
5
9
  console.log('Ok');
6
10
  }
@@ -1,8 +1,6 @@
1
1
  import isEmpty from '@tinkoff/utils/is/empty';
2
2
  import path from 'path';
3
3
  import { existsSync } from 'fs';
4
- import browserslist from 'browserslist';
5
- import envTargets from '@tinkoff/browserslist-config';
6
4
  import { sync as resolve } from 'resolve';
7
5
  import findCacheDir from 'find-cache-dir';
8
6
  import type { Options as SwcOptions } from '@swc/core';
@@ -16,16 +14,21 @@ let warningWasShown = false;
16
14
  export const getSwcOptions = (config: TranspilerConfig): SwcOptions => {
17
15
  const {
18
16
  env = 'development',
19
- target,
20
- modern,
21
17
  isServer = false,
22
18
  modules = false,
19
+ excludesPresetEnv,
20
+ browsersListTargets,
23
21
  typescript = false,
24
22
  hot = false,
25
23
  removeTypeofWindow,
26
24
  tramvai = false,
27
25
  rootDir = process.cwd(),
28
26
  generateDataQaTag = false,
27
+ // disabled because `arrayLikeIsIterable` and `iterableIsArray` assumtions is not supported yet in swc,
28
+ // this can leads to incorrect code generation e.g. when Set with spread is used - `[...new Set()] => [].concat(new Set())`
29
+ // TCORE-4904
30
+ loose = false,
31
+ externalHelpers = true,
29
32
  } = config;
30
33
 
31
34
  if (!warningWasShown) {
@@ -77,37 +80,17 @@ Having swc config may conflict with @tramvai/cli configuration`
77
80
  }
78
81
  }
79
82
 
80
- let resultTarget = target;
81
-
82
- if (!target) {
83
- if (isServer) {
84
- resultTarget = 'node';
85
- } else if (modern) {
86
- resultTarget = 'modern';
87
- }
88
- }
89
-
90
- const browserslistConfigRaw = browserslist.findConfig(rootDir);
91
-
92
- // выставляем дефолты если явный конфиг для browserslist не был найден или в нём нет нужного targets
93
- const browserslistQuery =
94
- browserslistConfigRaw?.[resultTarget] ?? envTargets[resultTarget] ?? envTargets.defaults;
95
-
96
- const targets = browserslist(browserslistQuery, {
97
- mobileToDesktop: true,
98
- env: resultTarget,
99
- });
100
-
101
83
  return {
102
84
  env: {
103
- targets,
85
+ targets: browsersListTargets,
104
86
  // Use relevant core-js version, because it affects which polyfills are included
105
87
  // https://github.com/swc-project/swc/blob/main/crates/swc_ecma_preset_env/data/core-js-compat/modules-by-versions.json
106
88
  coreJs: require('core-js/package.json').version,
107
89
  // disabled because `arrayLikeIsIterable` and `iterableIsArray` assumtions is not supported yet in swc,
108
90
  // this can leads to incorrect code generation e.g. when Set with spread is used - `[...new Set()] => [].concat(new Set())`
109
91
  // TCORE-4904
110
- loose: false,
92
+ loose,
93
+ exclude: excludesPresetEnv,
111
94
  mode: 'entry',
112
95
  },
113
96
  module: {
@@ -115,7 +98,7 @@ Having swc config may conflict with @tramvai/cli configuration`
115
98
  },
116
99
  isModule: 'unknown',
117
100
  jsc: {
118
- externalHelpers: true,
101
+ externalHelpers,
119
102
  parser: {
120
103
  syntax: typescript ? 'typescript' : 'ecmascript',
121
104
  decorators: true,
@@ -27,6 +27,7 @@ import {
27
27
  WEBPACK_DEBUG_STATS_FIELDS,
28
28
  } from '../../constants/stats';
29
29
  import { pwaBlock } from '../../blocks/pwa/client';
30
+ import PolyfillConditionPlugin from '../../plugins/PolyfillCondition';
30
31
 
31
32
  export default (configManager: ConfigManager<ApplicationConfigEntry>) => (config: Config) => {
32
33
  const { polyfill, fileSystemPages, env } = configManager;
@@ -59,11 +60,13 @@ export default (configManager: ConfigManager<ApplicationConfigEntry>) => (config
59
60
  .when(portalExists, (cfg) => cfg.entry('portal').add(portal))
60
61
  .when(polyfillExists, (cfg) => cfg.entry('polyfill').add(polyfillPath));
61
62
 
63
+ const statsFileName = configManager.modern ? 'stats.modern.json' : 'stats.json';
64
+
62
65
  config
63
66
  .plugin('stats-plugin')
64
67
  .use(StatsWriterPlugin, [
65
68
  {
66
- filename: configManager.modern ? 'stats.modern.json' : 'stats.json',
69
+ filename: statsFileName,
67
70
  stats: {
68
71
  ...(env === 'development' ? DEV_STATS_OPTIONS : DEFAULT_STATS_OPTIONS),
69
72
  ...(configManager.verboseWebpack ? WEBPACK_DEBUG_STATS_OPTIONS : {}),
@@ -75,6 +78,9 @@ export default (configManager: ConfigManager<ApplicationConfigEntry>) => (config
75
78
  },
76
79
  ])
77
80
  .end()
81
+ .plugin('polyfill-condition-plugin')
82
+ .use(PolyfillConditionPlugin, [{ filename: statsFileName }])
83
+ .end()
78
84
  .plugin('define')
79
85
  .tap((args) => [
80
86
  {
@@ -17,7 +17,13 @@ export const serverInline = (configManager: ConfigManager<CliConfigEntry>) => (c
17
17
  .batch(
18
18
  addTranspilerLoader(
19
19
  clientConfigManager,
20
- getTranspilerConfig(clientConfigManager, { typescript: type === 'ts' })
20
+ getTranspilerConfig(clientConfigManager, {
21
+ typescript: type === 'ts',
22
+ // inline transpiler runtime helpers to prevent webpack imports in generated inline scripts
23
+ externalHelpers: false,
24
+ // minimize swc helpers usage to prevent inline scripts bloat, risks is minimal for rarely used inline scripts
25
+ loose: true,
26
+ })
21
27
  )
22
28
  );
23
29
  };
@@ -0,0 +1,62 @@
1
+ import {
2
+ getPolyfillCondition,
3
+ getMaxBrowserVersionsByFeatures,
4
+ } from '../utils/polyfills/polyfillCondition';
5
+
6
+ const TARGET_PLUGIN_NAME = 'stats-writer-plugin';
7
+
8
+ export default class PolyfillConditionPlugin {
9
+ constructor(private options: { filename: string }) {
10
+ this.options = options;
11
+ }
12
+
13
+ apply(compiler) {
14
+ compiler.hooks.thisCompilation.tap(TARGET_PLUGIN_NAME, (compilation) => {
15
+ compilation.hooks.processAssets.tap(
16
+ {
17
+ name: TARGET_PLUGIN_NAME,
18
+ stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT,
19
+ },
20
+ () => {
21
+ const { entrypoints } = compilation;
22
+ const polyfillEntrypoint = entrypoints.get('polyfill');
23
+
24
+ // If no polyfill entrypoint presented do nothing
25
+ if (!polyfillEntrypoint) return;
26
+
27
+ const polyfillChunk = polyfillEntrypoint.getEntrypointChunk();
28
+ const polyfillModules = compilation.chunkGraph.getChunkModulesIterable(polyfillChunk);
29
+ const coreJsModules = [];
30
+
31
+ for (const module of polyfillModules) {
32
+ if (module.resource && /\/core-js\/modules\//.test(module.resource)) {
33
+ coreJsModules.push(module);
34
+ }
35
+ }
36
+
37
+ const features = coreJsModules.map((module) =>
38
+ getFeatureNameFromModulePath(module.resource)
39
+ );
40
+
41
+ const browserVersionsByFeatures = getMaxBrowserVersionsByFeatures(features);
42
+ const polyfillCondition = getPolyfillCondition(browserVersionsByFeatures);
43
+ const { filename } = this.options;
44
+ const statsJSON = JSON.parse(compilation.assets[filename].source().toString());
45
+
46
+ statsJSON.polyfillCondition = polyfillCondition;
47
+ statsJSON.features = browserVersionsByFeatures;
48
+
49
+ compilation.updateAsset(
50
+ filename,
51
+ new compiler.webpack.sources.RawSource(JSON.stringify(statsJSON))
52
+ );
53
+ }
54
+ );
55
+ });
56
+ }
57
+ }
58
+
59
+ // node_modules/core-js/modules/es.array.push.js => es.array.push
60
+ function getFeatureNameFromModulePath(modulePath) {
61
+ return modulePath.split('/').at(-1).replace(/\.js$/, '');
62
+ }