@gravity-ui/app-builder 0.28.1-beta.2 → 0.28.1-beta.5

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
@@ -81,7 +81,6 @@ export default defineConfig(
81
81
  },
82
82
  server: {
83
83
  // server settings
84
- tsconfigFileName: 'custom-tsconfig.json',
85
84
  },
86
85
  };
87
86
  },
@@ -144,8 +143,8 @@ All server settings are used only in dev mode:
144
143
  - `watchThrottle` (`number`) — use to add an extra throttle, or delay restarting.
145
144
  - `inspect/inspectBrk` (`number | true`) — listen for a debugging client on specified port.
146
145
  If specified `true`, try to listen on `9229`.
147
- - `tsconfig` (`string`) — name of the tsconfig file for server build.
148
- Default: `tsconfig.json`.
146
+ - `compiler` (`'typescript' | 'swc'`) — choose TypeScript compiler for server code compilation.
147
+ Default is `'typescript'`. Set to `'swc'` for faster compilation with SWC.
149
148
 
150
149
  ### Client
151
150
 
@@ -1,17 +1,56 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
29
  exports.buildServer = buildServer;
30
+ const path = __importStar(require("node:path"));
7
31
  const signal_exit_1 = require("signal-exit");
8
32
  const controllable_script_1 = require("../../../common/child-process/controllable-script");
33
+ const logger_1 = require("../../../common/logger");
9
34
  const paths_1 = __importDefault(require("../../../common/paths"));
10
35
  const utils_1 = require("../../../common/utils");
36
+ const swc = __importStar(require("../../../common/swc"));
11
37
  function buildServer(config) {
12
38
  (0, utils_1.createRunFolder)();
39
+ if (config.server.compiler === 'swc') {
40
+ // Используем SWC для компиляции
41
+ return new Promise((resolve, reject) => {
42
+ const logger = new logger_1.Logger('server', config.verbose);
43
+ const serverPath = path.resolve(paths_1.default.appDist, 'server');
44
+ swc.compile({
45
+ projectPath: paths_1.default.appServer,
46
+ outputPath: serverPath,
47
+ logger,
48
+ enableSourceMap: false,
49
+ }).then(() => resolve(), (error) => reject(new Error(`SWC compilation failed: ${error}`)));
50
+ });
51
+ }
52
+ // Используем TypeScript для компиляции (по умолчанию)
13
53
  return new Promise((resolve, reject) => {
14
- const tsconfigFileName = config.server.tsconfigFileName || 'tsconfig.json';
15
54
  const build = new controllable_script_1.ControllableScript(`
16
55
  let ts;
17
56
  try {
@@ -26,11 +65,7 @@ function buildServer(config) {
26
65
  const {compile} = require(${JSON.stringify(require.resolve('../../../common/typescript/compile'))});
27
66
 
28
67
  const logger = new Logger('server', ${config.verbose});
29
- compile(ts, {
30
- logger,
31
- projectPath: ${JSON.stringify(paths_1.default.appServer)},
32
- configFileName: ${JSON.stringify(tsconfigFileName)}
33
- });
68
+ compile(ts, {logger, projectPath: ${JSON.stringify(paths_1.default.appServer)}});
34
69
  `, null);
35
70
  build.start().then(() => {
36
71
  build.onExit((code) => {
@@ -32,38 +32,68 @@ const rimraf_1 = require("rimraf");
32
32
  const controllable_script_1 = require("../../common/child-process/controllable-script");
33
33
  const utils_1 = require("../../common/utils");
34
34
  const paths_1 = __importDefault(require("../../common/paths"));
35
+ function createTypescriptBuildScript(config) {
36
+ return `
37
+ let ts;
38
+ try {
39
+ ts = require('typescript');
40
+ } catch (e) {
41
+ if (e.code !== 'MODULE_NOT_FOUND') {
42
+ throw e;
43
+ }
44
+ ts = require(${JSON.stringify(require.resolve('typescript'))});
45
+ }
46
+ const {Logger} = require(${JSON.stringify(require.resolve('../../common/logger'))});
47
+ const {watch} = require(${JSON.stringify(require.resolve('../../common/typescript/watch'))});
48
+
49
+ const logger = new Logger('server', ${config.verbose});
50
+ watch(
51
+ ts,
52
+ ${JSON.stringify(paths_1.default.appServer)},
53
+ {
54
+ logger,
55
+ onAfterFilesEmitted: () => {
56
+ process.send({type: 'Emitted'});
57
+ },
58
+ enableSourceMap: true
59
+ }
60
+ );`;
61
+ }
62
+ function createSWCBuildScript(config) {
63
+ return `
64
+ let swcCli;
65
+ try {
66
+ swcCli = require('@swc/cli');
67
+ } catch (e) {
68
+ if (e.code !== 'MODULE_NOT_FOUND') {
69
+ throw e;
70
+ }
71
+ swcCli = require(${JSON.stringify(require.resolve('@swc/cli'))});
72
+ }
73
+ const {swcDir} = swcCli;
74
+ const {Logger} = require(${JSON.stringify(require.resolve('../../common/logger'))});
75
+ const {watch} = require(${JSON.stringify(require.resolve('../../common/swc/watch'))});
76
+
77
+ const logger = new Logger('server', ${config.verbose});
78
+ watch(
79
+ swcDir,
80
+ ${JSON.stringify(paths_1.default.appServer)},
81
+ {
82
+ logger,
83
+ onAfterFilesEmitted: () => {
84
+ process.send({type: 'Emitted'});
85
+ },
86
+ enableSourceMap: true
87
+ }
88
+ );`;
89
+ }
35
90
  async function watchServerCompilation(config) {
36
91
  const serverPath = path.resolve(paths_1.default.appDist, 'server');
37
92
  rimraf_1.rimraf.sync(serverPath);
38
93
  (0, utils_1.createRunFolder)();
39
- const tsconfigFileName = config.server.tsconfigFileName || 'tsconfig.json';
40
- const build = new controllable_script_1.ControllableScript(`
41
- let ts;
42
- try {
43
- ts = require('typescript');
44
- } catch (e) {
45
- if (e.code !== 'MODULE_NOT_FOUND') {
46
- throw e;
47
- }
48
- ts = require(${JSON.stringify(require.resolve('typescript'))});
49
- }
50
- const {Logger} = require(${JSON.stringify(require.resolve('../../common/logger'))});
51
- const {watch} = require(${JSON.stringify(require.resolve('../../common/typescript/watch'))});
52
-
53
- const logger = new Logger('server', ${config.verbose});
54
- watch(
55
- ts,
56
- ${JSON.stringify(paths_1.default.appServer)},
57
- {
58
- logger,
59
- onAfterFilesEmitted: () => {
60
- process.send({type: 'Emitted'});
61
- },
62
- enableSourceMap: true,
63
- tsconfigFileName: ${JSON.stringify(tsconfigFileName)}
64
- }
65
- );
66
- `, null);
94
+ const build = new controllable_script_1.ControllableScript(config.server.compiler === 'swc'
95
+ ? createSWCBuildScript(config)
96
+ : createTypescriptBuildScript(config), null);
67
97
  await build.start();
68
98
  return build;
69
99
  }
@@ -154,6 +154,7 @@ async function normalizeConfig(userConfig, mode) {
154
154
  port: undefined,
155
155
  inspect: undefined,
156
156
  inspectBrk: undefined,
157
+ compiler: serverConfig.compiler || 'typescript',
157
158
  };
158
159
  if (mode === 'dev') {
159
160
  if (serverConfig.port === true) {
@@ -18,6 +18,7 @@ import type { TerserOptions } from 'terser-webpack-plugin';
18
18
  import type { ReactRefreshPluginOptions } from '@pmmmwh/react-refresh-webpack-plugin/types/lib/types';
19
19
  type Bundler = 'webpack' | 'rspack';
20
20
  type JavaScriptLoader = 'babel' | 'swc';
21
+ type ServerCompiler = 'typescript' | 'swc';
21
22
  export type SwcConfig = Swc.Config & Pick<Swc.Options, 'isModule'>;
22
23
  export interface Entities<T> {
23
24
  data: Record<string, T>;
@@ -267,10 +268,10 @@ export interface ServerConfig {
267
268
  inspect?: number | true;
268
269
  inspectBrk?: number | true;
269
270
  /**
270
- * Name of the tsconfig file for server build
271
- * Default: 'tsconfig.json'
271
+ * Compiler for server code compilation
272
+ * @default 'typescript'
272
273
  */
273
- tsconfigFileName?: string;
274
+ compiler?: ServerCompiler;
274
275
  }
275
276
  export interface ServiceConfig {
276
277
  target?: 'client' | 'server';
@@ -311,11 +312,12 @@ export type NormalizedClientConfig = Omit<ClientConfig, 'publicPathPrefix' | 'pu
311
312
  }) => SwcConfig | Promise<SwcConfig>;
312
313
  reactRefresh: NonNullable<ClientConfig['reactRefresh']>;
313
314
  };
314
- export type NormalizedServerConfig = Omit<ServerConfig, 'port' | 'inspect' | 'inspectBrk'> & {
315
+ export type NormalizedServerConfig = Omit<ServerConfig, 'port' | 'inspect' | 'inspectBrk' | 'compiler'> & {
315
316
  port?: number;
316
317
  verbose?: boolean;
317
318
  inspect?: number;
318
319
  inspectBrk?: number;
320
+ compiler: ServerCompiler;
319
321
  };
320
322
  export type NormalizedServiceConfig = Omit<ServiceConfig, 'client' | 'server'> & {
321
323
  client: NormalizedClientConfig;
@@ -0,0 +1,9 @@
1
+ import type { Logger } from '../logger';
2
+ interface SwcCompileOptions {
3
+ projectPath: string;
4
+ outputPath: string;
5
+ logger: Logger;
6
+ enableSourceMap?: boolean;
7
+ }
8
+ export declare function compile({ projectPath, outputPath, logger, enableSourceMap, }: SwcCompileOptions): Promise<void>;
9
+ export {};
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compile = compile;
4
+ const rimraf_1 = require("rimraf");
5
+ // @ts-ignore - @swc/cli не имеет типов
6
+ const cli_1 = require("@swc/cli");
7
+ const pretty_time_1 = require("../logger/pretty-time");
8
+ async function compile({ projectPath, outputPath, logger, enableSourceMap = false, }) {
9
+ const start = process.hrtime.bigint();
10
+ logger.message('Start SWC compilation');
11
+ // Очищаем выходную директорию
12
+ rimraf_1.rimraf.sync(outputPath);
13
+ const swcConfig = {
14
+ module: {
15
+ type: 'commonjs',
16
+ },
17
+ jsc: {
18
+ parser: {
19
+ syntax: 'typescript',
20
+ tsx: true,
21
+ },
22
+ target: 'es2020',
23
+ transform: {
24
+ decoratorMetadata: true,
25
+ },
26
+ externalHelpers: false,
27
+ },
28
+ sourceMaps: enableSourceMap,
29
+ };
30
+ const cliOptions = {
31
+ filenames: [projectPath],
32
+ outDir: outputPath,
33
+ watch: false,
34
+ quiet: false,
35
+ sourceMaps: enableSourceMap,
36
+ extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs'],
37
+ stripLeadingPaths: true,
38
+ deleteDirOnStart: false,
39
+ copyFiles: false,
40
+ includeDotfiles: false,
41
+ sync: false,
42
+ workers: 1,
43
+ };
44
+ return new Promise((resolve, reject) => {
45
+ const callbacks = {
46
+ onSuccess: (_result) => {
47
+ logger.success(`SWC compiled successfully in ${(0, pretty_time_1.elapsedTime)(start)}`);
48
+ resolve();
49
+ },
50
+ onFail: (result) => {
51
+ logger.error(`SWC compilation failed in ${result.duration}ms`);
52
+ if (result.reasons) {
53
+ for (const [filename, error] of result.reasons) {
54
+ logger.error(`${filename}: ${error}`);
55
+ }
56
+ }
57
+ logger.error(`Error compile, elapsed time ${(0, pretty_time_1.elapsedTime)(start)}`);
58
+ reject(new Error('SWC compilation failed'));
59
+ },
60
+ };
61
+ try {
62
+ (0, cli_1.swcDir)({
63
+ cliOptions,
64
+ swcOptions: swcConfig,
65
+ callbacks,
66
+ });
67
+ }
68
+ catch (error) {
69
+ logger.error(`Failed to start SWC compilation: ${error}`);
70
+ reject(error);
71
+ }
72
+ });
73
+ }
@@ -0,0 +1,2 @@
1
+ export { compile } from './compile';
2
+ export { watch } from './watch';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.watch = exports.compile = void 0;
4
+ var compile_1 = require("./compile");
5
+ Object.defineProperty(exports, "compile", { enumerable: true, get: function () { return compile_1.compile; } });
6
+ var watch_1 = require("./watch");
7
+ Object.defineProperty(exports, "watch", { enumerable: true, get: function () { return watch_1.watch; } });
@@ -0,0 +1,10 @@
1
+ import type { Logger } from '../logger';
2
+ interface SwcWatchOptions {
3
+ projectPath: string;
4
+ outputPath: string;
5
+ logger: Logger;
6
+ onAfterFilesEmitted?: () => void;
7
+ enableSourceMap?: boolean;
8
+ }
9
+ export declare function watch(swcDir: any, { projectPath, outputPath, logger, onAfterFilesEmitted, enableSourceMap, }: SwcWatchOptions): Promise<void>;
10
+ export {};
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.watch = watch;
4
+ const rimraf_1 = require("rimraf");
5
+ const getSwcConfig = () => {
6
+ return {
7
+ jsc: {
8
+ target: 'es2020',
9
+ parser: {
10
+ syntax: 'typescript',
11
+ decorators: false,
12
+ dynamicImport: false,
13
+ },
14
+ },
15
+ sourceMaps: true,
16
+ };
17
+ };
18
+ async function watch(
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ swcDir, { projectPath, outputPath, logger, onAfterFilesEmitted, enableSourceMap = false, }) {
21
+ logger.message('Start SWC compilation in watch mode');
22
+ // Очищаем выходную директорию
23
+ rimraf_1.rimraf.sync(outputPath);
24
+ const swcConfig = getSwcConfig();
25
+ const cliOptions = {
26
+ filenames: [projectPath],
27
+ outDir: outputPath,
28
+ watch: true,
29
+ quiet: false,
30
+ sourceMaps: enableSourceMap,
31
+ extensions: ['.js', '.ts', '.mjs', '.cjs'],
32
+ stripLeadingPaths: true,
33
+ deleteDirOnStart: false,
34
+ copyFiles: false,
35
+ includeDotfiles: false,
36
+ sync: false,
37
+ workers: 1,
38
+ logWatchCompilation: true,
39
+ };
40
+ const callbacks = {
41
+ onSuccess: (result) => {
42
+ if (result.filename) {
43
+ logger.verbose(`Successfully compiled ${result.filename} in ${result.duration}ms`);
44
+ }
45
+ else {
46
+ logger.message(`Successfully compiled ${result.compiled || 0} files in ${result.duration}ms`);
47
+ }
48
+ onAfterFilesEmitted?.();
49
+ },
50
+ onFail: (result) => {
51
+ logger.error(`SWC compilation failed in ${result.duration}ms`);
52
+ if (result.reasons) {
53
+ for (const [filename, error] of result.reasons) {
54
+ logger.error(`${filename}: ${error}`);
55
+ }
56
+ }
57
+ },
58
+ onWatchReady: () => {
59
+ logger.message('SWC watching for file changes');
60
+ },
61
+ };
62
+ // Запускаем swcDir
63
+ await swcDir({
64
+ cliOptions,
65
+ swcOptions: swcConfig,
66
+ callbacks,
67
+ });
68
+ }
@@ -1,8 +1,7 @@
1
1
  import type Typescript from 'typescript';
2
2
  import type { Logger } from '../logger';
3
- export declare function watch(ts: typeof Typescript, projectPath: string, { logger, onAfterFilesEmitted, enableSourceMap, tsconfigFileName, }: {
3
+ export declare function watch(ts: typeof Typescript, projectPath: string, { logger, onAfterFilesEmitted, enableSourceMap, }: {
4
4
  logger: Logger;
5
5
  onAfterFilesEmitted?: () => void;
6
6
  enableSourceMap?: boolean;
7
- tsconfigFileName: string;
8
7
  }): void;
@@ -4,10 +4,10 @@ exports.watch = watch;
4
4
  const transformers_1 = require("./transformers");
5
5
  const utils_1 = require("./utils");
6
6
  const diagnostic_1 = require("./diagnostic");
7
- function watch(ts, projectPath, { logger, onAfterFilesEmitted, enableSourceMap, tsconfigFileName, }) {
7
+ function watch(ts, projectPath, { logger, onAfterFilesEmitted, enableSourceMap, }) {
8
8
  logger.message('Start compilation in watch mode');
9
9
  logger.message(`Typescript v${ts.version}`);
10
- const configPath = (0, utils_1.getTsProjectConfigPath)(ts, projectPath, tsconfigFileName);
10
+ const configPath = (0, utils_1.getTsProjectConfigPath)(ts, projectPath);
11
11
  const createProgram = ts.createEmitAndSemanticDiagnosticsBuilderProgram;
12
12
  const host = ts.createWatchCompilerHost(configPath, {
13
13
  noEmit: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/app-builder",
3
- "version": "0.28.1-beta.2",
3
+ "version": "0.28.1-beta.5",
4
4
  "description": "Develop and build your React client-server projects, powered by typescript and webpack",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -75,13 +75,14 @@
75
75
  "@rspack/core": "1.3.9",
76
76
  "@rspack/dev-server": "^1.1.1",
77
77
  "@rspack/plugin-react-refresh": "^1.4.1",
78
- "@statoscope/webpack-plugin": "^5.29.0",
79
78
  "@statoscope/stats": "^5.28.1",
80
79
  "@statoscope/stats-extension-compressed": "^5.28.1",
81
80
  "@statoscope/webpack-model": "^5.29.0",
81
+ "@statoscope/webpack-plugin": "^5.29.0",
82
82
  "@svgr/core": "^8.1.0",
83
83
  "@svgr/plugin-jsx": "^8.1.0",
84
84
  "@svgr/webpack": "^8.1.0",
85
+ "@swc/cli": "^0.7.8",
85
86
  "@swc/core": "1.11.24",
86
87
  "@swc/plugin-transform-imports": "7.0.3",
87
88
  "babel-loader": "^9.2.1",