@gravity-ui/app-builder 0.15.0 → 0.15.1-beta.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.
@@ -1,3 +1,4 @@
1
1
  import WebpackDevServer from 'webpack-dev-server';
2
+ import { RspackDevServer } from '@rspack/dev-server';
2
3
  import type { NormalizedServiceConfig } from '../../common/models';
3
- export declare function watchClientCompilation(config: NormalizedServiceConfig, onManifestReady: () => void): Promise<WebpackDevServer<import("express").Application, import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>>>;
4
+ export declare function watchClientCompilation(config: NormalizedServiceConfig, onManifestReady: () => void): Promise<WebpackDevServer<import("express").Application, import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>> | RspackDevServer>;
@@ -34,9 +34,13 @@ const webpack_dev_server_1 = __importDefault(require("webpack-dev-server"));
34
34
  const webpack_manifest_plugin_1 = require("webpack-manifest-plugin");
35
35
  const webpack_assets_manifest_1 = __importDefault(require("webpack-assets-manifest"));
36
36
  const utils_1 = require("../../common/utils");
37
+ const rspack_manifest_plugin_1 = require("rspack-manifest-plugin");
38
+ const core_1 = require("@rspack/core");
39
+ const dev_server_1 = require("@rspack/dev-server");
37
40
  const paths_1 = __importDefault(require("../../common/paths"));
38
41
  const logger_1 = require("../../common/logger");
39
42
  const config_1 = require("../../common/webpack/config");
43
+ const rspack_1 = require("../../common/webpack/rspack");
40
44
  async function watchClientCompilation(config, onManifestReady) {
41
45
  const clientCompilation = await buildDevServer(config);
42
46
  const compiler = clientCompilation.compiler;
@@ -44,19 +48,42 @@ async function watchClientCompilation(config, onManifestReady) {
44
48
  return clientCompilation;
45
49
  }
46
50
  async function buildDevServer(config) {
51
+ const bundler = config.client.bundler;
47
52
  const logger = new logger_1.Logger('client', config.verbose);
48
53
  const { webSocketPath = path.normalize(`/${config.client.publicPathPrefix}/build/sockjs-node`), writeToDisk, ...devServer } = config.client.devServer || {};
49
54
  const normalizedConfig = { ...config.client, devServer: { ...devServer, webSocketPath } };
50
- const webpackConfigs = [
51
- await (0, config_1.webpackConfigFactory)("development" /* WebpackMode.Dev */, normalizedConfig, { logger }),
52
- ];
53
55
  const isSsr = Boolean(normalizedConfig.ssr);
54
- if (isSsr) {
55
- const ssrLogger = new logger_1.Logger('client(SSR)', config.verbose);
56
- webpackConfigs.push(await (0, config_1.webpackConfigFactory)("development" /* WebpackMode.Dev */, normalizedConfig, {
57
- logger: ssrLogger,
58
- isSsr,
59
- }));
56
+ let webpackConfigs = [];
57
+ let rspackConfigs = [];
58
+ if (bundler === 'webpack') {
59
+ webpackConfigs = [
60
+ await (0, config_1.webpackConfigFactory)({
61
+ webpackMode: "development" /* WebpackMode.Dev */,
62
+ config: normalizedConfig,
63
+ logger,
64
+ }),
65
+ ];
66
+ if (isSsr) {
67
+ const ssrLogger = new logger_1.Logger('webpack(SSR)', config.verbose);
68
+ webpackConfigs.push(await (0, config_1.webpackConfigFactory)({
69
+ webpackMode: "development" /* WebpackMode.Dev */,
70
+ config: normalizedConfig,
71
+ logger: ssrLogger,
72
+ isSsr,
73
+ }));
74
+ }
75
+ }
76
+ else {
77
+ if (isSsr) {
78
+ throw new Error(`SSR is not supported in ${bundler}`);
79
+ }
80
+ rspackConfigs = [
81
+ await (0, config_1.rspackConfigFactory)({
82
+ webpackMode: "development" /* WebpackMode.Dev */,
83
+ config: normalizedConfig,
84
+ logger,
85
+ }),
86
+ ];
60
87
  }
61
88
  const publicPath = path.normalize(config.client.publicPathPrefix + '/build/');
62
89
  const staticFolder = path.resolve(paths_1.default.appDist, 'public');
@@ -134,41 +161,60 @@ async function buildDevServer(config) {
134
161
  });
135
162
  }
136
163
  options.proxy = proxy;
137
- const compiler = (0, webpack_1.default)(webpackConfigs);
138
- const server = new webpack_dev_server_1.default(options, compiler);
164
+ let server;
165
+ if (bundler === 'rspack') {
166
+ // Rspack multicompiler dont work with lazy compilation
167
+ const compiler = (0, core_1.rspack)(rspackConfigs[0]);
168
+ server = new dev_server_1.RspackDevServer(options, compiler);
169
+ // Need to clean cache before start. https://github.com/web-infra-dev/rspack/issues/9025
170
+ (0, rspack_1.clearCacheDirectory)(rspackConfigs[0], logger);
171
+ }
172
+ else {
173
+ const compiler = (0, webpack_1.default)(webpackConfigs);
174
+ server = new webpack_dev_server_1.default(options, compiler);
175
+ }
139
176
  try {
140
177
  await server.start();
141
178
  }
142
179
  catch (e) {
143
- logger.logError('Cannot start webpack dev server', e);
180
+ logger.logError(`Cannot start ${bundler} dev server`, e);
144
181
  }
145
182
  if (options.ipc && typeof options.ipc === 'string') {
146
183
  fs.chmod(options.ipc, 0o666, (e) => logger.logError('', e));
147
184
  }
148
185
  return server;
149
186
  }
150
- function subscribeToManifestReadyEvent(webpackCompiler, onManifestReady) {
187
+ function isRspackCompiler(compiler) {
188
+ return 'rspack' in compiler;
189
+ }
190
+ function subscribeToManifestReadyEvent(compiler, onManifestReady) {
151
191
  const promises = [];
152
- const options = Array.isArray(webpackCompiler.options)
153
- ? webpackCompiler.options
154
- : [webpackCompiler.options];
155
- const compilers = 'compilers' in webpackCompiler ? webpackCompiler.compilers : [webpackCompiler];
192
+ const options = Array.isArray(compiler.options) ? compiler.options : [compiler.options];
193
+ const compilers = 'compilers' in compiler ? compiler.compilers : [compiler];
156
194
  for (let i = 0; i < options.length; i++) {
157
195
  const config = options[i];
158
196
  const compiler = compilers[i];
159
197
  if (!config || !compiler) {
160
198
  throw new Error('Something goes wrong!');
161
199
  }
162
- const assetsManifestPlugin = config.plugins.find((plugin) => plugin instanceof webpack_assets_manifest_1.default);
163
- if (assetsManifestPlugin) {
164
- const assetsManifestReady = (0, utils_1.deferredPromise)();
165
- promises.push(assetsManifestReady.promise);
166
- assetsManifestPlugin.hooks.done.tap('app-builder', assetsManifestReady.resolve);
200
+ if (!isRspackCompiler(compiler)) {
201
+ const assetsManifestPlugin = config.plugins.find((plugin) => plugin instanceof webpack_assets_manifest_1.default);
202
+ if (assetsManifestPlugin) {
203
+ const assetsManifestReady = (0, utils_1.deferredPromise)();
204
+ promises.push(assetsManifestReady.promise);
205
+ assetsManifestPlugin.hooks.done.tap('app-builder', assetsManifestReady.resolve);
206
+ }
167
207
  }
168
208
  const manifestReady = (0, utils_1.deferredPromise)();
169
209
  promises.push(manifestReady.promise);
170
- const { afterEmit } = (0, webpack_manifest_plugin_1.getCompilerHooks)(compiler);
171
- afterEmit.tap('app-builder', manifestReady.resolve);
210
+ if (isRspackCompiler(compiler)) {
211
+ const { afterEmit } = (0, rspack_manifest_plugin_1.getCompilerHooks)(compiler);
212
+ afterEmit.tap('app-builder', manifestReady.resolve);
213
+ }
214
+ else {
215
+ const { afterEmit } = (0, webpack_manifest_plugin_1.getCompilerHooks)(compiler);
216
+ afterEmit.tap('app-builder', manifestReady.resolve);
217
+ }
172
218
  }
173
219
  Promise.all(promises).then(() => onManifestReady());
174
220
  }
@@ -197,9 +197,11 @@ async function normalizeClientConfig(client, mode) {
197
197
  svgr: client.svgr ?? {},
198
198
  entryFilter: client.entryFilter && splitPaths(client.entryFilter),
199
199
  webpack: typeof client.webpack === 'function' ? client.webpack : (config) => config,
200
+ rspack: typeof client.rspack === 'function' ? client.rspack : (config) => config,
200
201
  babel: typeof client.babel === 'function' ? client.babel : (config) => config,
201
202
  devServer: undefined,
202
203
  lazyCompilation: undefined,
204
+ bundler: client.bundler || 'webpack',
203
205
  };
204
206
  if (mode === 'dev') {
205
207
  if (client.lazyCompilation) {
@@ -129,6 +129,7 @@ function compileStyles(inputDir, outputDir, onFinish, additionalGlobs = []) {
129
129
  const sassTransformed = sass_1.default.compile(scssFile, {
130
130
  sourceMap: true,
131
131
  sourceMapIncludeSources: true,
132
+ silenceDeprecations: ['legacy-js-api'],
132
133
  importers: [
133
134
  {
134
135
  findFileUrl(url) {
@@ -3,6 +3,7 @@ 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
5
  import type { Configuration, DefinePlugin, FileCacheOptions, MemoryCacheOptions, ResolveOptions } from 'webpack';
6
+ import type { Configuration as RspackConfiguration } from '@rspack/core';
6
7
  import type * as Babel from '@babel/core';
7
8
  import type { ServerConfiguration } from 'webpack-dev-server';
8
9
  import type { Options as CircularDependenciesOptions } from 'circular-dependency-plugin';
@@ -14,6 +15,7 @@ import type { WebpackMode } from '../webpack/config';
14
15
  import type { UploadOptions } from '../s3-upload/upload';
15
16
  import type { TerserOptions } from 'terser-webpack-plugin';
16
17
  import type { ReactRefreshPluginOptions } from '@pmmmwh/react-refresh-webpack-plugin/types/lib/types';
18
+ type Bundler = 'webpack' | 'rspack';
17
19
  export interface Entities<T> {
18
20
  data: Record<string, T>;
19
21
  keys: string[];
@@ -126,7 +128,7 @@ export interface ClientConfig {
126
128
  svgr?: SvgrConfig;
127
129
  entryFilter?: string[];
128
130
  excludeFromClean?: string[];
129
- analyzeBundle?: 'true' | 'statoscope';
131
+ analyzeBundle?: 'true' | 'statoscope' | 'rsdoctor';
130
132
  statoscopeConfig?: Partial<StatoscopeOptions>;
131
133
  reactProfiling?: boolean;
132
134
  /**
@@ -182,6 +184,13 @@ export interface ClientConfig {
182
184
  configType: `${WebpackMode}`;
183
185
  isSsr?: boolean;
184
186
  }) => Configuration | Promise<Configuration>;
187
+ /**
188
+ * Modify or return a custom Rspack config.
189
+ */
190
+ rspack?: (config: RspackConfiguration, options: {
191
+ configType: `${WebpackMode}`;
192
+ isSsr?: boolean;
193
+ }) => RspackConfiguration | Promise<RspackConfiguration>;
185
194
  /**
186
195
  * Modify or return a custom Babel config.
187
196
  */
@@ -197,6 +206,7 @@ export interface ClientConfig {
197
206
  noExternal?: string | RegExp | (string | RegExp)[] | true;
198
207
  moduleType?: 'commonjs' | 'esm';
199
208
  };
209
+ bundler?: Bundler;
200
210
  }
201
211
  export interface CdnUploadConfig {
202
212
  bucket: string;
@@ -225,6 +235,7 @@ export interface ServiceConfig {
225
235
  verbose?: boolean;
226
236
  }
227
237
  export type NormalizedClientConfig = Omit<ClientConfig, 'publicPathPrefix' | 'hiddenSourceMap' | 'svgr' | 'lazyCompilation' | 'devServer' | 'disableForkTsChecker' | 'disableReactRefresh'> & {
238
+ bundler: Bundler;
228
239
  publicPathPrefix: string;
229
240
  hiddenSourceMap: boolean;
230
241
  svgr: NonNullable<ClientConfig['svgr']>;
@@ -238,6 +249,9 @@ export type NormalizedClientConfig = Omit<ClientConfig, 'publicPathPrefix' | 'hi
238
249
  configType: `${WebpackMode}`;
239
250
  isSsr: boolean;
240
251
  }) => Configuration | Promise<Configuration>;
252
+ rspack: (config: RspackConfiguration, options: {
253
+ configType: `${WebpackMode}`;
254
+ }) => RspackConfiguration | Promise<RspackConfiguration>;
241
255
  debugWebpack?: boolean;
242
256
  babel: (config: Babel.TransformOptions, options: {
243
257
  configType: `${WebpackMode}`;
@@ -0,0 +1,3 @@
1
+ import { NormalizedClientConfig } from '../models';
2
+ import type { Logger } from '../logger';
3
+ export declare function createS3UploadPlugins(config: NormalizedClientConfig, logger?: Logger): (false | "" | 0 | ((this: import("webpack").Compiler, compiler: import("webpack").Compiler) => void) | import("webpack").WebpackPluginInstance | null)[];
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createS3UploadPlugins = createS3UploadPlugins;
4
+ const webpack_plugin_1 = require("./webpack-plugin");
5
+ function createS3UploadPlugins(config, logger) {
6
+ const plugins = [];
7
+ let credentialsGlobal;
8
+ if (process.env.FRONTEND_S3_ACCESS_KEY_ID && process.env.FRONTEND_S3_SECRET_ACCESS_KEY) {
9
+ credentialsGlobal = {
10
+ accessKeyId: process.env.FRONTEND_S3_ACCESS_KEY_ID,
11
+ secretAccessKey: process.env.FRONTEND_S3_SECRET_ACCESS_KEY,
12
+ };
13
+ }
14
+ const cdns = Array.isArray(config.cdn) ? config.cdn : [config.cdn];
15
+ for (let index = 0; index < cdns.length; index++) {
16
+ const cdn = cdns[index];
17
+ if (!cdn) {
18
+ continue;
19
+ }
20
+ let credentials = credentialsGlobal;
21
+ const accessKeyId = process.env[`FRONTEND_S3_ACCESS_KEY_ID_${index}`];
22
+ const secretAccessKey = process.env[`FRONTEND_S3_SECRET_ACCESS_KEY_${index}`];
23
+ if (accessKeyId && secretAccessKey) {
24
+ credentials = {
25
+ accessKeyId,
26
+ secretAccessKey,
27
+ };
28
+ }
29
+ plugins.push(new webpack_plugin_1.S3UploadPlugin({
30
+ exclude: config.hiddenSourceMap ? /\.map$/ : undefined,
31
+ compress: cdn.compress,
32
+ s3ClientOptions: {
33
+ region: cdn.region,
34
+ endpoint: cdn.endpoint,
35
+ credentials,
36
+ },
37
+ s3UploadOptions: {
38
+ bucket: cdn.bucket,
39
+ targetPath: cdn.prefix,
40
+ cacheControl: cdn.cacheControl,
41
+ },
42
+ additionalPattern: cdn.additionalPattern,
43
+ logger,
44
+ }));
45
+ }
46
+ return plugins;
47
+ }
@@ -1,3 +1,4 @@
1
1
  export { S3UploadPlugin } from './webpack-plugin';
2
2
  export { uploadFiles } from './upload';
3
+ export { createS3UploadPlugins } from './create-plugin';
3
4
  export type { UploadFilesOptions } from './upload';
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uploadFiles = exports.S3UploadPlugin = void 0;
3
+ exports.createS3UploadPlugins = exports.uploadFiles = exports.S3UploadPlugin = void 0;
4
4
  var webpack_plugin_1 = require("./webpack-plugin");
5
5
  Object.defineProperty(exports, "S3UploadPlugin", { enumerable: true, get: function () { return webpack_plugin_1.S3UploadPlugin; } });
6
6
  var upload_1 = require("./upload");
7
7
  Object.defineProperty(exports, "uploadFiles", { enumerable: true, get: function () { return upload_1.uploadFiles; } });
8
+ var create_plugin_1 = require("./create-plugin");
9
+ Object.defineProperty(exports, "createS3UploadPlugins", { enumerable: true, get: function () { return create_plugin_1.createS3UploadPlugins; } });
@@ -5,29 +5,56 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.clientCompile = clientCompile;
7
7
  const webpack_1 = __importDefault(require("webpack"));
8
+ const core_1 = require("@rspack/core");
8
9
  const logger_1 = require("../logger");
9
10
  const config_1 = require("./config");
10
11
  const utils_1 = require("./utils");
12
+ const rspack_1 = require("./rspack");
11
13
  async function clientCompile(config) {
12
14
  const logger = new logger_1.Logger('client', config.verbose);
13
- const webpackConfigs = [await (0, config_1.webpackConfigFactory)("production" /* WebpackMode.Prod */, config, { logger })];
15
+ const webpackConfigs = [];
16
+ const rspackConfigs = [];
14
17
  const isSsr = Boolean(config.ssr);
15
- if (isSsr) {
16
- const ssrLogger = new logger_1.Logger('client(SSR)', config.verbose);
17
- webpackConfigs.push(await (0, config_1.webpackConfigFactory)("production" /* WebpackMode.Prod */, config, { logger: ssrLogger, isSsr }));
18
+ if (config.bundler === 'rspack') {
19
+ rspackConfigs.push(await (0, config_1.rspackConfigFactory)({ webpackMode: "production" /* WebpackMode.Prod */, config, logger }));
20
+ if (isSsr) {
21
+ const ssrLogger = new logger_1.Logger('client(SSR)', config.verbose);
22
+ rspackConfigs.push(await (0, config_1.rspackConfigFactory)({
23
+ webpackMode: "production" /* WebpackMode.Prod */,
24
+ config,
25
+ logger: ssrLogger,
26
+ isSsr,
27
+ }));
28
+ }
29
+ }
30
+ else {
31
+ webpackConfigs.push(await (0, config_1.webpackConfigFactory)({ webpackMode: "production" /* WebpackMode.Prod */, config, logger }));
32
+ if (isSsr) {
33
+ const ssrLogger = new logger_1.Logger('client(SSR)', config.verbose);
34
+ webpackConfigs.push(await (0, config_1.webpackConfigFactory)({
35
+ webpackMode: "production" /* WebpackMode.Prod */,
36
+ config,
37
+ logger: ssrLogger,
38
+ isSsr,
39
+ }));
40
+ }
18
41
  }
19
42
  logger.verbose('Config created');
20
43
  return new Promise((resolve) => {
21
- const compiler = (0, webpack_1.default)(webpackConfigs, (0, utils_1.webpackCompilerHandlerFactory)(logger, async () => {
22
- resolve();
23
- }));
44
+ const compiler = config.bundler === 'rspack'
45
+ ? (0, core_1.rspack)(rspackConfigs, (0, rspack_1.rspackCompilerHandlerFactory)(logger, async () => {
46
+ resolve();
47
+ }))
48
+ : (0, webpack_1.default)(webpackConfigs, (0, utils_1.webpackCompilerHandlerFactory)(logger, async () => {
49
+ resolve();
50
+ }));
24
51
  process.on('SIGINT', async () => {
25
- compiler.close(() => {
52
+ compiler?.close(() => {
26
53
  process.exit(1);
27
54
  });
28
55
  });
29
56
  process.on('SIGTERM', async () => {
30
- compiler.close(() => {
57
+ compiler?.close(() => {
31
58
  process.exit(1);
32
59
  });
33
60
  });
@@ -1,4 +1,5 @@
1
1
  import * as webpack from 'webpack';
2
+ import { Configuration as RspackConfiguration } from '@rspack/core';
2
3
  import type { NormalizedClientConfig } from '../models';
3
4
  import type { Logger } from '../logger';
4
5
  export interface HelperOptions {
@@ -15,12 +16,16 @@ export declare const enum WebpackMode {
15
16
  Prod = "production",
16
17
  Dev = "development"
17
18
  }
18
- export declare function webpackConfigFactory(webpackMode: WebpackMode, config: NormalizedClientConfig, { logger, isSsr }?: {
19
+ type ClientFactoryOptions = {
20
+ webpackMode: WebpackMode;
21
+ config: NormalizedClientConfig;
19
22
  logger?: Logger;
20
23
  isSsr?: boolean;
21
- }): Promise<webpack.Configuration>;
24
+ };
25
+ export declare function webpackConfigFactory(options: ClientFactoryOptions): Promise<webpack.Configuration>;
26
+ export declare function rspackConfigFactory(options: ClientFactoryOptions): Promise<RspackConfiguration>;
22
27
  export declare function configureModuleRules(helperOptions: HelperOptions, additionalRules?: NonNullable<webpack.RuleSetRule['oneOf']>): webpack.RuleSetRule[];
23
28
  export declare function configureResolve({ isEnvProduction, config }: HelperOptions): webpack.ResolveOptions;
24
29
  type Optimization = NonNullable<webpack.Configuration['optimization']>;
25
- export declare function configureOptimization({ config, isSsr }: HelperOptions): Optimization;
30
+ export declare function configureOptimization(helperOptions: HelperOptions): Optimization;
26
31
  export {};