arui-scripts 19.1.0 → 20.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/.turbo/turbo-test.log +10 -8
  2. package/CHANGELOG.md +23 -0
  3. package/README.md +1 -1
  4. package/build/bin/index.js +0 -0
  5. package/build/commands/build/client.js +49 -28
  6. package/build/commands/util/brotli-dictionary/create-dcb-file.d.ts +6 -0
  7. package/build/commands/util/brotli-dictionary/create-dcb-file.js +38 -0
  8. package/build/commands/util/brotli-dictionary/find-files-to-compress.d.ts +9 -0
  9. package/build/commands/util/brotli-dictionary/find-files-to-compress.js +57 -0
  10. package/build/commands/util/brotli-dictionary/get-bundle-files.d.ts +1 -0
  11. package/build/commands/util/brotli-dictionary/get-bundle-files.js +26 -0
  12. package/build/commands/util/create-dictionary-files.d.ts +1 -0
  13. package/build/commands/util/create-dictionary-files.js +55 -0
  14. package/build/configs/app-configs/calculate-dependent-config.js +19 -1
  15. package/build/configs/app-configs/get-defaults.js +6 -0
  16. package/build/configs/app-configs/types.d.ts +6 -0
  17. package/build/configs/server-externals-exemptions.js +0 -1
  18. package/build/configs/util/find-plugin.d.ts +2 -2
  19. package/build/configs/util/get-polyfills.d.ts +1 -1
  20. package/build/configs/util/get-polyfills.js +1 -14
  21. package/build/configs/util/resolve.d.ts +3 -1
  22. package/build/configs/webpack.client.js +32 -40
  23. package/build/plugins/reload-server-plugin.d.ts +2 -2
  24. package/build/plugins/reload-server-plugin.js +3 -1
  25. package/build/templates/nginx.conf.template.js +1 -0
  26. package/build/tsconfig-local.tsbuildinfo +1 -1
  27. package/docs/compression-dictionary.md +130 -0
  28. package/docs/modules.md +1 -2
  29. package/docs/settings.md +15 -2
  30. package/package.json +179 -178
@@ -5,19 +5,21 @@ ts-jest[versions] (WARN) Version 29.7.0 of jest installed has not been tested wi
5
5
  ts-jest[versions] (WARN) Version 5.6.3 of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=4.3.0 <5.0.0-0). Please do not report issues in ts-jest if you are using unsupported versions.
6
6
  ts-jest[versions] (WARN) Version 5.6.3 of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=4.3.0 <5.0.0-0). Please do not report issues in ts-jest if you are using unsupported versions.
7
7
  ts-jest[versions] (WARN) Version 5.6.3 of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=4.3.0 <5.0.0-0). Please do not report issues in ts-jest if you are using unsupported versions.
8
- PASS src/plugins/postcss-global-variables/utils/__tests__/add-global-variable.tests.ts (27.73 s)
9
- PASS src/configs/app-configs/__tests__/update-with-presets.tests.ts (27.867 s)
10
- PASS src/configs/util/__tests__/get-polyfills.tests.ts
8
+ PASS src/commands/util/brotli-dictionary/__tests__/find-files-to-compress.test.ts (28.265 s)
9
+ PASS src/plugins/postcss-global-variables/utils/__tests__/add-global-variable.tests.ts
10
+ PASS src/commands/util/brotli-dictionary/__tests__/create-dcb-file.test.ts (28.501 s)
11
+ PASS src/configs/app-configs/__tests__/update-with-presets.tests.ts
12
+ PASS src/configs/app-configs/__tests__/update-with-env.tests.ts
11
13
  PASS src/configs/util/__tests__/apply-overrides.tests.ts
12
14
  PASS src/configs/app-configs/__tests__/update-with-package.tests.ts
13
- PASS src/configs/app-configs/__tests__/update-with-env.tests.ts
14
15
  PASS src/plugins/postcss-global-variables/utils/__tests__/parse-variables.tests.ts
16
+ PASS src/configs/util/__tests__/get-polyfills.tests.ts
15
17
  PASS src/plugins/postcss-global-variables/utils/__tests__/get-media-query-name.tests.ts
16
18
  PASS src/configs/app-configs/__tests__/validate-settings-keys.tests.ts
17
- PASS src/configs/util/__tests__/find-plugin.tests.ts (29.477 s)
19
+ PASS src/configs/util/__tests__/find-plugin.tests.ts (31.057 s)
18
20
 
19
- Test Suites: 10 passed, 10 total
20
- Tests: 26 passed, 26 total
21
+ Test Suites: 12 passed, 12 total
22
+ Tests: 32 passed, 32 total
21
23
  Snapshots: 0 total
22
- Time: 30.486 s
24
+ Time: 32.219 s
23
25
  Ran all test suites.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # [15.3.0](https://github.com/core-ds/arui-scripts/compare/v15.2.0...v15.3.0) (2023-06-30)
2
2
 
3
+ ## 20.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#328](https://github.com/core-ds/arui-scripts/pull/328) [`4e05165`](https://github.com/core-ds/arui-scripts/commit/4e0516568276f2af67a624a4d32d422c707ed125) Thanks [@heymdall-legal](https://github.com/heymdall-legal)! - Добавлена возможность сборки dcb архивов. Добавлен новый параметр `dictionaryCompression` для настройки сборки архивов.
8
+
9
+ ## 20.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - [#335](https://github.com/core-ds/arui-scripts/pull/335) [`2562b34`](https://github.com/core-ds/arui-scripts/commit/2562b34f0670d174a572215df610ddfd0d64be41) Thanks [@dmitrbrvsk](https://github.com/dmitrbrvsk)! - 1. Удалено подключение полифилов из arui-feather. 2. arui-feather удален из списка `serverExternalsExemptions`.
14
+
15
+ Если вы по какой-то причине хотите вернуть это поведение:
16
+
17
+ 1. Вы можете использовать настройку `clientPolyfillsEntry`, передав туда путь до файла с полифилами (`./node_modules/arui-feather/polyfills.js`)
18
+ 2. Вы можете использовать оверрайд для `serverExternalsExemptions` и добавить туда regex для feather: `/^arui-feather/`.
19
+
20
+ - [#346](https://github.com/core-ds/arui-scripts/pull/346) [`bf3072e`](https://github.com/core-ds/arui-scripts/commit/bf3072e164d19179c05523900036a9841497cdcb) Thanks [@heymdall-legal](https://github.com/heymdall-legal)! - Изменены настройки минификации js кода. Минифицированный код больше НЕ поддерживает старые версии браузеров (safari 10, ie, chrome < 49).
21
+
22
+ Для большинства проектов это изменение не принесёт никаких проблем, но позволит сократить объем минифицированного кода на 5%.
23
+
24
+ Если вам по каким либо причинам нужно изменить это поведение - вы можете воспользоваться механизмом оверрайдов.
25
+
3
26
  ## 19.1.0
4
27
 
5
28
  ### Minor Changes
package/README.md CHANGED
@@ -10,7 +10,7 @@ ARUI-scripts
10
10
 
11
11
  Зависимость | Версия
12
12
  -- | --
13
- `nodejs` | `16.20.2, 18.0.0+, 20.0.0+, 22.0.0+`
13
+ `nodejs` | `20.0.0+, 22.0.0+, 24.0.0+`
14
14
  `react` | `16.13.0+`
15
15
  `react-dom` | `16.13.0+`
16
16
 
File without changes
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
@@ -8,32 +17,44 @@ const printBuildError_1 = __importDefault(require("react-dev-utils/printBuildErr
8
17
  const build_wrapper_1 = __importDefault(require("./build-wrapper"));
9
18
  const client_assets_sizes_1 = require("../util/client-assets-sizes");
10
19
  const webpack_client_prod_1 = require("../../configs/webpack.client.prod");
20
+ const create_dictionary_files_1 = require("../util/create-dictionary-files");
11
21
  console.log(chalk_1.default.magenta('Building client...'));
12
- (0, build_wrapper_1.default)(webpack_client_prod_1.webpackClientConfig)
13
- .then(({ stats, warnings }) => {
14
- if (warnings.length) {
15
- console.log(chalk_1.default.yellow('Client compiled with warnings.\n'));
16
- console.log(warnings.join('\n\n'));
17
- console.log(`Search for the ${chalk_1.default.underline(chalk_1.default.yellow('keywords'))} to learn more about each warning.`);
18
- console.log(`To ignore, add ${chalk_1.default.cyan('// eslint-disable-next-line')} to the line before.`);
19
- }
20
- else {
21
- console.log(chalk_1.default.green('Client compiled successfully.\n'));
22
- }
23
- function printOutputSizes(webpackConfig, stats) {
24
- var _a;
25
- const sizes = (0, client_assets_sizes_1.calculateAssetsSizes)(stats, (_a = webpackConfig === null || webpackConfig === void 0 ? void 0 : webpackConfig.output) === null || _a === void 0 ? void 0 : _a.path);
26
- (0, client_assets_sizes_1.printAssetsSizes)(sizes);
27
- }
28
- if (Array.isArray(webpack_client_prod_1.webpackClientConfig)) {
29
- webpack_client_prod_1.webpackClientConfig.forEach((conf, index) => printOutputSizes(conf, stats.stats[index]));
30
- }
31
- else {
32
- printOutputSizes(webpack_client_prod_1.webpackClientConfig, stats);
33
- }
34
- })
35
- .catch((err) => {
36
- console.log(chalk_1.default.red('Failed to compile client.\n'));
37
- (0, printBuildError_1.default)(err);
38
- process.exit(1);
39
- });
22
+ function main() {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ try {
25
+ const { stats, warnings } = yield (0, build_wrapper_1.default)(webpack_client_prod_1.webpackClientConfig);
26
+ if (warnings.length) {
27
+ console.log(chalk_1.default.yellow('Client compiled with warnings.\n'));
28
+ console.log(warnings.join('\n\n'));
29
+ console.log(`Search for the ${chalk_1.default.underline(chalk_1.default.yellow('keywords'))} to learn more about each warning.`);
30
+ console.log(`To ignore, add ${chalk_1.default.cyan('// eslint-disable-next-line')} to the line before.`);
31
+ }
32
+ else {
33
+ console.log(chalk_1.default.green('Client compiled successfully.\n'));
34
+ }
35
+ function printOutputSizes(webpackConfig, stats) {
36
+ var _a;
37
+ const sizes = (0, client_assets_sizes_1.calculateAssetsSizes)(stats, (_a = webpackConfig === null || webpackConfig === void 0 ? void 0 : webpackConfig.output) === null || _a === void 0 ? void 0 : _a.path);
38
+ (0, client_assets_sizes_1.printAssetsSizes)(sizes);
39
+ }
40
+ if (Array.isArray(webpack_client_prod_1.webpackClientConfig)) {
41
+ webpack_client_prod_1.webpackClientConfig.forEach((conf, index) => printOutputSizes(conf, stats.stats[index]));
42
+ }
43
+ else {
44
+ printOutputSizes(webpack_client_prod_1.webpackClientConfig, stats);
45
+ }
46
+ try {
47
+ yield (0, create_dictionary_files_1.createDictionaryFiles)();
48
+ }
49
+ catch (error) {
50
+ console.warn('Unable to create dcb files', error);
51
+ }
52
+ }
53
+ catch (err) {
54
+ console.log(chalk_1.default.red('Failed to compile client.\n'));
55
+ (0, printBuildError_1.default)(err);
56
+ process.exit(1);
57
+ }
58
+ });
59
+ }
60
+ main();
@@ -0,0 +1,6 @@
1
+ export type BuildDcbParams = {
2
+ inputFilePath: string;
3
+ dictionaryFilePath: string;
4
+ outFilePath: string;
5
+ };
6
+ export declare function createDcbFile({ inputFilePath, dictionaryFilePath, outFilePath, }: BuildDcbParams): Promise<void>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.createDcbFile = createDcbFile;
16
+ const buffer_1 = require("buffer");
17
+ const crypto_1 = __importDefault(require("crypto"));
18
+ const fs_1 = __importDefault(require("fs"));
19
+ const brotli_dict_1 = require("brotli-dict");
20
+ function createDcbFile(_a) {
21
+ return __awaiter(this, arguments, void 0, function* ({ inputFilePath, dictionaryFilePath, outFilePath, }) {
22
+ // Формат файла: {Magic Number}{sha256(dictionary)}{compressed data}
23
+ // Подробнее в документации: https://www.ietf.org/archive/id/draft-ietf-httpbis-compression-dictionary-19.html#section-4
24
+ const dictionaryData = yield fs_1.default.promises.readFile(dictionaryFilePath);
25
+ const inputFile = yield fs_1.default.promises.readFile(inputFilePath);
26
+ const magicNumberHeader = buffer_1.Buffer.from([0xff, 0x44, 0x43, 0x42]);
27
+ const dictionaryHash = crypto_1.default.createHash('sha256').update(dictionaryData).digest();
28
+ const compressedData = yield (0, brotli_dict_1.compress)(inputFile, {
29
+ dictionary: dictionaryData,
30
+ });
31
+ const outputData = buffer_1.Buffer.concat([
32
+ magicNumberHeader,
33
+ dictionaryHash,
34
+ buffer_1.Buffer.from(compressedData),
35
+ ]);
36
+ yield fs_1.default.promises.writeFile(outFilePath, outputData);
37
+ });
38
+ }
@@ -0,0 +1,9 @@
1
+ import { BuildDcbParams } from './create-dcb-file';
2
+ type FilesToCompress = {
3
+ baseDir: string;
4
+ dictionaryDir: string;
5
+ outDir: string;
6
+ allowedExtensions: string[];
7
+ };
8
+ export declare function findFilesToCompress({ baseDir, dictionaryDir, outDir, allowedExtensions, }: FilesToCompress): Promise<BuildDcbParams[]>;
9
+ export {};
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.findFilesToCompress = findFilesToCompress;
16
+ const fs_1 = __importDefault(require("fs"));
17
+ const path_1 = __importDefault(require("path"));
18
+ function parseFilename(filename) {
19
+ const parsedName = path_1.default.parse(filename);
20
+ const [stableName, hash] = parsedName.name.split('.');
21
+ return {
22
+ stableName,
23
+ hash,
24
+ ext: parsedName.ext.substring(1),
25
+ filename,
26
+ };
27
+ }
28
+ function findFilesToCompress(_a) {
29
+ return __awaiter(this, arguments, void 0, function* ({ baseDir, dictionaryDir, outDir, allowedExtensions, }) {
30
+ const files = yield fs_1.default.promises.readdir(baseDir);
31
+ const dictionaries = yield fs_1.default.promises.readdir(dictionaryDir);
32
+ const parsedDictionaries = dictionaries.reduce((map, current) => {
33
+ const parsed = parseFilename(current);
34
+ return (Object.assign(Object.assign({}, map), { [`${parsed.stableName}.${parsed.ext}`]: parsed }));
35
+ }, {});
36
+ const result = [];
37
+ files.forEach((file) => {
38
+ const parsedFilename = parseFilename(file);
39
+ if (!allowedExtensions.includes(parsedFilename.ext)) {
40
+ return;
41
+ }
42
+ if (!parsedFilename.stableName || !parsedFilename.hash) {
43
+ return;
44
+ }
45
+ const matchedDictionary = parsedDictionaries[`${parsedFilename.stableName}.${parsedFilename.ext}`];
46
+ if (!matchedDictionary) {
47
+ return;
48
+ }
49
+ result.push({
50
+ inputFilePath: path_1.default.join(baseDir, parsedFilename.filename),
51
+ dictionaryFilePath: path_1.default.join(dictionaryDir, matchedDictionary.filename),
52
+ outFilePath: path_1.default.join(outDir, `${parsedFilename.filename}.${matchedDictionary.hash}.dcb`),
53
+ });
54
+ });
55
+ return result;
56
+ });
57
+ }
@@ -0,0 +1 @@
1
+ export declare function getBundleFiles(): Promise<string[]>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getBundleFiles = getBundleFiles;
16
+ const fs_1 = __importDefault(require("fs"));
17
+ const path_1 = __importDefault(require("path"));
18
+ const app_configs_1 = require("../../../configs/app-configs");
19
+ function getBundleFiles() {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ const files = yield fs_1.default.promises.readdir(app_configs_1.configs.clientOutputPath);
22
+ return files
23
+ .filter((filename) => filename.endsWith('.js') || filename.endsWith('.css'))
24
+ .map((filename) => path_1.default.join(app_configs_1.configs.clientOutputPath, filename));
25
+ });
26
+ }
@@ -0,0 +1 @@
1
+ export declare function createDictionaryFiles(): Promise<void>;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.createDictionaryFiles = createDictionaryFiles;
16
+ const path_1 = __importDefault(require("path"));
17
+ const app_configs_1 = require("../../configs/app-configs");
18
+ const create_dcb_file_1 = require("./brotli-dictionary/create-dcb-file");
19
+ const find_files_to_compress_1 = require("./brotli-dictionary/find-files-to-compress");
20
+ const get_bundle_files_1 = require("./brotli-dictionary/get-bundle-files");
21
+ function createDictionaryFiles() {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const previousVersionPath = app_configs_1.configs.compressionPreviousVersionPath;
24
+ const singleFilesDictionaries = app_configs_1.configs.compressionPredefinedDictionaryPath;
25
+ if (previousVersionPath.length > 0) {
26
+ const filesToCompressPromise = previousVersionPath.map((dictionaryDir) => (0, find_files_to_compress_1.findFilesToCompress)({
27
+ baseDir: app_configs_1.configs.clientOutputPath,
28
+ outDir: app_configs_1.configs.clientOutputPath,
29
+ allowedExtensions: ['js', 'css'],
30
+ dictionaryDir,
31
+ }));
32
+ const filesToCompress = (yield Promise.all(filesToCompressPromise)).flat();
33
+ const dcbPromises = filesToCompress.map((fileSettings) => (0, create_dcb_file_1.createDcbFile)(fileSettings));
34
+ yield Promise.all(dcbPromises);
35
+ console.log(`Created ${filesToCompress.length} dcb archives from previous versions`);
36
+ return;
37
+ }
38
+ if (singleFilesDictionaries.length > 0) {
39
+ const bundleFiles = yield (0, get_bundle_files_1.getBundleFiles)();
40
+ const singleFilePromises = singleFilesDictionaries.map((dictionaryPath) => __awaiter(this, void 0, void 0, function* () {
41
+ const dictionaryName = path_1.default.parse(dictionaryPath).name;
42
+ const dcbPromises = bundleFiles.map((bundleFile) => __awaiter(this, void 0, void 0, function* () {
43
+ return (0, create_dcb_file_1.createDcbFile)({
44
+ inputFilePath: bundleFile,
45
+ dictionaryFilePath: dictionaryPath,
46
+ outFilePath: `${bundleFile}.${dictionaryName}.dcb`,
47
+ });
48
+ }));
49
+ yield Promise.all(dcbPromises);
50
+ console.log(`Created ${dcbPromises.length} dcb archives for ${dictionaryName} dictionary`);
51
+ }));
52
+ yield Promise.all(singleFilePromises);
53
+ }
54
+ });
55
+ }
@@ -34,5 +34,23 @@ function calculateDependentContext(config, context) {
34
34
  // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
35
35
  babelRuntimeVersion = require('@babel/runtime/package.json').version;
36
36
  }
37
- return Object.assign(Object.assign({}, context), { publicPath: `${config.assetsPath}/`, serverOutputPath: path_1.default.resolve(context.cwd, config.buildPath), clientOutputPath: path_1.default.resolve(context.cwd, config.buildPath, config.assetsPath), statsOutputPath: path_1.default.resolve(context.cwd, config.buildPath, config.statsOutputFilename), watchIgnorePath: ['node_modules', config.buildPath], babelRuntimeVersion });
37
+ const allDictionaryPath = config.dictionaryCompression.dictionaryPath
38
+ .map((p) => {
39
+ if (!path_1.default.isAbsolute(p)) {
40
+ return path_1.default.join(process.cwd(), p);
41
+ }
42
+ return p;
43
+ });
44
+ const singleFilesDictionaries = [];
45
+ const previousVersionPath = [];
46
+ allDictionaryPath.forEach((p) => {
47
+ const statResult = fs_1.default.statSync(p);
48
+ if (statResult.isFile()) {
49
+ singleFilesDictionaries.push(p);
50
+ }
51
+ else {
52
+ previousVersionPath.push(p);
53
+ }
54
+ });
55
+ return Object.assign(Object.assign({}, context), { publicPath: `${config.assetsPath}/`, serverOutputPath: path_1.default.resolve(context.cwd, config.buildPath), clientOutputPath: path_1.default.resolve(context.cwd, config.buildPath, config.assetsPath), statsOutputPath: path_1.default.resolve(context.cwd, config.buildPath, config.statsOutputFilename), watchIgnorePath: ['node_modules', config.buildPath], babelRuntimeVersion, compressionPredefinedDictionaryPath: singleFilesDictionaries, compressionPreviousVersionPath: previousVersionPath });
38
56
  }
@@ -47,6 +47,10 @@ function getDefaultAppConfig() {
47
47
  removeDevDependenciesDuringDockerBuild: true,
48
48
  // archive compilation configs
49
49
  archiveName: 'build.tar',
50
+ dictionaryCompression: {
51
+ dictionaryPath: [],
52
+ enablePreviousVersionHeaders: false,
53
+ },
50
54
  // build tuning
51
55
  keepPropTypes: false,
52
56
  codeLoader: 'swc',
@@ -135,5 +139,7 @@ function getDefaultAppContext() {
135
139
  changelogFeaturesPath: path_1.default.resolve(CWD, './changelog_features.tmp'),
136
140
  changelogBugfixesPath: path_1.default.resolve(CWD, './changelog_bugfixes.tmp'),
137
141
  changelogBreakingChangesPath: path_1.default.resolve(CWD, './changelog_breaking_changes.tmp'),
142
+ compressionPredefinedDictionaryPath: [],
143
+ compressionPreviousVersionPath: [],
138
144
  };
139
145
  }
@@ -34,6 +34,10 @@ export type AppConfigs = {
34
34
  runFromNonRootUser: boolean;
35
35
  removeDevDependenciesDuringDockerBuild: boolean;
36
36
  archiveName: string;
37
+ dictionaryCompression: {
38
+ dictionaryPath: string[];
39
+ enablePreviousVersionHeaders?: boolean;
40
+ };
37
41
  keepPropTypes: boolean;
38
42
  codeLoader: 'babel' | 'tsc' | 'swc';
39
43
  installServerSourceMaps: boolean;
@@ -121,6 +125,8 @@ export type AppContext = {
121
125
  changelogFeaturesPath: string;
122
126
  changelogBugfixesPath: string;
123
127
  changelogBreakingChangesPath: string;
128
+ compressionPreviousVersionPath: string[];
129
+ compressionPredefinedDictionaryPath: string[];
124
130
  };
125
131
  export type AppContextWithConfigs = AppContext & AppConfigs;
126
132
  export type PackageSettings = Partial<AppConfigs>;
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.serverExternalsExemptions = void 0;
4
4
  const apply_overrides_1 = require("./util/apply-overrides");
5
5
  exports.serverExternalsExemptions = (0, apply_overrides_1.applyOverrides)('serverExternalsExemptions', [
6
- /^arui-feather/,
7
6
  /^arui-ft-private/,
8
7
  /^arui-private/,
9
8
  /^alfaform-core-ui/,
@@ -1,4 +1,4 @@
1
- import { Cluster } from 'cluster';
1
+ import { Worker } from 'cluster';
2
2
  import { ReactRefreshPluginOptions } from '@pmmmwh/react-refresh-webpack-plugin/types/lib/types';
3
3
  import { type CssExtractRspackPluginOptions, Configuration, DefinePlugin, NormalModuleReplacementPlugin } from '@rspack/core';
4
4
  import { BannerPluginOptions } from '@rspack/core/dist/builtin-plugin/BannerPlugin';
@@ -62,7 +62,7 @@ type PluginsListServer = {
62
62
  };
63
63
  ReloadServerPlugin: {
64
64
  done: (...props: unknown[]) => unknown | null;
65
- workers: Array<Cluster['Worker']>;
65
+ workers: Worker[];
66
66
  };
67
67
  CaseSensitivePathsPlugin: {
68
68
  options: CaseSensitivePathsPlugin.Options;
@@ -1,2 +1,2 @@
1
1
  import { AppConfigs } from '../app-configs/types';
2
- export declare function getPolyfills(config: AppConfigs, requireResolve?: RequireResolve): string[];
2
+ export declare function getPolyfills(config: AppConfigs): string[];
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPolyfills = getPolyfills;
4
- // require.resolve вынесен как параметр функции для того, чтоб это можно было протестировать.
5
- // на данный момент jest не дает возможности мокать require.resolve https://github.com/facebook/jest/issues/9543
6
- function getPolyfills(config, requireResolve = require.resolve) {
4
+ function getPolyfills(config) {
7
5
  const polyfills = [];
8
6
  if (config.clientPolyfillsEntry && Array.isArray(config.clientPolyfillsEntry)) {
9
7
  polyfills.push(...config.clientPolyfillsEntry);
@@ -11,16 +9,5 @@ function getPolyfills(config, requireResolve = require.resolve) {
11
9
  else if (config.clientPolyfillsEntry) {
12
10
  polyfills.push(config.clientPolyfillsEntry);
13
11
  }
14
- else {
15
- // Для сохранения обратной совместимости нам надо добавлять полифилы из физера только тогда, когда пользователь
16
- // не задал свои кастомные полифилы.
17
- try {
18
- const aruiPolyfills = requireResolve('arui-feather/polyfills');
19
- polyfills.push(aruiPolyfills);
20
- }
21
- catch (error) {
22
- // just ignore it
23
- }
24
- }
25
12
  return polyfills;
26
13
  }
@@ -1,4 +1,6 @@
1
- export declare function tryResolve(...args: Parameters<typeof require.resolve>): string | undefined;
1
+ export declare function tryResolve(...args: [id: string, options?: {
2
+ paths?: string[] | undefined;
3
+ }]): string | undefined;
2
4
  /**
3
5
  * Возвращает полный путь до модуля из node_modules относительно базового пути.
4
6
  * Может быть полезно для определения пути до модуля, когда в проекте установлено сразу несколько модулей.
@@ -1,10 +1,34 @@
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.createClientWebpackConfig = exports.createSingleClientWebpackConfig = void 0;
7
30
  const path_1 = __importDefault(require("path"));
31
+ const zlib = __importStar(require("zlib"));
8
32
  const getCSSModuleLocalIdent_1 = __importDefault(require("react-dev-utils/getCSSModuleLocalIdent"));
9
33
  const react_refresh_typescript_1 = __importDefault(require("react-refresh-typescript"));
10
34
  const core_1 = require("@rspack/core");
@@ -58,44 +82,7 @@ function getMinimizeConfig(mode) {
58
82
  return {
59
83
  minimize: true,
60
84
  minimizer: [
61
- new terser_webpack_plugin_1.default({
62
- terserOptions: {
63
- parse: {
64
- // we want terser to parse ecma 8 code. However, we don't want it
65
- // to apply any minfication steps that turns valid ecma 5 code
66
- // into invalid ecma 5 code. This is why the 'compress' and 'output'
67
- // sections only apply transformations that are ecma 5 safe
68
- // https://github.com/facebook/create-react-app/pull/4234
69
- ecma: 2017,
70
- },
71
- compress: {
72
- ecma: 5,
73
- // Disabled because of an issue with Uglify breaking seemingly valid code:
74
- // https://github.com/facebook/create-react-app/issues/2376
75
- // Pending further investigation:
76
- // https://github.com/mishoo/UglifyJS2/issues/2011
77
- comparisons: false,
78
- // Disabled because of an issue with Terser breaking valid code:
79
- // https://github.com/facebook/create-react-app/issues/5250
80
- // Pending futher investigation:
81
- // https://github.com/terser-js/terser/issues/120
82
- inline: 2,
83
- },
84
- mangle: {
85
- safari10: true,
86
- },
87
- output: {
88
- ecma: 5,
89
- comments: false,
90
- // Turned on because emoji and regex is not minified properly using default
91
- // https://github.com/facebook/create-react-app/issues/2488
92
- ascii_only: true,
93
- },
94
- },
95
- // Use multi-process parallel running to improve the build speed
96
- // Default number of concurrent runs: os.cpus().length - 1
97
- parallel: true,
98
- }),
85
+ new terser_webpack_plugin_1.default(),
99
86
  new css_minimizer_webpack_plugin_1.default(),
100
87
  ].filter(Boolean),
101
88
  };
@@ -337,6 +324,9 @@ const createSingleClientWebpackConfig = (mode, entry, configName) => (Object.ass
337
324
  filename: '../index.html',
338
325
  }),
339
326
  mode === 'dev' && app_configs_1.configs.clientOnly && new client_env_config_1.ClientConfigPlugin(),
327
+ app_configs_1.configs.compressionPredefinedDictionaryPath && new core_1.CopyRspackPlugin({
328
+ patterns: app_configs_1.configs.compressionPredefinedDictionaryPath
329
+ }),
340
330
  // production plugins:
341
331
  mode === 'prod' && new rspack_manifest_plugin_1.RspackManifestPlugin({}),
342
332
  mode === 'prod' &&
@@ -352,9 +342,11 @@ const createSingleClientWebpackConfig = (mode, entry, configName) => (Object.ass
352
342
  new compression_webpack_plugin_1.default({
353
343
  filename: '[file].br',
354
344
  algorithm: 'brotliCompress',
355
- test: /\.(js|css|html|svg)$/,
345
+ test: /\.(js|css|html|svg|dict)$/,
356
346
  compressionOptions: {
357
- level: 11,
347
+ params: {
348
+ [zlib.constants.BROTLI_PARAM_QUALITY]: 11
349
+ },
358
350
  },
359
351
  threshold: 10240,
360
352
  minRatio: 0.8,
@@ -1,7 +1,7 @@
1
- import cluster from 'cluster';
1
+ import { Worker } from 'cluster';
2
2
  import { type Compiler } from 'webpack';
3
3
  export declare class ReloadServerPlugin {
4
- workers: cluster.Worker[];
4
+ workers: Worker[];
5
5
  done: null | (() => void);
6
6
  constructor({ script }?: {
7
7
  script: string;
@@ -30,7 +30,9 @@ class ReloadServerPlugin {
30
30
  this.done = callback;
31
31
  this.workers.forEach((worker) => {
32
32
  try {
33
- process.kill(worker.process.pid, 'SIGTERM');
33
+ if (worker.process.pid) {
34
+ process.kill(worker.process.pid, 'SIGTERM');
35
+ }
34
36
  }
35
37
  catch (e) {
36
38
  console.warn(`Unable to kill process #${worker.process.pid}`);