arui-scripts 20.1.0 → 20.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-test.log +9 -10
- package/CHANGELOG.md +29 -0
- package/build/commands/build/client.js +2 -10
- package/build/commands/util/client-assets-sizes.d.ts +1 -25
- package/build/commands/util/client-assets-sizes.js +51 -63
- package/build/configs/dev-server.d.ts +2 -1
- package/build/configs/util/apply-overrides.d.ts +2 -2
- package/build/configs/util/compress-with-dcb.d.ts +2 -0
- package/build/{commands/util/brotli-dictionary/create-dcb-file.js → configs/util/compress-with-dcb.js} +4 -10
- package/build/configs/util/compression-plugins-for-dictionaries.d.ts +2 -0
- package/build/configs/util/compression-plugins-for-dictionaries.js +81 -0
- package/build/configs/util/dcb-compression-plugin.d.ts +22 -0
- package/build/configs/util/dcb-compression-plugin.js +122 -0
- package/build/configs/webpack.client.js +5 -6
- package/build/configs/webpack.server.js +0 -5
- package/build/tsconfig-local.tsbuildinfo +1 -1
- package/package.json +12 -14
- package/build/commands/util/brotli-dictionary/create-dcb-file.d.ts +0 -6
- package/build/commands/util/brotli-dictionary/find-files-to-compress.d.ts +0 -9
- package/build/commands/util/brotli-dictionary/find-files-to-compress.js +0 -57
- package/build/commands/util/brotli-dictionary/get-bundle-files.d.ts +0 -1
- package/build/commands/util/brotli-dictionary/get-bundle-files.js +0 -26
- package/build/commands/util/create-dictionary-files.d.ts +0 -1
- package/build/commands/util/create-dictionary-files.js +0 -55
package/.turbo/turbo-test.log
CHANGED
|
@@ -5,21 +5,20 @@ 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/
|
|
9
|
-
PASS src/
|
|
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
|
|
8
|
+
PASS src/plugins/postcss-global-variables/utils/__tests__/add-global-variable.tests.ts (28.236 s)
|
|
9
|
+
PASS src/configs/app-configs/__tests__/update-with-presets.tests.ts (28.301 s)
|
|
13
10
|
PASS src/configs/util/__tests__/apply-overrides.tests.ts
|
|
14
11
|
PASS src/configs/app-configs/__tests__/update-with-package.tests.ts
|
|
15
|
-
PASS src/
|
|
12
|
+
PASS src/configs/app-configs/__tests__/update-with-env.tests.ts
|
|
13
|
+
PASS src/configs/util/__tests__/compress-with-dcb.test.ts
|
|
16
14
|
PASS src/configs/util/__tests__/get-polyfills.tests.ts
|
|
17
15
|
PASS src/plugins/postcss-global-variables/utils/__tests__/get-media-query-name.tests.ts
|
|
16
|
+
PASS src/plugins/postcss-global-variables/utils/__tests__/parse-variables.tests.ts
|
|
18
17
|
PASS src/configs/app-configs/__tests__/validate-settings-keys.tests.ts
|
|
19
|
-
PASS src/configs/util/__tests__/find-plugin.tests.ts (
|
|
18
|
+
PASS src/configs/util/__tests__/find-plugin.tests.ts (30.634 s)
|
|
20
19
|
|
|
21
|
-
Test Suites:
|
|
22
|
-
Tests:
|
|
20
|
+
Test Suites: 11 passed, 11 total
|
|
21
|
+
Tests: 25 passed, 25 total
|
|
23
22
|
Snapshots: 0 total
|
|
24
|
-
Time:
|
|
23
|
+
Time: 31.438 s
|
|
25
24
|
Ran all test suites.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
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.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#353](https://github.com/core-ds/arui-scripts/pull/353) [`fa5b84e`](https://github.com/core-ds/arui-scripts/commit/fa5b84ebef26fbe5e0ed4828ff0348461e57f984) Thanks [@heymdall-legal](https://github.com/heymdall-legal)! - Обновление плагина swc-plugin-coverage-instrument для корректной работы с новой версией SWC
|
|
8
|
+
|
|
9
|
+
## 20.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#352](https://github.com/core-ds/arui-scripts/pull/352) [`bcc3155`](https://github.com/core-ds/arui-scripts/commit/bcc3155b3450bf682f7d8d653d282b749853d7af) Thanks [@heymdall-legal](https://github.com/heymdall-legal)! - Обновление rspack до версии 1.4.11. Приносит дополнительное ускорение, исправление багов.
|
|
14
|
+
Основные фичи описаны в релиз-ноутах к версии [1.2](https://rspack.rs/blog/announcing-1-2), [1.3](https://rspack.rs/blog/announcing-1-3) и [1.4](https://rspack.rs/blog/announcing-1-4).
|
|
15
|
+
|
|
16
|
+
Кратко:
|
|
17
|
+
|
|
18
|
+
- меньше бинарник самого rspack
|
|
19
|
+
- более быстрый code-splitting
|
|
20
|
+
- из дефолтных watch-таргетов убраны node_modules, что ускоряет как старт, так и работу в дев режиме
|
|
21
|
+
- меньшее использование памяти
|
|
22
|
+
- более быстрый парсер кода
|
|
23
|
+
- улучшенный алгоритм tree-shaking - более компактные бандлы
|
|
24
|
+
- инкрементальная сборка в дев режиме - на 30% более быстрый HMR
|
|
25
|
+
|
|
26
|
+
С полным списком изменений можно ознакомится на [странице релизов rspack](https://github.com/web-infra-dev/rspack/releases?page=1).
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- [`43a7c5c`](https://github.com/core-ds/arui-scripts/commit/43a7c5c3dff8b933a75c1eaddfc738cdbdfb9e1b) Thanks [@Heymdall](https://github.com/Heymdall)! - Сжатие с DCB теперь просто использует compression plugin. Улучшен вывод статистики по собранным файлам
|
|
31
|
+
|
|
3
32
|
## 20.1.0
|
|
4
33
|
|
|
5
34
|
### Minor Changes
|
|
@@ -17,7 +17,6 @@ const printBuildError_1 = __importDefault(require("react-dev-utils/printBuildErr
|
|
|
17
17
|
const build_wrapper_1 = __importDefault(require("./build-wrapper"));
|
|
18
18
|
const client_assets_sizes_1 = require("../util/client-assets-sizes");
|
|
19
19
|
const webpack_client_prod_1 = require("../../configs/webpack.client.prod");
|
|
20
|
-
const create_dictionary_files_1 = require("../util/create-dictionary-files");
|
|
21
20
|
console.log(chalk_1.default.magenta('Building client...'));
|
|
22
21
|
function main() {
|
|
23
22
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -33,9 +32,8 @@ function main() {
|
|
|
33
32
|
console.log(chalk_1.default.green('Client compiled successfully.\n'));
|
|
34
33
|
}
|
|
35
34
|
function printOutputSizes(webpackConfig, stats) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
(0, client_assets_sizes_1.printAssetsSizes)(sizes);
|
|
35
|
+
console.log(chalk_1.default.bold(`Sizes for "${webpackConfig.name || 'main'}"`));
|
|
36
|
+
(0, client_assets_sizes_1.printAssetsSizes)(stats);
|
|
39
37
|
}
|
|
40
38
|
if (Array.isArray(webpack_client_prod_1.webpackClientConfig)) {
|
|
41
39
|
webpack_client_prod_1.webpackClientConfig.forEach((conf, index) => printOutputSizes(conf, stats.stats[index]));
|
|
@@ -43,12 +41,6 @@ function main() {
|
|
|
43
41
|
else {
|
|
44
42
|
printOutputSizes(webpack_client_prod_1.webpackClientConfig, stats);
|
|
45
43
|
}
|
|
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
44
|
}
|
|
53
45
|
catch (err) {
|
|
54
46
|
console.log(chalk_1.default.red('Failed to compile client.\n'));
|
|
@@ -1,26 +1,2 @@
|
|
|
1
1
|
import { Stats } from '@rspack/core';
|
|
2
|
-
|
|
3
|
-
name: string;
|
|
4
|
-
fullName: string;
|
|
5
|
-
gzipSize: number;
|
|
6
|
-
brotliSize: number;
|
|
7
|
-
size: number;
|
|
8
|
-
sizeLabel: string;
|
|
9
|
-
gzipLabel: string;
|
|
10
|
-
brotliLabel: string;
|
|
11
|
-
};
|
|
12
|
-
type TotalSizes = {
|
|
13
|
-
size: number;
|
|
14
|
-
sizeLabel: string;
|
|
15
|
-
gzipSize: number;
|
|
16
|
-
gzipLabel: string;
|
|
17
|
-
brotliSize: number;
|
|
18
|
-
brotliLabel: string;
|
|
19
|
-
};
|
|
20
|
-
type ClientAssetsSizes = {
|
|
21
|
-
totalSizes: TotalSizes;
|
|
22
|
-
assets: AssetSize[];
|
|
23
|
-
};
|
|
24
|
-
export declare function calculateAssetsSizes(webpackStats: Stats, rootDir?: string): ClientAssetsSizes;
|
|
25
|
-
export declare function printAssetsSizes(sizes: ClientAssetsSizes): void;
|
|
26
|
-
export {};
|
|
2
|
+
export declare function printAssetsSizes(webpackStats: Stats): void;
|
|
@@ -3,79 +3,67 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.calculateAssetsSizes = calculateAssetsSizes;
|
|
7
6
|
exports.printAssetsSizes = printAssetsSizes;
|
|
8
|
-
const fs_1 = __importDefault(require("fs"));
|
|
9
7
|
const path_1 = __importDefault(require("path"));
|
|
10
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
9
|
const filesize_1 = __importDefault(require("filesize"));
|
|
12
|
-
const
|
|
13
|
-
const strip_ansi_1 = __importDefault(require("strip-ansi"));
|
|
14
|
-
let brotliSize = () => NaN;
|
|
15
|
-
try {
|
|
16
|
-
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
17
|
-
brotliSize = require('brotli-size').sync;
|
|
18
|
-
}
|
|
19
|
-
catch (error) {
|
|
20
|
-
// empty error
|
|
21
|
-
}
|
|
22
|
-
function canReadAsset(asset) {
|
|
23
|
-
return (/\.(js|css)$/.test(asset) &&
|
|
24
|
-
!/service-worker\.js/.test(asset) &&
|
|
25
|
-
!/precache-manifest\.[0-9a-f]+\.js/.test(asset));
|
|
26
|
-
}
|
|
10
|
+
const app_configs_1 = require("../../configs/app-configs");
|
|
27
11
|
function removeFileNameHash(fileName) {
|
|
28
|
-
|
|
12
|
+
const parts = fileName
|
|
29
13
|
.replace(/\\/g, '/')
|
|
30
|
-
.
|
|
14
|
+
.split('.');
|
|
15
|
+
const id = parts[0];
|
|
16
|
+
const isChunk = fileName.includes('.chunk.');
|
|
17
|
+
const extension = parts.find(p => ['js', 'css'].includes(p));
|
|
18
|
+
return `${id}${isChunk ? '.chunk' : ''}.${extension}`;
|
|
31
19
|
}
|
|
32
|
-
function
|
|
20
|
+
function printAssetsSizes(webpackStats) {
|
|
33
21
|
const assetsStats = webpackStats.toJson({ all: false, assets: true }).assets || [];
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
22
|
+
const assetsMap = {};
|
|
23
|
+
const statExtensions = ['js', 'css', 'br', 'gz', 'dcb'];
|
|
24
|
+
assetsStats.forEach((asset) => {
|
|
25
|
+
if (asset.type !== 'asset') {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const extension = path_1.default.parse(asset.name).ext.substring(1);
|
|
29
|
+
if (!statExtensions.includes(extension) || asset.name.endsWith('.dict.br')) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const assetName = removeFileNameHash(asset.name);
|
|
33
|
+
if (!assetsMap[assetName]) {
|
|
34
|
+
assetsMap[assetName] = {};
|
|
35
|
+
}
|
|
36
|
+
if (extension === 'js' || extension === 'css') {
|
|
37
|
+
assetsMap[assetName].size = asset.size;
|
|
38
|
+
}
|
|
39
|
+
if (extension === 'br') {
|
|
40
|
+
assetsMap[assetName].brSize = asset.size;
|
|
41
|
+
}
|
|
42
|
+
if (extension === 'gz') {
|
|
43
|
+
assetsMap[assetName].gzipSize = asset.size;
|
|
44
|
+
}
|
|
45
|
+
if (extension === 'dcb') {
|
|
46
|
+
assetsMap[assetName].dcbSize = asset.size;
|
|
47
|
+
}
|
|
51
48
|
});
|
|
52
|
-
const totalSizes =
|
|
53
|
-
size:
|
|
54
|
-
gzipSize:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
totalSizes.sizeLabel = (0, filesize_1.default)(totalSizes.size || 0);
|
|
58
|
-
totalSizes.gzipLabel = (0, filesize_1.default)(totalSizes.gzipSize || 0);
|
|
59
|
-
totalSizes.brotliLabel = totalSizes.brotliSize ? (0, filesize_1.default)(totalSizes.brotliSize) : '-';
|
|
60
|
-
return {
|
|
61
|
-
totalSizes: totalSizes,
|
|
62
|
-
assets,
|
|
49
|
+
const totalSizes = {
|
|
50
|
+
size: 0,
|
|
51
|
+
gzipSize: 0,
|
|
52
|
+
brSize: 0,
|
|
53
|
+
dcbSize: 0,
|
|
63
54
|
};
|
|
64
|
-
}
|
|
65
|
-
function printAssetsSizes(sizes) {
|
|
66
|
-
const longestSizeLabelLength = Math.max.apply(null, sizes.assets.map((a) => {
|
|
67
|
-
const sizeLength = (0, strip_ansi_1.default)(a.gzipLabel).length;
|
|
68
|
-
return sizeLength + sizeLength + 8;
|
|
69
|
-
}));
|
|
70
55
|
console.log(chalk_1.default.blueBright('Assets sizes:'));
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
56
|
+
Object.keys(assetsMap).forEach((assetName) => {
|
|
57
|
+
const asset = assetsMap[assetName];
|
|
58
|
+
const size = asset.size || 0;
|
|
59
|
+
const gzipSize = asset.brSize || size;
|
|
60
|
+
const brSize = asset.brSize || gzipSize;
|
|
61
|
+
const dcbSize = asset.dcbSize || brSize;
|
|
62
|
+
totalSizes.size += size;
|
|
63
|
+
totalSizes.gzipSize += gzipSize;
|
|
64
|
+
totalSizes.brSize += brSize;
|
|
65
|
+
totalSizes.dcbSize += dcbSize;
|
|
66
|
+
console.log(` ${(0, filesize_1.default)(size)} (${(0, filesize_1.default)(gzipSize)} gzip, ${(0, filesize_1.default)(brSize)} br${app_configs_1.configs.dictionaryCompression.dictionaryPath.length > 0 ? `, ${(0, filesize_1.default)(dcbSize)} dcb` : ''}) ${chalk_1.default.cyan(assetName)}`);
|
|
79
67
|
});
|
|
80
|
-
console.log(`${chalk_1.default.blueBright('\nTotal size:\n')} ${
|
|
68
|
+
console.log(`${chalk_1.default.blueBright('\nTotal size:\n')} ${(0, filesize_1.default)(totalSizes.size)} (${(0, filesize_1.default)(totalSizes.gzipSize)} gzip, ${(0, filesize_1.default)(totalSizes.brSize)} br${app_configs_1.configs.dictionaryCompression.dictionaryPath.length > 0 ? `, ${(0, filesize_1.default)(totalSizes.dcbSize)} dcb` : ''})\n`);
|
|
81
69
|
}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { Configuration } from '@rspack/dev-server';
|
|
2
|
+
export declare const devServerConfig: Configuration;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as rspack from '@rspack/core';
|
|
2
|
+
import type { Configuration as RspackDevServerConfiguration } from '@rspack/dev-server';
|
|
2
3
|
import type { Options as SwcOptions } from '@swc/core';
|
|
3
|
-
import type { Configuration as WebpackDevServerConfiguration } from 'webpack-dev-server';
|
|
4
4
|
import { AppContextWithConfigs } from '../app-configs/types';
|
|
5
5
|
import { createSingleClientWebpackConfig } from '../webpack.client';
|
|
6
6
|
import { findLoader } from './find-loader';
|
|
@@ -15,7 +15,7 @@ type Overrides = {
|
|
|
15
15
|
webpackProd: rspack.Configuration;
|
|
16
16
|
webpackClientProd: rspack.Configuration | rspack.Configuration[];
|
|
17
17
|
webpackServerProd: rspack.Configuration;
|
|
18
|
-
devServer:
|
|
18
|
+
devServer: RspackDevServerConfiguration;
|
|
19
19
|
stats: rspack.RspackOptionsNormalized['stats'];
|
|
20
20
|
babel: any;
|
|
21
21
|
babelClient: any;
|
|
@@ -12,27 +12,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.
|
|
15
|
+
exports.compressWithDcb = compressWithDcb;
|
|
16
16
|
const buffer_1 = require("buffer");
|
|
17
17
|
const crypto_1 = __importDefault(require("crypto"));
|
|
18
|
-
const fs_1 = __importDefault(require("fs"));
|
|
19
18
|
const brotli_dict_1 = require("brotli-dict");
|
|
20
|
-
function
|
|
21
|
-
return __awaiter(this,
|
|
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);
|
|
19
|
+
function compressWithDcb(inputFile, dictionaryData) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
21
|
const magicNumberHeader = buffer_1.Buffer.from([0xff, 0x44, 0x43, 0x42]);
|
|
27
22
|
const dictionaryHash = crypto_1.default.createHash('sha256').update(dictionaryData).digest();
|
|
28
23
|
const compressedData = yield (0, brotli_dict_1.compress)(inputFile, {
|
|
29
24
|
dictionary: dictionaryData,
|
|
30
25
|
});
|
|
31
|
-
|
|
26
|
+
return buffer_1.Buffer.concat([
|
|
32
27
|
magicNumberHeader,
|
|
33
28
|
dictionaryHash,
|
|
34
29
|
buffer_1.Buffer.from(compressedData),
|
|
35
30
|
]);
|
|
36
|
-
yield fs_1.default.promises.writeFile(outFilePath, outputData);
|
|
37
31
|
});
|
|
38
32
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
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.compressionPluginsForDictionaries = compressionPluginsForDictionaries;
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const app_configs_1 = require("../app-configs");
|
|
19
|
+
const compress_with_dcb_1 = require("./compress-with-dcb");
|
|
20
|
+
const dcb_compression_plugin_1 = require("./dcb-compression-plugin");
|
|
21
|
+
function compressionPluginsForDictionaries() {
|
|
22
|
+
const predefinedPlugins = app_configs_1.configs.compressionPredefinedDictionaryPath.map((dictionaryPath) => {
|
|
23
|
+
const dictionaryName = path_1.default.parse(dictionaryPath).name;
|
|
24
|
+
const dictionaryContent = fs_1.default.readFileSync(dictionaryPath, null);
|
|
25
|
+
return new dcb_compression_plugin_1.CustomCompressionPlugin({
|
|
26
|
+
test: /\.js$|\.css$/,
|
|
27
|
+
filename: ({ filename }) => `${filename}.${dictionaryName}.dcb`,
|
|
28
|
+
algorithm: (input) => (0, compress_with_dcb_1.compressWithDcb)(input, dictionaryContent),
|
|
29
|
+
threshold: 10240,
|
|
30
|
+
minRatio: 0.8,
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
const prevVersionPlugins = app_configs_1.configs.compressionPreviousVersionPath.map((dictionaryPath) => {
|
|
34
|
+
const dictionaries = fs_1.default.readdirSync(dictionaryPath);
|
|
35
|
+
const parsedDictionaries = dictionaries.reduce((map, current) => {
|
|
36
|
+
const parsed = parseFilename(current);
|
|
37
|
+
return (Object.assign(Object.assign({}, map), { [`${parsed.stableName}.${parsed.ext}`]: parsed }));
|
|
38
|
+
}, {});
|
|
39
|
+
return new dcb_compression_plugin_1.CustomCompressionPlugin({
|
|
40
|
+
test: /\.js$|\.css$/,
|
|
41
|
+
threshold: 10240,
|
|
42
|
+
minRatio: 0.8,
|
|
43
|
+
filename: (pathData) => {
|
|
44
|
+
const parsedFilename = parseFilename(pathData.filename || '');
|
|
45
|
+
const matchedDictionary = parsedDictionaries[`${parsedFilename.stableName}.${parsedFilename.ext}`];
|
|
46
|
+
if (!matchedDictionary) {
|
|
47
|
+
return '';
|
|
48
|
+
}
|
|
49
|
+
return `${parsedFilename.filename}.${matchedDictionary.hash}.dcb`;
|
|
50
|
+
},
|
|
51
|
+
algorithm: (input_1, _a) => __awaiter(this, [input_1, _a], void 0, function* (input, { filename }) {
|
|
52
|
+
const parsedFilename = parseFilename(filename);
|
|
53
|
+
const matchedDictionary = parsedDictionaries[`${parsedFilename.stableName}.${parsedFilename.ext}`];
|
|
54
|
+
if (!matchedDictionary) {
|
|
55
|
+
return input;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const dictionaryContent = fs_1.default.readFileSync(path_1.default.join(dictionaryPath, matchedDictionary.filename), null);
|
|
59
|
+
return yield (0, compress_with_dcb_1.compressWithDcb)(input, dictionaryContent);
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
return input;
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
return [
|
|
68
|
+
...predefinedPlugins,
|
|
69
|
+
...prevVersionPlugins,
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
function parseFilename(filename) {
|
|
73
|
+
const parsedName = path_1.default.parse(filename);
|
|
74
|
+
const [stableName, hash] = parsedName.name.split('.');
|
|
75
|
+
return {
|
|
76
|
+
stableName,
|
|
77
|
+
hash,
|
|
78
|
+
ext: parsedName.ext.substring(1),
|
|
79
|
+
filename,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Assets, Compilation, Compiler } from '@rspack/core';
|
|
2
|
+
import { PathData } from '@rspack/core/dist/Compilation';
|
|
3
|
+
import { Rules } from 'compression-webpack-plugin';
|
|
4
|
+
type DcbCompressionOptions = {
|
|
5
|
+
test?: Rules;
|
|
6
|
+
include?: Rules;
|
|
7
|
+
exclude?: Rules;
|
|
8
|
+
algorithm: (input: Buffer, options: {
|
|
9
|
+
filename: string;
|
|
10
|
+
}) => Promise<Buffer>;
|
|
11
|
+
filename: (pathdata: PathData) => string;
|
|
12
|
+
threshold: number;
|
|
13
|
+
minRatio: number;
|
|
14
|
+
};
|
|
15
|
+
export declare class CustomCompressionPlugin {
|
|
16
|
+
protected options: DcbCompressionOptions;
|
|
17
|
+
constructor(options: DcbCompressionOptions);
|
|
18
|
+
runCompressionAlgorithm(input: Buffer, filename: string): Promise<Buffer>;
|
|
19
|
+
compress(compiler: Compiler, compilation: Compilation, assets: Assets): Promise<void>;
|
|
20
|
+
apply(compiler: Compiler): void;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
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.CustomCompressionPlugin = void 0;
|
|
16
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
17
|
+
const serialize_javascript_1 = __importDefault(require("serialize-javascript"));
|
|
18
|
+
/*
|
|
19
|
+
Based on compression-webpack-plugin, https://github.com/webpack-contrib/compression-webpack-plugin/tree/master
|
|
20
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
21
|
+
Author Tobias Koppers @sokra
|
|
22
|
+
*/
|
|
23
|
+
class CustomCompressionPlugin {
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.options = options;
|
|
26
|
+
}
|
|
27
|
+
runCompressionAlgorithm(input, filename) {
|
|
28
|
+
return this.options.algorithm(input, { filename });
|
|
29
|
+
}
|
|
30
|
+
compress(compiler, compilation, assets) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
const cache = compilation.getCache('BrCompressionWebpackPlugin');
|
|
33
|
+
const assetsForCompression = (yield Promise.all(Object.keys(assets).map((name) => __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
const asset = compilation.getAsset(name);
|
|
35
|
+
if (!asset || asset.info.compressed) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (!compiler.webpack.ModuleFilenameHelpers.matchObject.bind(undefined, this.options)(name)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
const relatedName = `compression-function-${crypto_1.default
|
|
42
|
+
.createHash('md5')
|
|
43
|
+
.update((0, serialize_javascript_1.default)(this.options.filename))
|
|
44
|
+
.digest('hex')}`;
|
|
45
|
+
if (asset.info.related && asset.info.related[relatedName]) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const cacheItem = cache.getItemCache((0, serialize_javascript_1.default)({
|
|
49
|
+
name,
|
|
50
|
+
algorithm: this.options.algorithm,
|
|
51
|
+
}), cache.getLazyHashedEtag(asset.source));
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
|
+
const output = ((yield cacheItem.getPromise()) || {});
|
|
54
|
+
let buffer;
|
|
55
|
+
// No need original buffer for cached files
|
|
56
|
+
if (!output.source) {
|
|
57
|
+
if (typeof asset.source.buffer === 'function') {
|
|
58
|
+
buffer = asset.source.buffer();
|
|
59
|
+
}
|
|
60
|
+
// Compatibility with webpack plugins which don't use `webpack-sources`
|
|
61
|
+
// See https://github.com/webpack-contrib/compression-webpack-plugin/issues/236
|
|
62
|
+
else {
|
|
63
|
+
buffer = asset.source.source();
|
|
64
|
+
if (!Buffer.isBuffer(buffer)) {
|
|
65
|
+
buffer = Buffer.from(buffer);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (buffer.length < this.options.threshold) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { name, source: asset.source, info: asset.info, buffer, output, cacheItem, relatedName };
|
|
73
|
+
})))).filter(Boolean);
|
|
74
|
+
const { RawSource } = compiler.webpack.sources;
|
|
75
|
+
const scheduledTasks = [];
|
|
76
|
+
for (const asset of assetsForCompression) {
|
|
77
|
+
scheduledTasks.push((() => __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
if (!asset || !asset.buffer) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const { name, source, buffer, output, cacheItem, relatedName } = asset;
|
|
82
|
+
if (!output.source) {
|
|
83
|
+
if (!output.compressed) {
|
|
84
|
+
try {
|
|
85
|
+
output.compressed = yield this.runCompressionAlgorithm(buffer, name);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
compilation.errors.push(error);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (output.compressed.length / buffer.length >
|
|
93
|
+
this.options.minRatio) {
|
|
94
|
+
yield cacheItem.storePromise({ compressed: output.compressed });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
output.source = new RawSource(output.compressed);
|
|
98
|
+
yield cacheItem.storePromise(output);
|
|
99
|
+
}
|
|
100
|
+
const newFilename = compilation.getPath(this.options.filename({ filename: name }));
|
|
101
|
+
const newInfo = { compressed: true };
|
|
102
|
+
compilation.updateAsset(name, source, {
|
|
103
|
+
related: { [relatedName]: newFilename },
|
|
104
|
+
});
|
|
105
|
+
compilation.emitAsset(newFilename, output.source, newInfo);
|
|
106
|
+
}))());
|
|
107
|
+
}
|
|
108
|
+
yield Promise.all(scheduledTasks);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
apply(compiler) {
|
|
112
|
+
const pluginName = this.constructor.name;
|
|
113
|
+
compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
|
|
114
|
+
compilation.hooks.processAssets.tapPromise({
|
|
115
|
+
name: pluginName,
|
|
116
|
+
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER,
|
|
117
|
+
// additionalAssets: true,
|
|
118
|
+
}, (assets) => this.compress(compiler, compilation, assets));
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.CustomCompressionPlugin = CustomCompressionPlugin;
|
|
@@ -39,7 +39,6 @@ const compression_webpack_plugin_1 = __importDefault(require("compression-webpac
|
|
|
39
39
|
const css_minimizer_webpack_plugin_1 = __importDefault(require("css-minimizer-webpack-plugin"));
|
|
40
40
|
const fork_ts_checker_webpack_plugin_1 = __importDefault(require("fork-ts-checker-webpack-plugin"));
|
|
41
41
|
const html_webpack_plugin_1 = __importDefault(require("html-webpack-plugin"));
|
|
42
|
-
const mini_svg_data_uri_1 = __importDefault(require("mini-svg-data-uri"));
|
|
43
42
|
const rspack_manifest_plugin_1 = require("rspack-manifest-plugin");
|
|
44
43
|
const terser_webpack_plugin_1 = __importDefault(require("terser-webpack-plugin"));
|
|
45
44
|
const webpack_deduplication_plugin_1 = require("webpack-deduplication-plugin");
|
|
@@ -47,6 +46,7 @@ const arui_runtime_1 = require("../plugins/arui-runtime");
|
|
|
47
46
|
const html_template_1 = require("../templates/html.template");
|
|
48
47
|
const minimizers_1 = require("./config-extras/minimizers");
|
|
49
48
|
const check_node_version_1 = require("./util/check-node-version");
|
|
49
|
+
const compression_plugins_for_dictionaries_1 = require("./util/compression-plugins-for-dictionaries");
|
|
50
50
|
const get_entry_1 = require("./util/get-entry");
|
|
51
51
|
const app_configs_1 = require("./app-configs");
|
|
52
52
|
const babel_client_1 = require("./babel-client");
|
|
@@ -245,9 +245,6 @@ const createSingleClientWebpackConfig = (mode, entry, configName) => (Object.ass
|
|
|
245
245
|
{
|
|
246
246
|
test: /\.svg/,
|
|
247
247
|
type: 'asset',
|
|
248
|
-
generator: {
|
|
249
|
-
dataUrl: (file) => (0, mini_svg_data_uri_1.default)(file.content.toString()),
|
|
250
|
-
},
|
|
251
248
|
parser: {
|
|
252
249
|
dataUrlCondition: {
|
|
253
250
|
maxSize: app_configs_1.configs.dataUrlMaxSize,
|
|
@@ -359,7 +356,9 @@ const createSingleClientWebpackConfig = (mode, entry, configName) => (Object.ass
|
|
|
359
356
|
mode === 'prod' &&
|
|
360
357
|
!app_configs_1.configs.keepPropTypes &&
|
|
361
358
|
new core_1.NormalModuleReplacementPlugin(/^thrift-services\/proptypes/, noopPath),
|
|
362
|
-
].
|
|
359
|
+
].concat([
|
|
360
|
+
...(mode === 'prod' ? (0, compression_plugins_for_dictionaries_1.compressionPluginsForDictionaries)() : [])
|
|
361
|
+
]).filter(Boolean),
|
|
363
362
|
// Без этого комиляция трирегилась на изменение в node_modules и приводила к утечке памяти
|
|
364
363
|
watchOptions: {
|
|
365
364
|
ignored: new RegExp(app_configs_1.configs.watchIgnorePath.join('|')),
|
|
@@ -395,7 +394,7 @@ function getCodeLoader(mode) {
|
|
|
395
394
|
test: /\.(js|jsx|mjs|ts|tsx|cjs)$/,
|
|
396
395
|
include: app_configs_1.configs.appSrc,
|
|
397
396
|
loader: 'builtin:swc-loader',
|
|
398
|
-
options: Object.assign(Object.assign({
|
|
397
|
+
options: Object.assign(Object.assign({}, swc_1.swcClientConfig), { jsc: Object.assign(Object.assign({}, swc_1.swcClientConfig.jsc), { transform: Object.assign(Object.assign({}, (_a = swc_1.swcClientConfig.jsc) === null || _a === void 0 ? void 0 : _a.transform), { react: Object.assign(Object.assign({}, (_c = (_b = swc_1.swcClientConfig.jsc) === null || _b === void 0 ? void 0 : _b.transform) === null || _c === void 0 ? void 0 : _c.react), { refresh: mode === 'dev' }) }) }) }),
|
|
399
398
|
};
|
|
400
399
|
}
|
|
401
400
|
return {
|
|
@@ -9,7 +9,6 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const getCSSModuleLocalIdent_1 = __importDefault(require("react-dev-utils/getCSSModuleLocalIdent"));
|
|
10
10
|
const core_1 = require("@rspack/core");
|
|
11
11
|
const case_sensitive_paths_webpack_plugin_1 = __importDefault(require("case-sensitive-paths-webpack-plugin"));
|
|
12
|
-
const mini_svg_data_uri_1 = __importDefault(require("mini-svg-data-uri"));
|
|
13
12
|
const run_script_webpack_plugin_1 = require("run-script-webpack-plugin");
|
|
14
13
|
const webpack_node_externals_1 = __importDefault(require("webpack-node-externals"));
|
|
15
14
|
const reload_server_plugin_1 = require("../plugins/reload-server-plugin");
|
|
@@ -126,10 +125,6 @@ const createServerConfig = (mode) => ({
|
|
|
126
125
|
{
|
|
127
126
|
test: /\.svg/,
|
|
128
127
|
type: 'asset',
|
|
129
|
-
generator: {
|
|
130
|
-
dataUrl: (file) => (0, mini_svg_data_uri_1.default)(file.content.toString()),
|
|
131
|
-
publicPath: '',
|
|
132
|
-
},
|
|
133
128
|
parser: {
|
|
134
129
|
dataUrlCondition: {
|
|
135
130
|
maxSize: app_configs_1.configs.dataUrlMaxSize,
|