@gravity-ui/app-builder 0.14.0-beta.1 → 0.14.0-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.
package/README.md CHANGED
@@ -192,11 +192,8 @@ With this `{rootDir}/src/ui/tsconfig.json`:
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
194
  - `babelCacheDirectory` (`boolean | string`) — Set directory for babel-loader cache (`default: node_modules/.cache/babel-loader``)
195
- - `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
- - `ssr` - build SSR bundle. The SSR entries should be inside `src/ui/ssr` directory and match the client entries.
198
- - `noExternal` (`string | RegExp | (string | RegExp)[] | true`) - prevent listed dependencies from being externalized for SSR. By default, all dependencies are externalized.
199
- - `moduleType`: (`'commonjs' | 'esm'`) - library type for the SSR bundle, by default `commonjs`.
195
+ - `babel` (`(config: babel.TransformOptions, options: {configType: 'development' | 'production'}) => babel.TransformOptions | Promise<babel.TransformOptions>`) - Allow override the default babel transform options.
196
+ - `webpack` (`(config: webpack.Configuration, options: {configType: 'development' | 'production'}) => webpack.Configuration | Promise<webpack.Configuration>`) - Allow override the default configuration.
200
197
 
201
198
  ##### Dev build
202
199
 
@@ -40,6 +40,9 @@ const config_1 = require("../../common/webpack/config");
40
40
  async function watchClientCompilation(config, onManifestReady) {
41
41
  const clientCompilation = await buildWebpackServer(config);
42
42
  const compiler = clientCompilation.compiler;
43
+ if ('compilers' in compiler) {
44
+ throw new Error('Unexpected multi compiler');
45
+ }
43
46
  subscribeToManifestReadyEvent(compiler, onManifestReady);
44
47
  return clientCompilation;
45
48
  }
@@ -47,14 +50,7 @@ async function buildWebpackServer(config) {
47
50
  const logger = new logger_1.Logger('webpack', config.verbose);
48
51
  const { webSocketPath = path.normalize(`/${config.client.publicPathPrefix}/build/sockjs-node`), writeToDisk, ...devServer } = config.client.devServer || {};
49
52
  const normalizedConfig = { ...config.client, devServer: { ...devServer, webSocketPath } };
50
- const webpackConfigs = [
51
- await (0, config_1.webpackConfigFactory)("development" /* WebpackMode.Dev */, normalizedConfig, { logger }),
52
- ];
53
- const isSsr = Boolean(normalizedConfig.ssr);
54
- if (isSsr) {
55
- const logger = new logger_1.Logger('webpack(SSR)', config.verbose);
56
- webpackConfigs.push(await (0, config_1.webpackConfigFactory)("development" /* WebpackMode.Dev */, normalizedConfig, { logger, isSsr }));
57
- }
53
+ const webpackConfig = await (0, config_1.webpackConfigFactory)("development" /* WebpackMode.Dev */, normalizedConfig, { logger });
58
54
  const publicPath = path.normalize(config.client.publicPathPrefix + '/build/');
59
55
  const staticFolder = path.resolve(paths_1.default.appDist, 'public');
60
56
  const options = {
@@ -62,18 +58,7 @@ async function buildWebpackServer(config) {
62
58
  devMiddleware: {
63
59
  publicPath,
64
60
  stats: 'errors-warnings',
65
- writeToDisk: (target) => {
66
- if (writeToDisk === true) {
67
- return true;
68
- }
69
- if (isSsr && target.startsWith(paths_1.default.appSsrBuild)) {
70
- return true;
71
- }
72
- if (typeof writeToDisk === 'function') {
73
- return writeToDisk(target);
74
- }
75
- return false;
76
- },
61
+ writeToDisk,
77
62
  },
78
63
  liveReload: false,
79
64
  hot: true,
@@ -131,7 +116,7 @@ async function buildWebpackServer(config) {
131
116
  });
132
117
  }
133
118
  options.proxy = proxy;
134
- const compiler = (0, webpack_1.default)(webpackConfigs);
119
+ const compiler = (0, webpack_1.default)(webpackConfig);
135
120
  const server = new webpack_dev_server_1.default(options, compiler);
136
121
  try {
137
122
  await server.start();
@@ -144,28 +129,17 @@ async function buildWebpackServer(config) {
144
129
  }
145
130
  return server;
146
131
  }
147
- function subscribeToManifestReadyEvent(webpackCompiler, onManifestReady) {
132
+ function subscribeToManifestReadyEvent(compiler, onManifestReady) {
148
133
  const promises = [];
149
- const options = Array.isArray(webpackCompiler.options)
150
- ? webpackCompiler.options
151
- : [webpackCompiler.options];
152
- const compilers = 'compilers' in webpackCompiler ? webpackCompiler.compilers : [webpackCompiler];
153
- for (let i = 0; i < options.length; i++) {
154
- const config = options[i];
155
- const compiler = compilers[i];
156
- if (!config || !compiler) {
157
- throw new Error('Something goes wrong!');
158
- }
159
- const assetsManifestPlugin = config.plugins.find((plugin) => plugin instanceof webpack_assets_manifest_1.default);
160
- if (assetsManifestPlugin) {
161
- const assetsManifestReady = (0, utils_1.deferredPromise)();
162
- promises.push(assetsManifestReady.promise);
163
- assetsManifestPlugin.hooks.done.tap('app-builder', assetsManifestReady.resolve);
164
- }
165
- const manifestReady = (0, utils_1.deferredPromise)();
166
- promises.push(manifestReady.promise);
167
- const { afterEmit } = (0, webpack_manifest_plugin_1.getCompilerHooks)(compiler);
168
- afterEmit.tap('app-builder', manifestReady.resolve);
134
+ const assetsManifestPlugin = compiler.options.plugins.find((plugin) => plugin instanceof webpack_assets_manifest_1.default);
135
+ if (assetsManifestPlugin) {
136
+ const assetsManifestReady = (0, utils_1.deferredPromise)();
137
+ promises.push(assetsManifestReady.promise);
138
+ assetsManifestPlugin.hooks.done.tap('app-builder', assetsManifestReady.resolve);
169
139
  }
140
+ const manifestReady = (0, utils_1.deferredPromise)();
141
+ promises.push(manifestReady.promise);
142
+ const { afterEmit } = (0, webpack_manifest_plugin_1.getCompilerHooks)(compiler);
143
+ afterEmit.tap('app-builder', manifestReady.resolve);
170
144
  Promise.all(promises).then(() => onManifestReady());
171
145
  }
@@ -56,7 +56,7 @@ async function default_1(config) {
56
56
  script: `${serverPath}/index.js`,
57
57
  args: ['--dev', config.server.port ? `--port=${config.server.port}` : ''],
58
58
  env: {
59
- ...(config.server.port ? { APP_PORT: `${config.server.port}` } : undefined),
59
+ ...(config.server.port ? { APP_PORT: config.server.port } : undefined),
60
60
  },
61
61
  nodeArgs: inspect || inspectBrk
62
62
  ? [`--${inspect ? 'inspect' : 'inspect-brk'}=:::${inspect || inspectBrk}`]
@@ -1,13 +1,9 @@
1
1
  export declare function babelPreset(config: {
2
2
  newJsxTransform?: boolean;
3
- isSsr?: boolean;
4
3
  }): (string | {
5
4
  env: {
6
5
  modules: boolean;
7
6
  bugfixes: boolean;
8
- targets: {
9
- node: string;
10
- } | undefined;
11
7
  };
12
8
  runtime: {
13
9
  version: string;
@@ -5,11 +5,7 @@ function babelPreset(config) {
5
5
  return [
6
6
  require.resolve('./ui-preset'),
7
7
  {
8
- env: {
9
- modules: false,
10
- bugfixes: true,
11
- targets: config.isSsr ? { node: 'current' } : undefined,
12
- },
8
+ env: { modules: false, bugfixes: true },
13
9
  runtime: { version: '^7.13.10' },
14
10
  typescript: true,
15
11
  react: {
@@ -180,23 +180,17 @@ export interface ClientConfig {
180
180
  */
181
181
  webpack?: (config: Configuration, options: {
182
182
  configType: `${WebpackMode}`;
183
- isSsr?: boolean;
184
183
  }) => Configuration | Promise<Configuration>;
185
184
  /**
186
185
  * Modify or return a custom Babel config.
187
186
  */
188
187
  babel?: (config: Babel.TransformOptions, options: {
189
188
  configType: `${WebpackMode}`;
190
- isSsr: boolean;
191
189
  }) => Babel.TransformOptions | Promise<Babel.TransformOptions>;
192
190
  /**
193
191
  * Modify or return a custom [Terser options](https://github.com/terser/terser#minify-options).
194
192
  */
195
193
  terser?: (options: TerserOptions) => TerserOptions;
196
- ssr?: {
197
- noExternal?: string | RegExp | (string | RegExp)[] | true;
198
- moduleType?: 'commonjs' | 'esm';
199
- };
200
194
  }
201
195
  export interface CdnUploadConfig {
202
196
  bucket: string;
@@ -236,12 +230,10 @@ export type NormalizedClientConfig = Omit<ClientConfig, 'publicPathPrefix' | 'hi
236
230
  verbose?: boolean;
237
231
  webpack: (config: Configuration, options: {
238
232
  configType: `${WebpackMode}`;
239
- isSsr: boolean;
240
233
  }) => Configuration | Promise<Configuration>;
241
234
  debugWebpack?: boolean;
242
235
  babel: (config: Babel.TransformOptions, options: {
243
236
  configType: `${WebpackMode}`;
244
- isSsr: boolean;
245
237
  }) => Babel.TransformOptions | Promise<Babel.TransformOptions>;
246
238
  reactRefresh: NonNullable<ClientConfig['reactRefresh']>;
247
239
  };
@@ -7,8 +7,6 @@ declare const _default: {
7
7
  appDist: string;
8
8
  appRun: string;
9
9
  appBuild: string;
10
- appSsrEntry: string;
11
- appSsrBuild: string;
12
10
  src: string;
13
11
  libBuild: string;
14
12
  libBuildEsm: string;
@@ -36,8 +36,6 @@ exports.default = {
36
36
  appDist: resolveApp('dist'),
37
37
  appRun: resolveApp('dist/run'),
38
38
  appBuild: resolveApp('dist/public/build'),
39
- appSsrEntry: resolveApp('src/ui/ssr'),
40
- appSsrBuild: resolveApp('dist/ssr'),
41
39
  src: resolveApp('src'),
42
40
  libBuild: resolveApp('build'),
43
41
  libBuildEsm: resolveApp('build/esm'),
@@ -10,15 +10,10 @@ const config_1 = require("./config");
10
10
  const utils_1 = require("./utils");
11
11
  async function webpackCompile(config) {
12
12
  const logger = new logger_1.Logger('webpack', config.verbose);
13
- const webpackConfigs = [await (0, config_1.webpackConfigFactory)("production" /* WebpackMode.Prod */, config, { logger })];
14
- const isSsr = Boolean(config.ssr);
15
- if (isSsr) {
16
- const logger = new logger_1.Logger('webpack(SSR)', config.verbose);
17
- webpackConfigs.push(await (0, config_1.webpackConfigFactory)("production" /* WebpackMode.Prod */, config, { logger, isSsr }));
18
- }
13
+ const webpackConfig = await (0, config_1.webpackConfigFactory)("production" /* WebpackMode.Prod */, config, { logger });
19
14
  logger.verbose('Config created');
20
15
  return new Promise((resolve) => {
21
- const compiler = (0, webpack_1.default)(webpackConfigs, (0, utils_1.webpackCompilerHandlerFactory)(logger, async () => {
16
+ const compiler = (0, webpack_1.default)(webpackConfig, (0, utils_1.webpackCompilerHandlerFactory)(logger, async () => {
22
17
  resolve();
23
18
  }));
24
19
  process.on('SIGINT', async () => {
@@ -7,20 +7,16 @@ export interface HelperOptions {
7
7
  isEnvDevelopment: boolean;
8
8
  isEnvProduction: boolean;
9
9
  configType: `${WebpackMode}`;
10
- buildDirectory: string;
11
- entriesDirectory: string;
12
- isSsr: boolean;
13
10
  }
14
11
  export declare const enum WebpackMode {
15
12
  Prod = "production",
16
13
  Dev = "development"
17
14
  }
18
- export declare function webpackConfigFactory(webpackMode: WebpackMode, config: NormalizedClientConfig, { logger, isSsr }?: {
15
+ export declare function webpackConfigFactory(webpackMode: WebpackMode, config: NormalizedClientConfig, { logger }?: {
19
16
  logger?: Logger;
20
- isSsr?: boolean;
21
17
  }): Promise<webpack.Configuration>;
22
18
  export declare function configureModuleRules(helperOptions: HelperOptions, additionalRules?: NonNullable<webpack.RuleSetRule['oneOf']>): webpack.RuleSetRule[];
23
19
  export declare function configureResolve({ isEnvProduction, config }: HelperOptions): webpack.ResolveOptions;
24
20
  type Optimization = NonNullable<webpack.Configuration['optimization']>;
25
- export declare function configureOptimization({ config, isSsr }: HelperOptions): Optimization;
21
+ export declare function configureOptimization({ config }: HelperOptions): Optimization;
26
22
  export {};
@@ -44,7 +44,6 @@ const react_refresh_webpack_plugin_1 = __importDefault(require("@pmmmwh/react-re
44
44
  const moment_timezone_data_webpack_plugin_1 = __importDefault(require("moment-timezone-data-webpack-plugin"));
45
45
  const webpack_plugin_1 = __importDefault(require("@statoscope/webpack-plugin"));
46
46
  const circular_dependency_plugin_1 = __importDefault(require("circular-dependency-plugin"));
47
- const webpack_node_externals_1 = __importDefault(require("webpack-node-externals"));
48
47
  const paths_1 = __importDefault(require("../paths"));
49
48
  const babel_1 = require("../babel");
50
49
  const progress_plugin_1 = require("./progress-plugin");
@@ -54,7 +53,7 @@ const log_config_1 = require("../logger/log-config");
54
53
  const utils_2 = require("../typescript/utils");
55
54
  const imagesSizeLimit = 2048;
56
55
  const fontSizeLimit = 8192;
57
- async function webpackConfigFactory(webpackMode, config, { logger, isSsr = false } = {}) {
56
+ async function webpackConfigFactory(webpackMode, config, { logger } = {}) {
58
57
  const isEnvDevelopment = webpackMode === "development" /* WebpackMode.Dev */;
59
58
  const isEnvProduction = webpackMode === "production" /* WebpackMode.Prod */;
60
59
  const helperOptions = {
@@ -63,25 +62,11 @@ async function webpackConfigFactory(webpackMode, config, { logger, isSsr = false
63
62
  isEnvDevelopment,
64
63
  isEnvProduction,
65
64
  configType: webpackMode,
66
- buildDirectory: isSsr ? paths_1.default.appSsrBuild : paths_1.default.appBuild,
67
- entriesDirectory: isSsr ? paths_1.default.appSsrEntry : paths_1.default.appEntry,
68
- isSsr,
69
65
  };
70
- let externals = config.externals;
71
- if (isSsr) {
72
- externals =
73
- config.ssr?.noExternal === true
74
- ? undefined
75
- : (0, webpack_node_externals_1.default)({
76
- allowlist: config.ssr?.noExternal,
77
- importType: config.ssr?.moduleType === 'esm' ? 'module' : 'commonjs',
78
- });
79
- }
80
66
  let webpackConfig = {
81
67
  mode: webpackMode,
82
68
  context: paths_1.default.app,
83
69
  bail: isEnvProduction,
84
- target: isSsr ? 'node' : undefined,
85
70
  devtool: configureDevTool(helperOptions),
86
71
  entry: configureEntry(helperOptions),
87
72
  output: configureOutput(helperOptions),
@@ -91,7 +76,7 @@ async function webpackConfigFactory(webpackMode, config, { logger, isSsr = false
91
76
  },
92
77
  plugins: configurePlugins(helperOptions),
93
78
  optimization: configureOptimization(helperOptions),
94
- externals,
79
+ externals: config.externals,
95
80
  node: config.node,
96
81
  watchOptions: configureWatchOptions(helperOptions),
97
82
  ignoreWarnings: [/Failed to parse source map/],
@@ -107,7 +92,7 @@ async function webpackConfigFactory(webpackMode, config, { logger, isSsr = false
107
92
  },
108
93
  cache: config.cache,
109
94
  };
110
- webpackConfig = await config.webpack(webpackConfig, { configType: webpackMode, isSsr });
95
+ webpackConfig = await config.webpack(webpackConfig, { configType: webpackMode });
111
96
  if (config.debugWebpack) {
112
97
  (0, log_config_1.logConfig)('Preview webpack config', webpackConfig);
113
98
  }
@@ -150,10 +135,7 @@ function configureWatchOptions({ config }) {
150
135
  delete watchOptions.watchPackages;
151
136
  return watchOptions;
152
137
  }
153
- function configureExperiments({ config, isEnvProduction, isSsr, }) {
154
- if (isSsr) {
155
- return config.ssr?.moduleType === 'esm' ? { outputModule: true } : undefined;
156
- }
138
+ function configureExperiments({ config, isEnvProduction, }) {
157
139
  if (isEnvProduction) {
158
140
  return undefined;
159
141
  }
@@ -208,74 +190,61 @@ function createEntryArray(entry) {
208
190
  return [require.resolve('./public-path'), entry];
209
191
  }
210
192
  function addEntry(entry, file) {
193
+ const newEntry = path.resolve(paths_1.default.appEntry, file);
211
194
  return {
212
195
  ...entry,
213
- [path.parse(file).name]: createEntryArray(file),
196
+ [path.parse(file).name]: createEntryArray(newEntry),
214
197
  };
215
198
  }
216
- function configureEntry({ config, entriesDirectory }) {
217
- let entries = fs.readdirSync(entriesDirectory).filter((file) => /\.[jt]sx?$/.test(file));
199
+ function configureEntry({ config }) {
200
+ let entries = fs.readdirSync(paths_1.default.appEntry).filter((file) => /\.[jt]sx?$/.test(file));
218
201
  if (Array.isArray(config.entryFilter) && config.entryFilter.length) {
219
202
  entries = entries.filter((entry) => config.entryFilter?.includes(entry.split('.')[0] ?? ''));
220
203
  }
221
204
  if (!entries.length) {
222
- throw new Error('No entries were found after applying entry filter');
205
+ throw new Error('No entries were found after applying UI_CORE_ENTRY_FILTER');
223
206
  }
224
- return entries.reduce((entry, file) => addEntry(entry, path.resolve(entriesDirectory, file)), {});
207
+ return entries.reduce((entry, file) => addEntry(entry, file), {});
225
208
  }
226
- function getFileNames({ isEnvProduction, isSsr, config }) {
227
- let ext = 'js';
228
- if (isSsr) {
229
- ext = config.ssr?.moduleType === 'esm' ? 'mjs' : 'cjs';
230
- }
209
+ function getFileNames({ isEnvProduction }) {
231
210
  return {
232
- filename: isEnvProduction ? `js/[name].[contenthash:8].${ext}` : `js/[name].${ext}`,
211
+ filename: isEnvProduction ? 'js/[name].[contenthash:8].js' : 'js/[name].js',
233
212
  chunkFilename: isEnvProduction
234
213
  ? 'js/[name].[contenthash:8].chunk.js'
235
214
  : 'js/[name].chunk.js',
236
215
  };
237
216
  }
238
- function configureOutput(options) {
239
- let ssrOptions;
240
- if (options.isSsr) {
241
- ssrOptions = {
242
- library: { type: options.config.ssr?.moduleType === 'esm' ? 'module' : 'commonjs2' },
243
- chunkFormat: false,
244
- };
245
- }
217
+ function configureOutput({ isEnvDevelopment, ...rest }) {
246
218
  return {
247
- ...getFileNames(options),
248
- path: options.buildDirectory,
249
- pathinfo: options.isEnvDevelopment,
250
- ...ssrOptions,
219
+ ...getFileNames({ isEnvDevelopment, ...rest }),
220
+ path: paths_1.default.appBuild,
221
+ pathinfo: isEnvDevelopment,
251
222
  };
252
223
  }
253
- function createJavaScriptLoader({ isEnvProduction, isEnvDevelopment, configType, config, isSsr, }) {
224
+ function createJavaScriptLoader({ isEnvProduction, isEnvDevelopment, configType, config, }) {
254
225
  const plugins = [];
255
- if (!isSsr) {
256
- if (isEnvDevelopment && config.reactRefresh !== false) {
257
- plugins.push([
258
- require.resolve('react-refresh/babel'),
259
- config.devServer?.webSocketPath
260
- ? {
261
- overlay: {
262
- sockPath: config.devServer.webSocketPath,
263
- },
264
- }
265
- : undefined,
266
- ]);
267
- }
268
- if (isEnvProduction) {
269
- plugins.push([
270
- require.resolve('babel-plugin-import'),
271
- { libraryName: 'lodash', libraryDirectory: '', camel2DashComponentName: false },
272
- ]);
273
- }
226
+ if (isEnvDevelopment && config.reactRefresh !== false) {
227
+ plugins.push([
228
+ require.resolve('react-refresh/babel'),
229
+ config.devServer?.webSocketPath
230
+ ? {
231
+ overlay: {
232
+ sockPath: config.devServer.webSocketPath,
233
+ },
234
+ }
235
+ : undefined,
236
+ ]);
237
+ }
238
+ if (isEnvProduction) {
239
+ plugins.push([
240
+ require.resolve('babel-plugin-import'),
241
+ { libraryName: 'lodash', libraryDirectory: '', camel2DashComponentName: false },
242
+ ]);
274
243
  }
275
244
  const transformOptions = config.babel({
276
- presets: [(0, babel_1.babelPreset)({ newJsxTransform: config.newJsxTransform, isSsr })],
245
+ presets: [(0, babel_1.babelPreset)(config)],
277
246
  plugins,
278
- }, { configType, isSsr });
247
+ }, { configType });
279
248
  return {
280
249
  loader: require.resolve('babel-loader'),
281
250
  options: {
@@ -370,7 +339,7 @@ function createStylesRule(options) {
370
339
  use: loaders,
371
340
  };
372
341
  }
373
- function getCssLoaders({ isEnvDevelopment, isEnvProduction, config, isSsr }, additionalRules) {
342
+ function getCssLoaders({ isEnvDevelopment, isEnvProduction, config }, additionalRules) {
374
343
  const loaders = [];
375
344
  if (!config.transformCssWithLightningCss) {
376
345
  loaders.push({
@@ -393,32 +362,27 @@ function getCssLoaders({ isEnvDevelopment, isEnvProduction, config, isSsr }, add
393
362
  loaders.unshift({
394
363
  loader: require.resolve('css-loader'),
395
364
  options: {
365
+ esModule: false,
396
366
  sourceMap: !config.disableSourceMapGeneration,
397
367
  importLoaders,
398
368
  modules: {
399
369
  auto: true,
400
370
  localIdentName: '[name]__[local]--[hash:base64:5]',
401
371
  exportLocalsConvention: 'camelCase',
402
- exportOnlyLocals: isSsr,
403
372
  },
404
373
  },
405
374
  });
406
375
  if (isEnvProduction) {
407
- loaders.unshift({ loader: mini_css_extract_plugin_1.default.loader, options: { emit: !isSsr } });
376
+ loaders.unshift(mini_css_extract_plugin_1.default.loader);
408
377
  }
409
378
  if (isEnvDevelopment) {
410
- if (isSsr || config.ssr) {
411
- loaders.unshift({ loader: mini_css_extract_plugin_1.default.loader, options: { emit: !isSsr } });
412
- }
413
- else {
414
- loaders.unshift({
415
- loader: require.resolve('style-loader'),
416
- });
417
- }
379
+ loaders.unshift({
380
+ loader: require.resolve('style-loader'),
381
+ });
418
382
  }
419
383
  return loaders;
420
384
  }
421
- function createIconsRule({ isEnvProduction, config, isSsr }, jsLoader) {
385
+ function createIconsRule({ isEnvProduction, config }, jsLoader) {
422
386
  const iconIncludes = config.icons || [];
423
387
  return {
424
388
  // eslint-disable-next-line security/detect-unsafe-regex
@@ -455,12 +419,11 @@ function createIconsRule({ isEnvProduction, config, isSsr }, jsLoader) {
455
419
  generator: {
456
420
  filename: 'assets/images/[name].[contenthash:8][ext]',
457
421
  publicPath: isEnvProduction ? '../' : undefined,
458
- emit: isSsr ? false : undefined,
459
422
  },
460
423
  }),
461
424
  };
462
425
  }
463
- function createAssetsRules({ isEnvProduction, config, isSsr }) {
426
+ function createAssetsRules({ isEnvProduction, config }) {
464
427
  const imagesRule = {
465
428
  test: /\.(ico|bmp|gif|jpe?g|png|svg)$/,
466
429
  include: [paths_1.default.appClient, ...(config.images || [])],
@@ -472,7 +435,6 @@ function createAssetsRules({ isEnvProduction, config, isSsr }) {
472
435
  },
473
436
  generator: {
474
437
  filename: 'assets/images/[name].[contenthash:8][ext]',
475
- emit: isSsr ? false : undefined,
476
438
  },
477
439
  };
478
440
  const fontsRule = {
@@ -486,7 +448,6 @@ function createAssetsRules({ isEnvProduction, config, isSsr }) {
486
448
  },
487
449
  generator: {
488
450
  filename: 'assets/fonts/[name].[contenthash:8][ext]',
489
- emit: isSsr ? false : undefined,
490
451
  },
491
452
  };
492
453
  const rules = [imagesRule, fontsRule];
@@ -506,7 +467,6 @@ function createAssetsRules({ isEnvProduction, config, isSsr }) {
506
467
  generator: {
507
468
  filename: 'assets/images/[name].[contenthash:8][ext]',
508
469
  publicPath: '../',
509
- emit: isSsr ? false : undefined,
510
470
  },
511
471
  }, {
512
472
  test: /\.(ttf|eot|woff2?)$/,
@@ -521,19 +481,17 @@ function createAssetsRules({ isEnvProduction, config, isSsr }) {
521
481
  generator: {
522
482
  filename: 'assets/fonts/[name].[contenthash:8][ext]',
523
483
  publicPath: '../',
524
- emit: isSsr ? false : undefined,
525
484
  },
526
485
  });
527
486
  }
528
487
  return rules;
529
488
  }
530
- function createFallbackRules({ isEnvProduction, isSsr }) {
489
+ function createFallbackRules({ isEnvProduction }) {
531
490
  const rules = [
532
491
  {
533
492
  type: 'asset/resource',
534
493
  generator: {
535
494
  filename: 'assets/[name].[contenthash:8][ext]',
536
- emit: isSsr ? false : undefined,
537
495
  },
538
496
  exclude: [/\.[jt]sx?$/, /\.json$/, /\.[cm]js$/, /\.ejs$/],
539
497
  },
@@ -548,7 +506,6 @@ function createFallbackRules({ isEnvProduction, isSsr }) {
548
506
  generator: {
549
507
  filename: 'assets/[name].[contenthash:8][ext]',
550
508
  publicPath: '../',
551
- emit: isSsr ? false : undefined,
552
509
  },
553
510
  });
554
511
  }
@@ -563,7 +520,7 @@ function createMomentTimezoneDataPlugin(options = {}) {
563
520
  return new moment_timezone_data_webpack_plugin_1.default({ ...options, startYear, endYear });
564
521
  }
565
522
  function configurePlugins(options) {
566
- const { isEnvDevelopment, isEnvProduction, config, isSsr } = options;
523
+ const { isEnvDevelopment, isEnvProduction, config } = options;
567
524
  const excludeFromClean = config.excludeFromClean || [];
568
525
  const manifestFile = 'assets-manifest.json';
569
526
  const plugins = [
@@ -587,11 +544,11 @@ function configurePlugins(options) {
587
544
  : {
588
545
  entrypoints: true,
589
546
  writeToDisk: true,
590
- output: path.resolve(options.buildDirectory, manifestFile),
547
+ output: path.resolve(paths_1.default.appBuild, manifestFile),
591
548
  }),
549
+ createMomentTimezoneDataPlugin(config.momentTz),
592
550
  new webpack.DefinePlugin({
593
551
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
594
- 'process.env.IS_SSR': JSON.stringify(isSsr),
595
552
  ...config.definitions,
596
553
  }),
597
554
  ];
@@ -601,12 +558,51 @@ function configurePlugins(options) {
601
558
  if (process.env.WEBPACK_PROFILE === 'true') {
602
559
  plugins.push(new webpack.debug.ProfilingPlugin());
603
560
  }
561
+ const contextReplacement = config.contextReplacement || {};
562
+ plugins.push(new webpack.ContextReplacementPlugin(/moment[\\/]locale$/,
563
+ // eslint-disable-next-line security/detect-non-literal-regexp
564
+ new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})$`)));
565
+ plugins.push(new webpack.ContextReplacementPlugin(/dayjs[\\/]locale$/,
566
+ // eslint-disable-next-line security/detect-non-literal-regexp
567
+ new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})\\.js$`)));
568
+ if (contextReplacement['highlight.js']) {
569
+ plugins.push(new webpack.ContextReplacementPlugin(/highlight\.js[\\/]lib[\\/]languages$/,
570
+ // eslint-disable-next-line security/detect-non-literal-regexp
571
+ new RegExp(`^\\./(${contextReplacement['highlight.js'].join('|')})$`)));
572
+ }
573
+ if (config.monaco) {
574
+ const MonacoEditorWebpackPlugin = require('monaco-editor-webpack-plugin');
575
+ plugins.push(new MonacoEditorWebpackPlugin({
576
+ filename: isEnvProduction ? '[name].[hash:8].worker.js' : undefined,
577
+ ...config.monaco,
578
+ // currently, workers located on cdn are not working properly, so we are enforcing loading workers from
579
+ // service instead
580
+ publicPath: path.normalize(config.publicPathPrefix + '/build/'),
581
+ }));
582
+ }
583
+ if (isEnvDevelopment && config.reactRefresh !== false) {
584
+ const { webSocketPath = path.normalize(`/${config.publicPathPrefix}/build/sockjs-node`) } = config.devServer || {};
585
+ plugins.push(new react_refresh_webpack_plugin_1.default(config.reactRefresh({
586
+ overlay: { sockPath: webSocketPath },
587
+ exclude: [/node_modules/, /\.worker\.[jt]sx?$/],
588
+ })));
589
+ }
590
+ if (config.detectCircularDependencies) {
591
+ let circularPluginOptions = {
592
+ exclude: /node_modules/,
593
+ allowAsyncCycles: true,
594
+ };
595
+ if (typeof config.detectCircularDependencies === 'object') {
596
+ circularPluginOptions = config.detectCircularDependencies;
597
+ }
598
+ plugins.push(new circular_dependency_plugin_1.default(circularPluginOptions));
599
+ }
604
600
  if (config.forkTsChecker !== false) {
605
601
  plugins.push(new fork_ts_checker_webpack_plugin_1.default({
606
602
  ...config.forkTsChecker,
607
603
  typescript: {
608
604
  typescriptPath: (0, utils_2.resolveTypescript)(),
609
- configFile: path.resolve(paths_1.default.appClient, 'tsconfig.json'),
605
+ configFile: path.resolve(paths_1.default.app, 'src/ui/tsconfig.json'),
610
606
  diagnosticOptions: {
611
607
  syntactic: true,
612
608
  },
@@ -615,17 +611,19 @@ function configurePlugins(options) {
615
611
  },
616
612
  }));
617
613
  }
618
- if (config.detectCircularDependencies) {
619
- let circularPluginOptions = {
620
- exclude: /node_modules/,
621
- allowAsyncCycles: true,
622
- };
623
- if (typeof config.detectCircularDependencies === 'object') {
624
- circularPluginOptions = config.detectCircularDependencies;
625
- }
626
- plugins.push(new circular_dependency_plugin_1.default(circularPluginOptions));
614
+ if (config.polyfill?.process) {
615
+ plugins.push(new webpack.ProvidePlugin({ process: 'process/browser.js' }));
627
616
  }
628
617
  if (isEnvProduction) {
618
+ plugins.push(new mini_css_extract_plugin_1.default({
619
+ filename: 'css/[name].[contenthash:8].css',
620
+ chunkFilename: 'css/[name].[contenthash:8].chunk.css',
621
+ ignoreOrder: true,
622
+ }));
623
+ if (config.sentryConfig) {
624
+ const sentryPlugin = require('@sentry/webpack-plugin').sentryWebpackPlugin;
625
+ plugins.push(sentryPlugin({ ...config.sentryConfig }));
626
+ }
629
627
  if (config.analyzeBundle === 'true') {
630
628
  plugins.push(new webpack_bundle_analyzer_1.BundleAnalyzerPlugin({
631
629
  openAnalyzer: false,
@@ -636,8 +634,8 @@ function configurePlugins(options) {
636
634
  if (config.analyzeBundle === 'statoscope') {
637
635
  const customStatoscopeConfig = config.statoscopeConfig || {};
638
636
  plugins.push(new webpack_plugin_1.default({
639
- saveReportTo: path.resolve(options.buildDirectory, 'report.html'),
640
- saveStatsTo: path.resolve(options.buildDirectory, 'stats.json'),
637
+ saveReportTo: path.resolve(paths_1.default.appBuild, 'report.html'),
638
+ saveStatsTo: path.resolve(paths_1.default.appBuild, 'stats.json'),
641
639
  open: false,
642
640
  statsOptions: {
643
641
  all: true,
@@ -646,104 +644,50 @@ function configurePlugins(options) {
646
644
  }));
647
645
  }
648
646
  }
649
- if (isEnvProduction || isSsr || config.ssr) {
650
- plugins.push(new mini_css_extract_plugin_1.default({
651
- filename: isEnvProduction ? 'css/[name].[contenthash:8].css' : 'css/[name].css',
652
- chunkFilename: isEnvProduction
653
- ? 'css/[name].[contenthash:8].chunk.css'
654
- : 'css/[name].chunk.css',
655
- ignoreOrder: true,
656
- }));
657
- }
658
- if (!isSsr) {
659
- if (config.monaco) {
660
- const MonacoEditorWebpackPlugin = require('monaco-editor-webpack-plugin');
661
- plugins.push(new MonacoEditorWebpackPlugin({
662
- filename: isEnvProduction ? '[name].[hash:8].worker.js' : undefined,
663
- ...config.monaco,
664
- // currently, workers located on cdn are not working properly, so we are enforcing loading workers from
665
- // service instead
666
- publicPath: path.normalize(config.publicPathPrefix + '/build/'),
667
- }));
647
+ if (config.cdn) {
648
+ let credentialsGlobal;
649
+ if (process.env.FRONTEND_S3_ACCESS_KEY_ID && process.env.FRONTEND_S3_SECRET_ACCESS_KEY) {
650
+ credentialsGlobal = {
651
+ accessKeyId: process.env.FRONTEND_S3_ACCESS_KEY_ID,
652
+ secretAccessKey: process.env.FRONTEND_S3_SECRET_ACCESS_KEY,
653
+ };
668
654
  }
669
- const contextReplacement = config.contextReplacement || {};
670
- plugins.push(createMomentTimezoneDataPlugin(config.momentTz));
671
- plugins.push(new webpack.ContextReplacementPlugin(/moment[\\/]locale$/,
672
- // eslint-disable-next-line security/detect-non-literal-regexp
673
- new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})$`)));
674
- plugins.push(new webpack.ContextReplacementPlugin(/dayjs[\\/]locale$/,
675
- // eslint-disable-next-line security/detect-non-literal-regexp
676
- new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})\\.js$`)));
677
- if (contextReplacement['highlight.js']) {
678
- plugins.push(new webpack.ContextReplacementPlugin(/highlight\.js[\\/]lib[\\/]languages$/,
679
- // eslint-disable-next-line security/detect-non-literal-regexp
680
- new RegExp(`^\\./(${contextReplacement['highlight.js'].join('|')})$`)));
681
- }
682
- if (isEnvDevelopment && config.reactRefresh !== false) {
683
- const { webSocketPath = path.normalize(`/${config.publicPathPrefix}/build/sockjs-node`), } = config.devServer || {};
684
- plugins.push(new react_refresh_webpack_plugin_1.default(config.reactRefresh({
685
- overlay: { sockPath: webSocketPath },
686
- exclude: [/node_modules/, /\.worker\.[jt]sx?$/],
687
- })));
688
- }
689
- if (config.polyfill?.process) {
690
- plugins.push(new webpack.ProvidePlugin({ process: 'process/browser.js' }));
691
- }
692
- if (isEnvProduction) {
693
- if (config.sentryConfig) {
694
- const sentryPlugin = require('@sentry/webpack-plugin').sentryWebpackPlugin;
695
- plugins.push(sentryPlugin({ ...config.sentryConfig }));
655
+ const cdns = Array.isArray(config.cdn) ? config.cdn : [config.cdn];
656
+ for (let index = 0; index < cdns.length; index++) {
657
+ const cdn = cdns[index];
658
+ if (!cdn) {
659
+ continue;
696
660
  }
697
- }
698
- if (config.cdn) {
699
- let credentialsGlobal;
700
- if (process.env.FRONTEND_S3_ACCESS_KEY_ID &&
701
- process.env.FRONTEND_S3_SECRET_ACCESS_KEY) {
702
- credentialsGlobal = {
703
- accessKeyId: process.env.FRONTEND_S3_ACCESS_KEY_ID,
704
- secretAccessKey: process.env.FRONTEND_S3_SECRET_ACCESS_KEY,
661
+ let credentials = credentialsGlobal;
662
+ const accessKeyId = process.env[`FRONTEND_S3_ACCESS_KEY_ID_${index}`];
663
+ const secretAccessKey = process.env[`FRONTEND_S3_SECRET_ACCESS_KEY_${index}`];
664
+ if (accessKeyId && secretAccessKey) {
665
+ credentials = {
666
+ accessKeyId,
667
+ secretAccessKey,
705
668
  };
706
669
  }
707
- const cdns = Array.isArray(config.cdn) ? config.cdn : [config.cdn];
708
- for (let index = 0; index < cdns.length; index++) {
709
- const cdn = cdns[index];
710
- if (!cdn) {
711
- continue;
712
- }
713
- let credentials = credentialsGlobal;
714
- const accessKeyId = process.env[`FRONTEND_S3_ACCESS_KEY_ID_${index}`];
715
- const secretAccessKey = process.env[`FRONTEND_S3_SECRET_ACCESS_KEY_${index}`];
716
- if (accessKeyId && secretAccessKey) {
717
- credentials = {
718
- accessKeyId,
719
- secretAccessKey,
720
- };
721
- }
722
- plugins.push(new s3_upload_1.S3UploadPlugin({
723
- exclude: config.hiddenSourceMap ? /\.map$/ : undefined,
724
- compress: cdn.compress,
725
- s3ClientOptions: {
726
- region: cdn.region,
727
- endpoint: cdn.endpoint,
728
- credentials,
729
- },
730
- s3UploadOptions: {
731
- bucket: cdn.bucket,
732
- targetPath: cdn.prefix,
733
- cacheControl: cdn.cacheControl,
734
- },
735
- additionalPattern: cdn.additionalPattern,
736
- logger: options.logger,
737
- }));
738
- }
670
+ plugins.push(new s3_upload_1.S3UploadPlugin({
671
+ exclude: config.hiddenSourceMap ? /\.map$/ : undefined,
672
+ compress: cdn.compress,
673
+ s3ClientOptions: {
674
+ region: cdn.region,
675
+ endpoint: cdn.endpoint,
676
+ credentials,
677
+ },
678
+ s3UploadOptions: {
679
+ bucket: cdn.bucket,
680
+ targetPath: cdn.prefix,
681
+ cacheControl: cdn.cacheControl,
682
+ },
683
+ additionalPattern: cdn.additionalPattern,
684
+ logger: options.logger,
685
+ }));
739
686
  }
740
687
  }
741
688
  return plugins;
742
689
  }
743
- function configureOptimization({ config, isSsr }) {
744
- if (isSsr) {
745
- return {};
746
- }
690
+ function configureOptimization({ config }) {
747
691
  const configVendors = config.vendors ?? [];
748
692
  let vendorsList = [
749
693
  'react',
@@ -1,4 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- // @ts-expect-error
4
- __webpack_public_path__ = globalThis.__PUBLIC_PATH__ ?? '/build/';
3
+ __webpack_public_path__ = window.__PUBLIC_PATH__ ?? '/build/';
@@ -35,7 +35,6 @@ const css_minimizer_webpack_plugin_1 = __importDefault(require("css-minimizer-we
35
35
  const config_1 = require("./config");
36
36
  const config_2 = require("../config");
37
37
  const models_1 = require("../models");
38
- const paths_1 = __importDefault(require("../paths"));
39
38
  async function configureServiceWebpackConfig(mode, storybookConfig) {
40
39
  const serviceConfig = await (0, config_2.getProjectConfig)(mode === "production" /* WebpackMode.Prod */ ? 'build' : 'dev', {
41
40
  storybook: true,
@@ -105,9 +104,6 @@ async function configureWebpackConfigForStorybook(mode, userConfig = {}, storybo
105
104
  isEnvProduction,
106
105
  config: config.client,
107
106
  configType: mode,
108
- buildDirectory: paths_1.default.appBuild,
109
- entriesDirectory: paths_1.default.appEntry,
110
- isSsr: false,
111
107
  };
112
108
  return {
113
109
  module: {
@@ -1,6 +1,6 @@
1
1
  import type webpack from 'webpack';
2
2
  import type { Logger } from '../logger';
3
- export declare function webpackCompilerHandlerFactory(logger: Logger, onCompilationEnd?: () => void): (err?: Error | null, stats?: webpack.MultiStats) => Promise<void>;
3
+ export declare function webpackCompilerHandlerFactory(logger: Logger, onCompilationEnd?: () => void): (err?: Error | null, stats?: webpack.Stats) => Promise<void>;
4
4
  export declare function resolveTsconfigPathsToAlias(tsConfigPath: string): {
5
5
  aliases: Record<string, string[]>;
6
6
  modules: string[];
@@ -50,16 +50,11 @@ function webpackCompilerHandlerFactory(logger, onCompilationEnd) {
50
50
  if (onCompilationEnd) {
51
51
  await onCompilationEnd();
52
52
  }
53
- const [clientStats, ssrStats] = stats?.stats ?? [];
54
- if (clientStats) {
55
- const time = clientStats.endTime - clientStats.startTime;
53
+ if (stats) {
54
+ const time = stats.endTime - stats.startTime;
56
55
  logger.success(`Client was successfully compiled in ${(0, pretty_time_1.prettyTime)(BigInt(time) * BigInt(1_000_000))}`);
57
56
  }
58
- if (ssrStats) {
59
- const time = ssrStats.endTime - ssrStats.startTime;
60
- logger.success(`SSR: Client was successfully compiled in ${(0, pretty_time_1.prettyTime)(BigInt(time) * BigInt(1_000_000))}`);
61
- }
62
- if (!clientStats && !ssrStats) {
57
+ else {
63
58
  logger.success(`Client was successfully compiled`);
64
59
  }
65
60
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/app-builder",
3
- "version": "0.14.0-beta.1",
3
+ "version": "0.14.0-beta.2",
4
4
  "description": "Develop and build your React client-server projects, powered by typescript and webpack",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -129,7 +129,6 @@
129
129
  "webpack-bundle-analyzer": "^4.10.2",
130
130
  "webpack-dev-server": "^5.1.0",
131
131
  "webpack-manifest-plugin": "^5.0.0",
132
- "webpack-node-externals": "^3.0.0",
133
132
  "worker-loader": "^3.0.8",
134
133
  "yargs": "^17.7.2"
135
134
  },
@@ -153,7 +152,6 @@
153
152
  "@types/webpack-assets-manifest": "^5.1.4",
154
153
  "@types/webpack-bundle-analyzer": "^4.7.0",
155
154
  "@types/webpack-manifest-plugin": "^3.0.8",
156
- "@types/webpack-node-externals": "^3.0.4",
157
155
  "@types/yargs": "17.0.11",
158
156
  "babel-plugin-tester": "^11.0.4",
159
157
  "eslint": "^8.57.0",