arui-scripts 20.0.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.
- package/.turbo/turbo-test.log +10 -8
- package/CHANGELOG.md +6 -0
- package/build/bin/index.js +0 -0
- package/build/commands/build/client.js +49 -28
- package/build/commands/util/brotli-dictionary/create-dcb-file.d.ts +6 -0
- package/build/commands/util/brotli-dictionary/create-dcb-file.js +38 -0
- package/build/commands/util/brotli-dictionary/find-files-to-compress.d.ts +9 -0
- package/build/commands/util/brotli-dictionary/find-files-to-compress.js +57 -0
- package/build/commands/util/brotli-dictionary/get-bundle-files.d.ts +1 -0
- package/build/commands/util/brotli-dictionary/get-bundle-files.js +26 -0
- package/build/commands/util/create-dictionary-files.d.ts +1 -0
- package/build/commands/util/create-dictionary-files.js +55 -0
- package/build/configs/app-configs/calculate-dependent-config.js +19 -1
- package/build/configs/app-configs/get-defaults.js +6 -0
- package/build/configs/app-configs/types.d.ts +6 -0
- package/build/configs/util/find-plugin.d.ts +2 -2
- package/build/configs/util/resolve.d.ts +3 -1
- package/build/configs/webpack.client.js +31 -2
- package/build/plugins/reload-server-plugin.d.ts +2 -2
- package/build/plugins/reload-server-plugin.js +3 -1
- package/build/templates/nginx.conf.template.js +1 -0
- package/build/tsconfig-local.tsbuildinfo +1 -1
- package/docs/compression-dictionary.md +130 -0
- package/docs/settings.md +14 -1
- package/package.json +179 -178
package/.turbo/turbo-test.log
CHANGED
|
@@ -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/
|
|
9
|
-
PASS src/
|
|
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
|
|
10
13
|
PASS src/configs/util/__tests__/apply-overrides.tests.ts
|
|
11
14
|
PASS src/configs/app-configs/__tests__/update-with-package.tests.ts
|
|
12
|
-
PASS src/configs/app-configs/__tests__/update-with-env.tests.ts
|
|
13
|
-
PASS src/configs/util/__tests__/get-polyfills.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 (
|
|
19
|
+
PASS src/configs/util/__tests__/find-plugin.tests.ts (31.057 s)
|
|
18
20
|
|
|
19
|
-
Test Suites:
|
|
20
|
-
Tests:
|
|
21
|
+
Test Suites: 12 passed, 12 total
|
|
22
|
+
Tests: 32 passed, 32 total
|
|
21
23
|
Snapshots: 0 total
|
|
22
|
-
Time:
|
|
24
|
+
Time: 32.219 s
|
|
23
25
|
Ran all test suites.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
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
|
+
|
|
3
9
|
## 20.0.0
|
|
4
10
|
|
|
5
11
|
### Major Changes
|
package/build/bin/index.js
CHANGED
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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,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
|
-
|
|
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>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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:
|
|
65
|
+
workers: Worker[];
|
|
66
66
|
};
|
|
67
67
|
CaseSensitivePathsPlugin: {
|
|
68
68
|
options: CaseSensitivePathsPlugin.Options;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export declare function tryResolve(...args:
|
|
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");
|
|
@@ -300,6 +324,9 @@ const createSingleClientWebpackConfig = (mode, entry, configName) => (Object.ass
|
|
|
300
324
|
filename: '../index.html',
|
|
301
325
|
}),
|
|
302
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
|
+
}),
|
|
303
330
|
// production plugins:
|
|
304
331
|
mode === 'prod' && new rspack_manifest_plugin_1.RspackManifestPlugin({}),
|
|
305
332
|
mode === 'prod' &&
|
|
@@ -315,9 +342,11 @@ const createSingleClientWebpackConfig = (mode, entry, configName) => (Object.ass
|
|
|
315
342
|
new compression_webpack_plugin_1.default({
|
|
316
343
|
filename: '[file].br',
|
|
317
344
|
algorithm: 'brotliCompress',
|
|
318
|
-
test: /\.(js|css|html|svg)$/,
|
|
345
|
+
test: /\.(js|css|html|svg|dict)$/,
|
|
319
346
|
compressionOptions: {
|
|
320
|
-
|
|
347
|
+
params: {
|
|
348
|
+
[zlib.constants.BROTLI_PARAM_QUALITY]: 11
|
|
349
|
+
},
|
|
321
350
|
},
|
|
322
351
|
threshold: 10240,
|
|
323
352
|
minRatio: 0.8,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Worker } from 'cluster';
|
|
2
2
|
import { type Compiler } from 'webpack';
|
|
3
3
|
export declare class ReloadServerPlugin {
|
|
4
|
-
workers:
|
|
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
|
-
|
|
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}`);
|
|
@@ -8,6 +8,7 @@ const nginxTemplate = `client_max_body_size 20m;
|
|
|
8
8
|
server {
|
|
9
9
|
listen ${app_configs_1.configs.clientServerPort};
|
|
10
10
|
server_tokens off;
|
|
11
|
+
${app_configs_1.configs.dictionaryCompression.enablePreviousVersionHeaders ? 'brotli_auto_dictionary on;' : ''}
|
|
11
12
|
|
|
12
13
|
${app_configs_1.configs.clientOnly
|
|
13
14
|
? `location / {
|