@gravity-ui/app-builder 0.15.1-beta.7 → 0.16.1

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 CHANGED
@@ -191,9 +191,13 @@ With this `{rootDir}/src/ui/tsconfig.json`:
191
191
  - `excludeFromClean` (`string[]`) — do not clean provided paths before build.
192
192
  - `forkTsCheker` (`false | ForkTsCheckerWebpackPluginOptions`) - config for ForkTsCheckerWebpackPlugin [more](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#options). If `false`, ForkTsCheckerWebpackPlugin will be disabled.
193
193
  - `cache` (`boolean | FileCacheOptions | MemoryCacheOptions`) — Cache the generated webpack modules and chunks to improve build speed. [more](https://webpack.js.org/configuration/cache/)
194
- - `babelCacheDirectory` (`boolean | string`) Set directory for babel-loader cache (`default: node_modules/.cache/babel-loader``)
194
+ - `bundler` (`'webpack' | 'rspack'`) - Option to choose a bundler.
195
+ - `javaScriptLoader` (`'babel' | 'swc'`) - Option to choose a JavaScript loader.
195
196
  - `babel` (`(config: babel.TransformOptions, options: {configType: 'development' | 'production'; isSsr: boolean}) => babel.TransformOptions | Promise<babel.TransformOptions>`) - Allow override the default babel transform options.
196
- - `webpack` (`(config: webpack.Configuration, options: {configType: 'development' | 'production'; isSsr: boolean}) => webpack.Configuration | Promise<webpack.Configuration>`) - Allow override the default configuration.
197
+ - `babelCacheDirectory` (`boolean | string`) Set directory for babel-loader cache (`default: node_modules/.cache/babel-loader``)
198
+ - `swc` (`(config: SwcConfig, options: {configType: 'development' | 'production'; isSsr: boolean}) => SwcConfig | Promise<SwcConfig>`) - Allow override the default swc configuration.
199
+ - `webpack` (`(config: webpack.Configuration, options: {configType: 'development' | 'production'; isSsr: boolean}) => webpack.Configuration | Promise<webpack.Configuration>`) - Allow override the default webpack configuration.
200
+ - `rspack` (`(config: rspack.Configuration, options: {configType: 'development' | 'production'; isSsr: boolean}) => rspack.Configuration | Promise<rspack.Configuration>`) - Allow override the default rspack configuration.
197
201
  - `ssr` - build SSR bundle. The SSR entries should be inside `src/ui/ssr` directory and match the client entries.
198
202
  - `noExternal` (`string | RegExp | (string | RegExp)[] | true`) - prevent listed dependencies from being externalized for SSR. By default, all dependencies are externalized.
199
203
  - `moduleType`: (`'commonjs' | 'esm'`) - library type for the SSR bundle, by default `commonjs`.
@@ -199,9 +199,11 @@ async function normalizeClientConfig(client, mode) {
199
199
  webpack: typeof client.webpack === 'function' ? client.webpack : (config) => config,
200
200
  rspack: typeof client.rspack === 'function' ? client.rspack : (config) => config,
201
201
  babel: typeof client.babel === 'function' ? client.babel : (config) => config,
202
+ swc: typeof client.swc === 'function' ? client.swc : (config) => config,
202
203
  devServer: undefined,
203
204
  lazyCompilation: undefined,
204
205
  bundler: client.bundler || 'webpack',
206
+ javaScriptLoader: client.javaScriptLoader || 'babel',
205
207
  };
206
208
  if (mode === 'dev') {
207
209
  if (client.lazyCompilation) {
@@ -2,9 +2,10 @@ import type { EditorLanguage } from 'monaco-editor-webpack-plugin/out/languages'
2
2
  import type { EditorFeature } from 'monaco-editor-webpack-plugin/out/features';
3
3
  import type { IFeatureDefinition } from 'monaco-editor-webpack-plugin/out/types';
4
4
  import type { Options as MomentTzOptions } from 'moment-timezone-data-webpack-plugin';
5
- import type { Configuration, DefinePlugin, FileCacheOptions, MemoryCacheOptions, ResolveOptions } from 'webpack';
5
+ import type { Configuration, DefinePlugin, FileCacheOptions, MemoryCacheOptions } from 'webpack';
6
6
  import type { Configuration as RspackConfiguration } from '@rspack/core';
7
7
  import type * as Babel from '@babel/core';
8
+ import type * as Swc from '@swc/types';
8
9
  import type { ServerConfiguration } from 'webpack-dev-server';
9
10
  import type { Options as CircularDependenciesOptions } from 'circular-dependency-plugin';
10
11
  import type { Config as SvgrConfig } from '@svgr/core';
@@ -16,6 +17,8 @@ import type { UploadOptions } from '../s3-upload/upload';
16
17
  import type { TerserOptions } from 'terser-webpack-plugin';
17
18
  import type { ReactRefreshPluginOptions } from '@pmmmwh/react-refresh-webpack-plugin/types/lib/types';
18
19
  type Bundler = 'webpack' | 'rspack';
20
+ type JavaScriptLoader = 'babel' | 'swc';
21
+ export type SwcConfig = Swc.Config & Pick<Swc.Options, 'isModule'>;
19
22
  export interface Entities<T> {
20
23
  data: Record<string, T>;
21
24
  keys: string[];
@@ -111,7 +114,9 @@ export interface ClientConfig {
111
114
  /**
112
115
  * Redirect module requests when normal resolving fails.
113
116
  */
114
- fallback?: ResolveOptions['fallback'];
117
+ fallback?: {
118
+ [index: string]: string | false | string[];
119
+ };
115
120
  /**
116
121
  * Follow symbolic links while looking for a file. [more](https://webpack.js.org/configuration/resolve/#resolvesymlinks)
117
122
  */
@@ -198,6 +203,13 @@ export interface ClientConfig {
198
203
  configType: `${WebpackMode}`;
199
204
  isSsr: boolean;
200
205
  }) => Babel.TransformOptions | Promise<Babel.TransformOptions>;
206
+ /**
207
+ * Modify or return a custom SWC config.
208
+ */
209
+ swc?: (config: SwcConfig, options: {
210
+ configType: `${WebpackMode}`;
211
+ isSsr: boolean;
212
+ }) => SwcConfig | Promise<SwcConfig>;
201
213
  /**
202
214
  * Modify or return a custom [Terser options](https://github.com/terser/terser#minify-options).
203
215
  */
@@ -207,6 +219,7 @@ export interface ClientConfig {
207
219
  moduleType?: 'commonjs' | 'esm';
208
220
  };
209
221
  bundler?: Bundler;
222
+ javaScriptLoader?: JavaScriptLoader;
210
223
  }
211
224
  export interface CdnUploadConfig {
212
225
  bucket: string;
@@ -236,6 +249,7 @@ export interface ServiceConfig {
236
249
  }
237
250
  export type NormalizedClientConfig = Omit<ClientConfig, 'publicPathPrefix' | 'hiddenSourceMap' | 'svgr' | 'lazyCompilation' | 'devServer' | 'disableForkTsChecker' | 'disableReactRefresh'> & {
238
251
  bundler: Bundler;
252
+ javaScriptLoader: JavaScriptLoader;
239
253
  publicPathPrefix: string;
240
254
  hiddenSourceMap: boolean;
241
255
  svgr: NonNullable<ClientConfig['svgr']>;
@@ -257,6 +271,10 @@ export type NormalizedClientConfig = Omit<ClientConfig, 'publicPathPrefix' | 'hi
257
271
  configType: `${WebpackMode}`;
258
272
  isSsr: boolean;
259
273
  }) => Babel.TransformOptions | Promise<Babel.TransformOptions>;
274
+ swc: (config: SwcConfig, options: {
275
+ configType: `${WebpackMode}`;
276
+ isSsr: boolean;
277
+ }) => SwcConfig | Promise<SwcConfig>;
260
278
  reactRefresh: NonNullable<ClientConfig['reactRefresh']>;
261
279
  };
262
280
  export type NormalizedServerConfig = Omit<ServerConfig, 'port' | 'inspect' | 'inspectBrk'> & {
@@ -1,5 +1,5 @@
1
1
  import * as webpack from 'webpack';
2
- import { Configuration as RspackConfiguration } from '@rspack/core';
2
+ import type * as Rspack from '@rspack/core';
3
3
  import type { NormalizedClientConfig } from '../models';
4
4
  import type { Logger } from '../logger';
5
5
  export interface HelperOptions {
@@ -23,9 +23,19 @@ type ClientFactoryOptions = {
23
23
  isSsr?: boolean;
24
24
  };
25
25
  export declare function webpackConfigFactory(options: ClientFactoryOptions): Promise<webpack.Configuration>;
26
- export declare function rspackConfigFactory(options: ClientFactoryOptions): Promise<RspackConfiguration>;
27
- export declare function configureModuleRules(helperOptions: HelperOptions, additionalRules?: NonNullable<webpack.RuleSetRule['oneOf']>): webpack.RuleSetRule[];
28
- export declare function configureResolve({ isEnvProduction, config }: HelperOptions): webpack.ResolveOptions;
26
+ export declare function rspackConfigFactory(options: ClientFactoryOptions): Promise<Rspack.Configuration>;
27
+ export declare function configureModuleRules(helperOptions: HelperOptions, additionalRules?: NonNullable<webpack.RuleSetRule['oneOf']>): Promise<webpack.RuleSetRule[]>;
28
+ export declare function configureResolve({ isEnvProduction, config }: HelperOptions): {
29
+ alias: {
30
+ [x: string]: string | string[];
31
+ };
32
+ modules: string[];
33
+ extensions: string[];
34
+ symlinks: boolean | undefined;
35
+ fallback: {
36
+ [index: string]: string | false | string[];
37
+ } | undefined;
38
+ };
29
39
  type Optimization = NonNullable<webpack.Configuration['optimization']>;
30
40
  export declare function configureOptimization(helperOptions: HelperOptions): Optimization;
31
41
  export {};
@@ -101,7 +101,7 @@ async function webpackConfigFactory(options) {
101
101
  output: configureOutput(helperOptions),
102
102
  resolve: configureResolve(helperOptions),
103
103
  module: {
104
- rules: configureModuleRules(helperOptions),
104
+ rules: await configureModuleRules(helperOptions),
105
105
  },
106
106
  plugins: configureWebpackPlugins(helperOptions),
107
107
  optimization: configureOptimization(helperOptions),
@@ -144,9 +144,9 @@ async function rspackConfigFactory(options) {
144
144
  devtool: configureDevTool(helperOptions),
145
145
  entry: configureEntry(helperOptions),
146
146
  output: configureOutput(helperOptions),
147
- resolve: configureRspackResolve(helperOptions),
147
+ resolve: configureResolve(helperOptions),
148
148
  module: {
149
- rules: configureModuleRules(helperOptions),
149
+ rules: (await configureModuleRules(helperOptions)),
150
150
  },
151
151
  plugins: configureRspackPlugins(helperOptions),
152
152
  optimization: configureRspackOptimization(helperOptions),
@@ -172,13 +172,13 @@ async function rspackConfigFactory(options) {
172
172
  }
173
173
  return rspackConfig;
174
174
  }
175
- function configureModuleRules(helperOptions, additionalRules = []) {
176
- const jsLoader = createJavaScriptLoader(helperOptions);
175
+ async function configureModuleRules(helperOptions, additionalRules = []) {
176
+ const jsLoader = await createJavaScriptLoader(helperOptions);
177
177
  return [
178
178
  ...createSourceMapRules(!helperOptions.config.disableSourceMapGeneration),
179
179
  {
180
180
  oneOf: [
181
- createWorkerRule(helperOptions),
181
+ await createWorkerRule(helperOptions),
182
182
  createJavaScriptRule(helperOptions, jsLoader),
183
183
  createStylesRule(helperOptions),
184
184
  createSassStylesRule(helperOptions),
@@ -313,16 +313,6 @@ function configureResolve({ isEnvProduction, config }) {
313
313
  fallback: config.fallback,
314
314
  };
315
315
  }
316
- function configureRspackResolve(helperOptions) {
317
- const { alias, modules, extensions, symlinks, fallback } = configureResolve(helperOptions);
318
- return {
319
- alias: Array.isArray(alias) ? undefined : alias,
320
- modules,
321
- extensions,
322
- symlinks,
323
- fallback: Array.isArray(fallback) ? undefined : fallback,
324
- };
325
- }
326
316
  function createEntryArray(entry) {
327
317
  return [require.resolve('./public-path'), entry];
328
318
  }
@@ -369,7 +359,61 @@ function configureOutput(options) {
369
359
  ...ssrOptions,
370
360
  };
371
361
  }
372
- function createJavaScriptLoader({ isEnvProduction, isEnvDevelopment, configType, config, isSsr, }) {
362
+ async function createJavaScriptLoader({ isEnvProduction, isEnvDevelopment, configType, config, isSsr, }) {
363
+ if (config.javaScriptLoader === 'swc') {
364
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
365
+ const plugins = [];
366
+ if (!isSsr && isEnvProduction) {
367
+ plugins.push([
368
+ require.resolve('@swc/plugin-transform-imports'),
369
+ {
370
+ lodash: { transform: 'lodash/{{member}}' },
371
+ },
372
+ ]);
373
+ }
374
+ const swcConfig = await config.swc({
375
+ module: {
376
+ type: 'es6',
377
+ },
378
+ env: {
379
+ targets: isSsr ? { node: process.versions.node } : require('browserslist')(),
380
+ mode: 'usage',
381
+ coreJs: '3.40',
382
+ bugfixes: true,
383
+ },
384
+ isModule: 'unknown',
385
+ jsc: {
386
+ parser: {
387
+ syntax: 'typescript',
388
+ tsx: true,
389
+ },
390
+ transform: {
391
+ react: {
392
+ runtime: config.newJsxTransform ? 'automatic' : 'classic',
393
+ development: isEnvDevelopment,
394
+ refresh: !isSsr && isEnvDevelopment && config.reactRefresh !== false,
395
+ useBuiltins: true,
396
+ },
397
+ optimizer: isEnvProduction
398
+ ? {
399
+ simplify: true,
400
+ jsonify: { minCost: 1024 },
401
+ }
402
+ : undefined,
403
+ },
404
+ assumptions: {
405
+ privateFieldsAsProperties: true,
406
+ setPublicClassFields: true,
407
+ },
408
+ experimental: { plugins },
409
+ },
410
+ sourceMaps: !config.disableSourceMapGeneration,
411
+ }, { configType, isSsr });
412
+ return {
413
+ loader: config.bundler === 'rspack' ? 'builtin:swc-loader' : require.resolve('swc-loader'),
414
+ options: swcConfig,
415
+ };
416
+ }
373
417
  const plugins = [];
374
418
  if (!isSsr) {
375
419
  if (isEnvDevelopment && config.reactRefresh !== false) {
@@ -391,7 +435,7 @@ function createJavaScriptLoader({ isEnvProduction, isEnvDevelopment, configType,
391
435
  ]);
392
436
  }
393
437
  }
394
- const transformOptions = config.babel({
438
+ const babelTransformOptions = await config.babel({
395
439
  presets: [(0, babel_1.babelPreset)({ newJsxTransform: config.newJsxTransform, isSsr })],
396
440
  plugins,
397
441
  }, { configType, isSsr });
@@ -399,7 +443,7 @@ function createJavaScriptLoader({ isEnvProduction, isEnvDevelopment, configType,
399
443
  loader: require.resolve('babel-loader'),
400
444
  options: {
401
445
  sourceType: 'unambiguous',
402
- ...transformOptions,
446
+ ...babelTransformOptions,
403
447
  babelrc: false,
404
448
  configFile: false,
405
449
  compact: isEnvProduction,
@@ -436,7 +480,7 @@ function createSourceMapRules(shouldUseSourceMap) {
436
480
  }
437
481
  return [];
438
482
  }
439
- function createWorkerRule(options) {
483
+ async function createWorkerRule(options) {
440
484
  return {
441
485
  test: /\.worker\.[jt]sx?$/,
442
486
  exclude: /node_modules/,
@@ -453,7 +497,7 @@ function createWorkerRule(options) {
453
497
  inline: 'no-fallback',
454
498
  },
455
499
  },
456
- createJavaScriptLoader(options),
500
+ await createJavaScriptLoader(options),
457
501
  ],
458
502
  };
459
503
  }
@@ -470,7 +514,7 @@ function createSassStylesRule(options) {
470
514
  options: {
471
515
  sourceMap: true, // must be always true for work with resolve-url-loader
472
516
  sassOptions: {
473
- loadPaths: [paths_1.default.app, paths_1.default.appClient],
517
+ loadPaths: [paths_1.default.appClient],
474
518
  },
475
519
  },
476
520
  },
@@ -531,14 +575,16 @@ function getCssLoaders({ isEnvDevelopment, isEnvProduction, config, isSsr }, add
531
575
  });
532
576
  if (isEnvProduction) {
533
577
  loaders.unshift({
534
- loader: isRspack ? core_1.CssExtractRspackPlugin.loader : mini_css_extract_plugin_1.default.loader,
578
+ loader: isRspack ? core_1.rspack.CssExtractRspackPlugin.loader : mini_css_extract_plugin_1.default.loader,
535
579
  options: { emit: !isSsr },
536
580
  });
537
581
  }
538
582
  if (isEnvDevelopment) {
539
583
  if (isSsr || config.ssr) {
540
584
  loaders.unshift({
541
- loader: isRspack ? core_1.CssExtractRspackPlugin.loader : mini_css_extract_plugin_1.default.loader,
585
+ loader: isRspack
586
+ ? core_1.rspack.CssExtractRspackPlugin.loader
587
+ : mini_css_extract_plugin_1.default.loader,
542
588
  options: { emit: !isSsr },
543
589
  });
544
590
  }
@@ -751,40 +797,9 @@ function getCssExtractPluginOptions({ isEnvProduction }) {
751
797
  ignoreOrder: true,
752
798
  };
753
799
  }
754
- const commonBundlerPlugins = {
755
- DefinePlugin: {
756
- rspack: core_1.rspack.DefinePlugin,
757
- webpack: webpack.DefinePlugin,
758
- },
759
- ContextReplacementPlugin: {
760
- rspack: core_1.rspack.ContextReplacementPlugin,
761
- webpack: webpack.ContextReplacementPlugin,
762
- },
763
- ProvidePlugin: {
764
- rspack: core_1.rspack.ProvidePlugin,
765
- webpack: webpack.ProvidePlugin,
766
- },
767
- ProgressPlugin: {
768
- rspack: progress_plugin_1.RspackProgressPlugin,
769
- webpack: progress_plugin_1.WebpackProgressPlugin,
770
- },
771
- ManifestPlugin: {
772
- rspack: rspack_manifest_plugin_1.RspackManifestPlugin,
773
- webpack: webpack_manifest_plugin_1.WebpackManifestPlugin,
774
- },
775
- TsCheckerPlugin: {
776
- rspack: ts_checker_rspack_plugin_1.TsCheckerRspackPlugin,
777
- webpack: fork_ts_checker_webpack_plugin_1.default,
778
- },
779
- CSSExtractPlugin: {
780
- rspack: core_1.CssExtractRspackPlugin,
781
- webpack: mini_css_extract_plugin_1.default,
782
- },
783
- };
784
- function configureCommonPlugins(options) {
800
+ function configureCommonPlugins(options, bundlerPlugins) {
785
801
  const { isEnvDevelopment, isEnvProduction, config, isSsr } = options;
786
802
  const excludeFromClean = config.excludeFromClean || [];
787
- const bundler = config.bundler;
788
803
  const forkTsCheckerOptions = getForkTsCheckerOptions(options);
789
804
  const plugins = [
790
805
  new clean_webpack_plugin_1.CleanWebpackPlugin({
@@ -795,17 +810,13 @@ function configureCommonPlugins(options) {
795
810
  ...excludeFromClean,
796
811
  ],
797
812
  }),
798
- new commonBundlerPlugins['ManifestPlugin'][bundler]({
813
+ new bundlerPlugins.ManifestPlugin({
799
814
  writeToFileEmit: true,
800
815
  publicPath: '',
801
816
  }),
802
- new commonBundlerPlugins['DefinePlugin'][bundler](getDefinitions(options)),
803
- ...(options.logger
804
- ? [new commonBundlerPlugins['ProgressPlugin'][bundler]({ logger: options.logger })]
805
- : []),
806
- ...(forkTsCheckerOptions
807
- ? [new commonBundlerPlugins['TsCheckerPlugin'][bundler](forkTsCheckerOptions)]
808
- : []),
817
+ new bundlerPlugins.DefinePlugin(getDefinitions(options)),
818
+ ...(options.logger ? [new bundlerPlugins.ProgressPlugin({ logger: options.logger })] : []),
819
+ ...(forkTsCheckerOptions ? [new bundlerPlugins.TsCheckerPlugin(forkTsCheckerOptions)] : []),
809
820
  ];
810
821
  if (config.detectCircularDependencies) {
811
822
  let circularPluginOptions = {
@@ -817,23 +828,14 @@ function configureCommonPlugins(options) {
817
828
  }
818
829
  plugins.push(new circular_dependency_plugin_1.default(circularPluginOptions));
819
830
  }
820
- if (isEnvProduction) {
821
- if (config.analyzeBundle === 'true') {
822
- plugins.push(new webpack_bundle_analyzer_1.BundleAnalyzerPlugin({
823
- openAnalyzer: false,
824
- analyzerMode: 'static',
825
- reportFilename: 'stats.html',
826
- }));
827
- }
828
- }
829
831
  if (isEnvProduction || isSsr || config.ssr) {
830
- plugins.push(new commonBundlerPlugins['CSSExtractPlugin'][bundler](getCssExtractPluginOptions(options)));
832
+ plugins.push(new bundlerPlugins.CSSExtractPlugin(getCssExtractPluginOptions(options)));
831
833
  }
832
834
  if (!isSsr) {
833
835
  const contextReplacements = getContextReplacements(options);
834
- contextReplacements.forEach(({ resourceRegExp, newResource }) => plugins.push(new commonBundlerPlugins['ContextReplacementPlugin'][bundler](resourceRegExp, newResource)));
836
+ contextReplacements.forEach(({ resourceRegExp, newResource }) => plugins.push(new bundlerPlugins.ContextReplacementPlugin(resourceRegExp, newResource)));
835
837
  if (config.polyfill?.process) {
836
- plugins.push(new commonBundlerPlugins['ProvidePlugin'][bundler]({
838
+ plugins.push(new bundlerPlugins.ProvidePlugin({
837
839
  process: 'process/browser.js',
838
840
  }));
839
841
  }
@@ -850,6 +852,13 @@ function configureCommonPlugins(options) {
850
852
  plugins.push(createMomentTimezoneDataPlugin(config.momentTz));
851
853
  }
852
854
  if (isEnvProduction) {
855
+ if (config.analyzeBundle === 'true') {
856
+ plugins.push(new webpack_bundle_analyzer_1.BundleAnalyzerPlugin({
857
+ openAnalyzer: false,
858
+ analyzerMode: 'static',
859
+ reportFilename: 'stats.html',
860
+ }));
861
+ }
853
862
  if (config.analyzeBundle === 'statoscope') {
854
863
  const customStatoscopeConfig = config.statoscopeConfig || {};
855
864
  plugins.push(new webpack_plugin_1.default({
@@ -862,6 +871,11 @@ function configureCommonPlugins(options) {
862
871
  ...customStatoscopeConfig,
863
872
  }));
864
873
  }
874
+ if (config.analyzeBundle === 'rsdoctor') {
875
+ plugins.push(new bundlerPlugins.RSDoctorPlugin({
876
+ mode: 'brief',
877
+ }));
878
+ }
865
879
  if (config.sentryConfig) {
866
880
  const sentryPlugin = require('@sentry/webpack-plugin').sentryWebpackPlugin;
867
881
  plugins.push(sentryPlugin({ ...config.sentryConfig }));
@@ -874,8 +888,18 @@ function configureCommonPlugins(options) {
874
888
  }
875
889
  function configureWebpackPlugins(options) {
876
890
  const { isEnvDevelopment, isEnvProduction, config, isSsr } = options;
891
+ const plugins = {
892
+ DefinePlugin: webpack.DefinePlugin,
893
+ ContextReplacementPlugin: webpack.ContextReplacementPlugin,
894
+ ProvidePlugin: webpack.ProvidePlugin,
895
+ ProgressPlugin: (0, progress_plugin_1.createProgressPlugin)(webpack.ProgressPlugin),
896
+ ManifestPlugin: webpack_manifest_plugin_1.WebpackManifestPlugin,
897
+ TsCheckerPlugin: fork_ts_checker_webpack_plugin_1.default,
898
+ CSSExtractPlugin: mini_css_extract_plugin_1.default,
899
+ RSDoctorPlugin: require('@rsdoctor/webpack-plugin').RsdoctorWebpackPlugin,
900
+ };
877
901
  const webpackPlugins = [
878
- ...configureCommonPlugins(options),
902
+ ...configureCommonPlugins(options, plugins),
879
903
  new webpack_assets_manifest_1.default(isEnvProduction
880
904
  ? {
881
905
  entrypoints: true,
@@ -888,14 +912,6 @@ function configureWebpackPlugins(options) {
888
912
  }),
889
913
  ...(process.env.WEBPACK_PROFILE === 'true' ? [new webpack.debug.ProfilingPlugin()] : []),
890
914
  ];
891
- if (isEnvProduction) {
892
- if (config.analyzeBundle === 'rsdoctor') {
893
- const { RsdoctorWebpackPlugin } = require('@rsdoctor/webpack-plugin');
894
- webpackPlugins.push(new RsdoctorWebpackPlugin({
895
- mode: 'brief',
896
- }));
897
- }
898
- }
899
915
  if (!isSsr && isEnvDevelopment && config.reactRefresh !== false) {
900
916
  const { webSocketPath = path.normalize(`/${config.publicPathPrefix}/build/sockjs-node`) } = config.devServer || {};
901
917
  const reactRefreshConfig = config.reactRefresh({
@@ -908,8 +924,18 @@ function configureWebpackPlugins(options) {
908
924
  }
909
925
  function configureRspackPlugins(options) {
910
926
  const { isEnvDevelopment, isEnvProduction, config, isSsr } = options;
927
+ const plugins = {
928
+ DefinePlugin: core_1.rspack.DefinePlugin,
929
+ ContextReplacementPlugin: core_1.rspack.ContextReplacementPlugin,
930
+ ProvidePlugin: core_1.rspack.ProvidePlugin,
931
+ ProgressPlugin: (0, progress_plugin_1.createProgressPlugin)(core_1.rspack.ProgressPlugin),
932
+ ManifestPlugin: rspack_manifest_plugin_1.RspackManifestPlugin,
933
+ TsCheckerPlugin: ts_checker_rspack_plugin_1.TsCheckerRspackPlugin,
934
+ CSSExtractPlugin: core_1.rspack.CssExtractRspackPlugin,
935
+ RSDoctorPlugin: require('@rsdoctor/rspack-plugin').RsdoctorRspackPlugin,
936
+ };
911
937
  const rspackPlugins = [
912
- ...configureCommonPlugins(options),
938
+ ...configureCommonPlugins(options, plugins),
913
939
  new rspack_manifest_plugin_1.RspackManifestPlugin({
914
940
  fileName: isEnvProduction
915
941
  ? assetsManifestFile
@@ -920,14 +946,6 @@ function configureRspackPlugins(options) {
920
946
  generate: rspack_1.generateAssetsManifest,
921
947
  }),
922
948
  ];
923
- if (isEnvProduction) {
924
- if (config.analyzeBundle === 'rsdoctor') {
925
- const { RsdoctorRspackPlugin } = require('@rsdoctor/rspack-plugin');
926
- rspackPlugins.push(new RsdoctorRspackPlugin({
927
- mode: 'brief',
928
- }));
929
- }
930
- }
931
949
  if (!isSsr && isEnvDevelopment && config.reactRefresh !== false) {
932
950
  const { webSocketPath = path.normalize(`/${config.publicPathPrefix}/build/sockjs-node`) } = config.devServer || {};
933
951
  const { overlay, ...reactRefreshConfig } = config.reactRefresh({
@@ -49,8 +49,9 @@ function nodeExternals({ noExternal = [], module }) {
49
49
  return `commonjs ${request}`;
50
50
  }
51
51
  if (dependencyType === 'commonjs' ||
52
- // lodash/something without extension can't be imported so always require it
53
- (moduleName === 'lodash' && request.match(/^lodash\/[\w_]+($|\/[\w_]+$)/))) {
52
+ // lodash and lodash/something without extension can't be imported so always require it
53
+ (moduleName === 'lodash' &&
54
+ (request === 'lodash' || request.match(/^lodash\/[\w_]+($|\/[\w_]+$)/)))) {
54
55
  return `node-commonjs ${request}`;
55
56
  }
56
57
  return `module-import ${request}`;
@@ -1,10 +1,11 @@
1
+ import type * as Rspack from '@rspack/core';
1
2
  import type * as Webpack from 'webpack';
2
3
  import type { Logger } from '../logger';
3
4
  interface State {
4
5
  done?: boolean;
5
6
  start?: bigint;
6
7
  }
7
- export declare const WebpackProgressPlugin: {
8
+ export declare function createProgressPlugin<T extends typeof Webpack.ProgressPlugin | typeof Rspack.ProgressPlugin>(BaseClass: T): {
8
9
  new ({ logger }: {
9
10
  logger: Logger;
10
11
  }): {
@@ -13,15 +14,5 @@ export declare const WebpackProgressPlugin: {
13
14
  handler: (percent: number, message: string, ...details: string[]) => void;
14
15
  apply(compiler: Webpack.Compiler): void;
15
16
  };
16
- };
17
- export declare const RspackProgressPlugin: {
18
- new ({ logger }: {
19
- logger: Logger;
20
- }): {
21
- logger: Logger;
22
- state: State;
23
- handler: (percent: number, message: string, ...details: string[]) => void;
24
- apply(compiler: Webpack.Compiler): void;
25
- };
26
- };
17
+ } & T;
27
18
  export {};
@@ -1,12 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.RspackProgressPlugin = exports.WebpackProgressPlugin = void 0;
7
- const webpack_1 = __importDefault(require("webpack"));
3
+ exports.createProgressPlugin = createProgressPlugin;
8
4
  const pretty_time_1 = require("../logger/pretty-time");
9
- const core_1 = require("@rspack/core");
10
5
  function createProgressPlugin(BaseClass) {
11
6
  return class ProgressPlugin extends BaseClass {
12
7
  logger;
@@ -51,5 +46,3 @@ function hook(compiler, hookName, callback) {
51
46
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
47
  compiler.hooks[hookName].tap(`app-builder: ${hookName}`, callback);
53
48
  }
54
- exports.WebpackProgressPlugin = createProgressPlugin(webpack_1.default.ProgressPlugin);
55
- exports.RspackProgressPlugin = createProgressPlugin(core_1.rspack.ProgressPlugin);
@@ -8,7 +8,17 @@ export declare function configureWebpackConfigForStorybook(mode: Mode, userConfi
8
8
  module: {
9
9
  rules: Webpack.RuleSetRule[];
10
10
  };
11
- resolve: Webpack.ResolveOptions;
11
+ resolve: {
12
+ alias: {
13
+ [x: string]: string | string[];
14
+ };
15
+ modules: string[];
16
+ extensions: string[];
17
+ symlinks: boolean | undefined;
18
+ fallback: {
19
+ [index: string]: string | false | string[];
20
+ } | undefined;
21
+ };
12
22
  plugins: (false | "" | 0 | ((this: Webpack.Compiler, compiler: Webpack.Compiler) => void) | Webpack.WebpackPluginInstance | null | undefined)[];
13
23
  optimization: {
14
24
  minimizer: (false | "" | 0 | Webpack.WebpackPluginInstance | "..." | ((this: Webpack.Compiler, compiler: Webpack.Compiler) => void) | null | undefined)[] | undefined;
@@ -50,6 +50,11 @@ async function configureServiceWebpackConfig(mode, storybookConfig) {
50
50
  else {
51
51
  options = serviceConfig.client;
52
52
  }
53
+ options = {
54
+ ...options,
55
+ // TODO support rspack for storybook
56
+ bundler: 'webpack',
57
+ };
53
58
  const webpackConfig = await configureWebpackConfigForStorybook(mode, options, storybookConfig.module?.rules);
54
59
  let devtool = storybookConfig.devtool;
55
60
  // storybook uses `cheap-module-source-map` and it's incompatible with `CssMinimizerWebpackPlugin`
@@ -97,6 +102,8 @@ async function configureWebpackConfigForStorybook(mode, userConfig = {}, storybo
97
102
  const config = await (0, config_2.normalizeConfig)({
98
103
  client: {
99
104
  ...userConfig,
105
+ // TODO support rspack for storybook
106
+ bundler: 'webpack',
100
107
  includes: (userConfig.includes ?? []).concat(['.storybook']),
101
108
  },
102
109
  });
@@ -111,7 +118,7 @@ async function configureWebpackConfigForStorybook(mode, userConfig = {}, storybo
111
118
  };
112
119
  return {
113
120
  module: {
114
- rules: (0, config_1.configureModuleRules)(helperOptions, storybookModuleRules.filter((rule) => rule !== '...')),
121
+ rules: await (0, config_1.configureModuleRules)(helperOptions, storybookModuleRules.filter((rule) => rule !== '...')),
115
122
  },
116
123
  resolve: (0, config_1.configureResolve)(helperOptions),
117
124
  plugins: configurePlugins(helperOptions),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/app-builder",
3
- "version": "0.15.1-beta.7",
3
+ "version": "0.16.1",
4
4
  "description": "Develop and build your React client-server projects, powered by typescript and webpack",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -79,6 +79,8 @@
79
79
  "@svgr/core": "^8.1.0",
80
80
  "@svgr/plugin-jsx": "^8.1.0",
81
81
  "@svgr/webpack": "^8.1.0",
82
+ "@swc/plugin-transform-imports": "^6.4.0",
83
+ "@swc/types": "^0.1.17",
82
84
  "babel-loader": "^9.2.1",
83
85
  "babel-plugin-import": "^1.13.8",
84
86
  "babel-plugin-inline-react-svg": "^2.0.2",
@@ -88,6 +90,7 @@
88
90
  "circular-dependency-plugin": "^5.2.2",
89
91
  "clean-webpack-plugin": "^4.0.0",
90
92
  "common-tags": "^1.8.2",
93
+ "core-js": "~3.40.0",
91
94
  "cosmiconfig": "^8.3.6",
92
95
  "cosmiconfig-typescript-loader": "^5.0.0",
93
96
  "css-loader": "^7.1.2",
@@ -124,6 +127,7 @@
124
127
  "strip-ansi": "^6.0.1",
125
128
  "style-loader": "^4.0.0",
126
129
  "svgo": "^3.3.2",
130
+ "swc-loader": "^0.2.6",
127
131
  "terser-webpack-plugin": "5.3.10",
128
132
  "ts-checker-rspack-plugin": "^1.1.1",
129
133
  "ts-node": "10.9.2",