@gravity-ui/app-builder 0.23.1-beta.0 → 0.24.1-beta.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/dist/commands/build/build-service/client.js +1 -1
- package/dist/commands/dev/client.js +4 -0
- package/dist/common/models/index.d.ts +1 -0
- package/dist/common/webpack/compile.d.ts +1 -1
- package/dist/common/webpack/compile.js +15 -3
- package/dist/common/webpack/config.d.ts +2 -0
- package/dist/common/webpack/config.js +14 -19
- package/package.json +3 -3
- package/dist/common/webpack/statoscope.d.ts +0 -12
- package/dist/common/webpack/statoscope.js +0 -159
|
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.buildClient = buildClient;
|
|
4
4
|
const compile_1 = require("../../../common/webpack/compile");
|
|
5
5
|
function buildClient(config) {
|
|
6
|
-
return (0, compile_1.clientCompile)(config.client);
|
|
6
|
+
return (0, compile_1.clientCompile)(config.client, config.configPath);
|
|
7
7
|
}
|
|
@@ -60,6 +60,7 @@ async function buildDevServer(config) {
|
|
|
60
60
|
await (0, config_1.webpackConfigFactory)({
|
|
61
61
|
webpackMode: "development" /* WebpackMode.Dev */,
|
|
62
62
|
config: normalizedConfig,
|
|
63
|
+
configPath: config.configPath,
|
|
63
64
|
logger,
|
|
64
65
|
}),
|
|
65
66
|
];
|
|
@@ -68,6 +69,7 @@ async function buildDevServer(config) {
|
|
|
68
69
|
webpackConfigs.push(await (0, config_1.webpackConfigFactory)({
|
|
69
70
|
webpackMode: "development" /* WebpackMode.Dev */,
|
|
70
71
|
config: normalizedConfig,
|
|
72
|
+
configPath: config.configPath,
|
|
71
73
|
logger: ssrLogger,
|
|
72
74
|
isSsr,
|
|
73
75
|
}));
|
|
@@ -78,6 +80,7 @@ async function buildDevServer(config) {
|
|
|
78
80
|
await (0, config_1.rspackConfigFactory)({
|
|
79
81
|
webpackMode: "development" /* WebpackMode.Dev */,
|
|
80
82
|
config: normalizedConfig,
|
|
83
|
+
configPath: config.configPath,
|
|
81
84
|
logger,
|
|
82
85
|
}),
|
|
83
86
|
];
|
|
@@ -86,6 +89,7 @@ async function buildDevServer(config) {
|
|
|
86
89
|
rspackConfigs.push(await (0, config_1.rspackConfigFactory)({
|
|
87
90
|
webpackMode: "development" /* WebpackMode.Dev */,
|
|
88
91
|
config: normalizedConfig,
|
|
92
|
+
configPath: config.configPath,
|
|
89
93
|
logger: ssrLogger,
|
|
90
94
|
isSsr,
|
|
91
95
|
}));
|
|
@@ -271,6 +271,7 @@ export interface ServiceConfig {
|
|
|
271
271
|
server?: ServerConfig;
|
|
272
272
|
lib?: never;
|
|
273
273
|
verbose?: boolean;
|
|
274
|
+
configPath?: string;
|
|
274
275
|
}
|
|
275
276
|
export type NormalizedClientConfig = Omit<ClientConfig, 'publicPathPrefix' | 'publicPath' | 'assetsManifestFile' | 'hiddenSourceMap' | 'svgr' | 'lazyCompilation' | 'devServer' | 'disableForkTsChecker' | 'disableReactRefresh'> & {
|
|
276
277
|
bundler: Bundler;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { NormalizedClientConfig } from '../models';
|
|
2
|
-
export declare function clientCompile(config: NormalizedClientConfig): Promise<void>;
|
|
2
|
+
export declare function clientCompile(config: NormalizedClientConfig, configPath?: string): Promise<void>;
|
|
@@ -9,30 +9,42 @@ const core_1 = require("@rspack/core");
|
|
|
9
9
|
const logger_1 = require("../logger");
|
|
10
10
|
const config_1 = require("./config");
|
|
11
11
|
const utils_1 = require("./utils");
|
|
12
|
-
async function clientCompile(config) {
|
|
12
|
+
async function clientCompile(config, configPath) {
|
|
13
13
|
const logger = new logger_1.Logger('client', config.verbose);
|
|
14
14
|
const webpackConfigs = [];
|
|
15
15
|
const rspackConfigs = [];
|
|
16
16
|
const isSsr = Boolean(config.ssr);
|
|
17
17
|
if (config.bundler === 'rspack') {
|
|
18
|
-
rspackConfigs.push(await (0, config_1.rspackConfigFactory)({
|
|
18
|
+
rspackConfigs.push(await (0, config_1.rspackConfigFactory)({
|
|
19
|
+
webpackMode: "production" /* WebpackMode.Prod */,
|
|
20
|
+
config,
|
|
21
|
+
configPath,
|
|
22
|
+
logger,
|
|
23
|
+
}));
|
|
19
24
|
if (isSsr) {
|
|
20
25
|
const ssrLogger = new logger_1.Logger('client(SSR)', config.verbose);
|
|
21
26
|
rspackConfigs.push(await (0, config_1.rspackConfigFactory)({
|
|
22
27
|
webpackMode: "production" /* WebpackMode.Prod */,
|
|
23
28
|
config,
|
|
29
|
+
configPath,
|
|
24
30
|
logger: ssrLogger,
|
|
25
31
|
isSsr,
|
|
26
32
|
}));
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
35
|
else {
|
|
30
|
-
webpackConfigs.push(await (0, config_1.webpackConfigFactory)({
|
|
36
|
+
webpackConfigs.push(await (0, config_1.webpackConfigFactory)({
|
|
37
|
+
webpackMode: "production" /* WebpackMode.Prod */,
|
|
38
|
+
config,
|
|
39
|
+
configPath,
|
|
40
|
+
logger,
|
|
41
|
+
}));
|
|
31
42
|
if (isSsr) {
|
|
32
43
|
const ssrLogger = new logger_1.Logger('client(SSR)', config.verbose);
|
|
33
44
|
webpackConfigs.push(await (0, config_1.webpackConfigFactory)({
|
|
34
45
|
webpackMode: "production" /* WebpackMode.Prod */,
|
|
35
46
|
config,
|
|
47
|
+
configPath,
|
|
36
48
|
logger: ssrLogger,
|
|
37
49
|
isSsr,
|
|
38
50
|
}));
|
|
@@ -13,6 +13,7 @@ export interface HelperOptions {
|
|
|
13
13
|
entry?: string | string[] | Record<string, string | string[]>;
|
|
14
14
|
entriesDirectory: string;
|
|
15
15
|
isSsr: boolean;
|
|
16
|
+
configPath?: string;
|
|
16
17
|
}
|
|
17
18
|
export declare const enum WebpackMode {
|
|
18
19
|
Prod = "production",
|
|
@@ -23,6 +24,7 @@ type ClientFactoryOptions = {
|
|
|
23
24
|
config: NormalizedClientConfig;
|
|
24
25
|
logger?: Logger;
|
|
25
26
|
isSsr?: boolean;
|
|
27
|
+
configPath?: string;
|
|
26
28
|
};
|
|
27
29
|
export declare function webpackConfigFactory(options: ClientFactoryOptions): Promise<webpack.Configuration>;
|
|
28
30
|
export declare function rspackConfigFactory(options: ClientFactoryOptions): Promise<Rspack.Configuration>;
|
|
@@ -57,10 +57,9 @@ const s3_upload_1 = require("../s3-upload");
|
|
|
57
57
|
const log_config_1 = require("../logger/log-config");
|
|
58
58
|
const utils_2 = require("../typescript/utils");
|
|
59
59
|
const node_externals_1 = require("./node-externals");
|
|
60
|
-
const statoscope_1 = require("./statoscope");
|
|
61
60
|
const imagesSizeLimit = 2048;
|
|
62
61
|
const fontSizeLimit = 8192;
|
|
63
|
-
function getHelperOptions({ webpackMode, config, logger, isSsr = false, }) {
|
|
62
|
+
function getHelperOptions({ webpackMode, config, logger, isSsr = false, configPath, }) {
|
|
64
63
|
const isEnvDevelopment = webpackMode === "development" /* WebpackMode.Dev */;
|
|
65
64
|
const isEnvProduction = webpackMode === "production" /* WebpackMode.Prod */;
|
|
66
65
|
return {
|
|
@@ -74,6 +73,7 @@ function getHelperOptions({ webpackMode, config, logger, isSsr = false, }) {
|
|
|
74
73
|
entry: config.entry,
|
|
75
74
|
entriesDirectory: isSsr ? paths_1.default.appSsrEntry : paths_1.default.appEntry,
|
|
76
75
|
isSsr,
|
|
76
|
+
configPath,
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
function configureExternals({ config, isSsr }) {
|
|
@@ -221,13 +221,10 @@ function configureWatchOptions({ config }) {
|
|
|
221
221
|
delete watchOptions.watchPackages;
|
|
222
222
|
return watchOptions;
|
|
223
223
|
}
|
|
224
|
-
function getCacheBuildDependencies({ config }) {
|
|
224
|
+
function getCacheBuildDependencies({ config, configPath }) {
|
|
225
225
|
const buildDependencies = {};
|
|
226
226
|
const dependenciesGroups = {
|
|
227
|
-
appBuilderConfig: [
|
|
228
|
-
path.join(paths_1.default.app, 'app-builder.config.ts'),
|
|
229
|
-
path.join(paths_1.default.app, 'app-builder.config.js'),
|
|
230
|
-
],
|
|
227
|
+
appBuilderConfig: configPath ? [configPath] : [],
|
|
231
228
|
packageJson: [path.join(paths_1.default.app, 'package.json')],
|
|
232
229
|
tsconfig: [
|
|
233
230
|
path.join(paths_1.default.app, 'tsconfig.json'),
|
|
@@ -317,17 +314,22 @@ function configureRspackExperiments(options) {
|
|
|
317
314
|
},
|
|
318
315
|
};
|
|
319
316
|
}
|
|
317
|
+
const filesystemCacheOptions = typeof config.cache === 'object' && config.cache.type === 'filesystem'
|
|
318
|
+
? config.cache
|
|
319
|
+
: undefined;
|
|
320
|
+
const version = [filesystemCacheOptions?.name, filesystemCacheOptions?.version]
|
|
321
|
+
.filter(Boolean)
|
|
322
|
+
.join('-');
|
|
320
323
|
return {
|
|
321
324
|
cache: {
|
|
325
|
+
version: version || undefined,
|
|
322
326
|
type: 'persistent',
|
|
323
327
|
snapshot: {
|
|
324
328
|
managedPaths: config.watchOptions?.watchPackages ? [] : undefined,
|
|
325
329
|
},
|
|
326
330
|
storage: {
|
|
327
331
|
type: 'filesystem',
|
|
328
|
-
directory:
|
|
329
|
-
? config.cache.cacheDirectory
|
|
330
|
-
: undefined,
|
|
332
|
+
directory: filesystemCacheOptions?.cacheDirectory,
|
|
331
333
|
},
|
|
332
334
|
buildDependencies: Object.values(getCacheBuildDependencies(options)).flat(),
|
|
333
335
|
},
|
|
@@ -933,7 +935,7 @@ function configureCommonPlugins(options, bundlerPlugins) {
|
|
|
933
935
|
}
|
|
934
936
|
if (config.analyzeBundle === 'statoscope') {
|
|
935
937
|
const customStatoscopeConfig = config.statoscopeConfig || {};
|
|
936
|
-
|
|
938
|
+
plugins.push(new webpack_plugin_1.default({
|
|
937
939
|
saveReportTo: path.resolve(options.buildDirectory, 'report.html'),
|
|
938
940
|
saveStatsTo: path.resolve(options.buildDirectory, 'stats.json'),
|
|
939
941
|
open: false,
|
|
@@ -941,14 +943,7 @@ function configureCommonPlugins(options, bundlerPlugins) {
|
|
|
941
943
|
all: true,
|
|
942
944
|
},
|
|
943
945
|
...customStatoscopeConfig,
|
|
944
|
-
});
|
|
945
|
-
// TIP: statoscope doesn't support rspack, but this workaround helps to run it
|
|
946
|
-
if (config.bundler === 'rspack') {
|
|
947
|
-
const compressor = statoscopePlugin.options.compressor;
|
|
948
|
-
statoscopePlugin.extensions =
|
|
949
|
-
compressor === false ? [] : [new statoscope_1.RspackCompressedExtension(compressor)];
|
|
950
|
-
}
|
|
951
|
-
plugins.push(statoscopePlugin);
|
|
946
|
+
}));
|
|
952
947
|
}
|
|
953
948
|
if (config.analyzeBundle === 'rsdoctor') {
|
|
954
949
|
plugins.push(new bundlerPlugins.RSDoctorPlugin({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravity-ui/app-builder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.1-beta.0",
|
|
4
4
|
"description": "Develop and build your React client-server projects, powered by typescript and webpack",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -75,10 +75,10 @@
|
|
|
75
75
|
"@rspack/core": "1.2.8",
|
|
76
76
|
"@rspack/dev-server": "^1.0.10",
|
|
77
77
|
"@rspack/plugin-react-refresh": "^1.0.1",
|
|
78
|
-
"@statoscope/webpack-plugin": "^5.
|
|
78
|
+
"@statoscope/webpack-plugin": "^5.29.0",
|
|
79
79
|
"@statoscope/stats": "^5.28.1",
|
|
80
80
|
"@statoscope/stats-extension-compressed": "^5.28.1",
|
|
81
|
-
"@statoscope/webpack-model": "^5.
|
|
81
|
+
"@statoscope/webpack-model": "^5.29.0",
|
|
82
82
|
"@svgr/core": "^8.1.0",
|
|
83
83
|
"@svgr/plugin-jsx": "^8.1.0",
|
|
84
84
|
"@svgr/webpack": "^8.1.0",
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Compiler } from 'webpack';
|
|
2
|
-
import { ExtensionDescriptor } from '@statoscope/stats/spec/extension';
|
|
3
|
-
import CompressedExtensionGenerator, { CompressorOrPreset, Format, Payload } from '@statoscope/stats-extension-compressed/dist/generator';
|
|
4
|
-
import { StatsExtensionWebpackAdapter } from '@statoscope/webpack-model';
|
|
5
|
-
export declare class RspackCompressedExtension implements StatsExtensionWebpackAdapter<Payload> {
|
|
6
|
-
compressor: CompressorOrPreset;
|
|
7
|
-
descriptor: ExtensionDescriptor;
|
|
8
|
-
compressedExtensionGenerator: CompressedExtensionGenerator;
|
|
9
|
-
constructor(compressor: CompressorOrPreset);
|
|
10
|
-
getExtension(): Format;
|
|
11
|
-
handleCompiler(compiler: Compiler): void;
|
|
12
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.RspackCompressedExtension = void 0;
|
|
7
|
-
/* eslint-disable max-depth */
|
|
8
|
-
/**
|
|
9
|
-
* Adapted Statoscope extension @statoscope/webpack-stats-extension-compressed to support Rspack.
|
|
10
|
-
* This workaround will be removed once the pull request is merged into Statoscope:
|
|
11
|
-
* https://github.com/statoscope/statoscope/pull/239
|
|
12
|
-
*/
|
|
13
|
-
const path_1 = __importDefault(require("path"));
|
|
14
|
-
const util_1 = require("util");
|
|
15
|
-
const generator_1 = __importDefault(require("@statoscope/stats-extension-compressed/dist/generator"));
|
|
16
|
-
const name = '@statoscope/webpack-stats-extension-compressed';
|
|
17
|
-
const version = 'app-builder-version';
|
|
18
|
-
const pluginName = `${name}@${version}`;
|
|
19
|
-
class RspackCompressedExtension {
|
|
20
|
-
compressor;
|
|
21
|
-
descriptor = { name, version };
|
|
22
|
-
compressedExtensionGenerator = new generator_1.default(this.descriptor);
|
|
23
|
-
// eslint-disable-next-line @typescript-eslint/parameter-properties
|
|
24
|
-
constructor(compressor) {
|
|
25
|
-
this.compressor = compressor;
|
|
26
|
-
}
|
|
27
|
-
getExtension() {
|
|
28
|
-
return this.compressedExtensionGenerator.get();
|
|
29
|
-
}
|
|
30
|
-
handleCompiler(compiler) {
|
|
31
|
-
const isRspack = 'rspackVersion' in compiler.webpack;
|
|
32
|
-
const rspackCodeGenerationResults = new Map();
|
|
33
|
-
if (isRspack) {
|
|
34
|
-
compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
|
|
35
|
-
rspackCodeGenerationResults.clear();
|
|
36
|
-
compilation.hooks.executeModule.tap(pluginName, ({ moduleObject, codeGenerationResult }) => {
|
|
37
|
-
if (!moduleObject) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
rspackCodeGenerationResults.set(moduleObject.id, codeGenerationResult);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
compiler.hooks.done.tapAsync(pluginName, async (stats, cb) => {
|
|
45
|
-
const stack = [stats.compilation];
|
|
46
|
-
let cursor;
|
|
47
|
-
while ((cursor = stack.pop())) {
|
|
48
|
-
stack.push(...cursor.children);
|
|
49
|
-
// webpack 4
|
|
50
|
-
let readFile = (0, util_1.promisify)(cursor.compiler.inputFileSystem.readFile.bind(cursor.compiler.inputFileSystem));
|
|
51
|
-
// webpack 5
|
|
52
|
-
if (cursor.compiler.outputFileSystem &&
|
|
53
|
-
typeof cursor.compiler.outputFileSystem.readFile === 'function') {
|
|
54
|
-
readFile = (0, util_1.promisify)(cursor.compiler.outputFileSystem.readFile.bind(cursor.compiler.outputFileSystem));
|
|
55
|
-
}
|
|
56
|
-
for (const name of Object.keys(cursor.assets)) {
|
|
57
|
-
const assetPath = path_1.default.join(cursor.compiler.outputPath, name);
|
|
58
|
-
let content;
|
|
59
|
-
try {
|
|
60
|
-
content = await readFile(assetPath);
|
|
61
|
-
if (!content) {
|
|
62
|
-
throw new Error();
|
|
63
|
-
}
|
|
64
|
-
this.compressedExtensionGenerator.handleResource(cursor.hash, name, content, this.compressor);
|
|
65
|
-
}
|
|
66
|
-
catch (e) {
|
|
67
|
-
console.warn(`Can't read the asset ${name}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
const modulesStack = [...cursor.modules];
|
|
71
|
-
let modulesCursor;
|
|
72
|
-
while ((modulesCursor = modulesStack.pop())) {
|
|
73
|
-
// @ts-ignore
|
|
74
|
-
if (modulesCursor.modules) {
|
|
75
|
-
// @ts-ignore
|
|
76
|
-
modulesStack.push(...modulesCursor.modules);
|
|
77
|
-
}
|
|
78
|
-
let concatenated = Buffer.from('');
|
|
79
|
-
if (modulesCursor.constructor.name === 'CssModule' &&
|
|
80
|
-
// @ts-ignore
|
|
81
|
-
(typeof modulesCursor.content === 'string' ||
|
|
82
|
-
// @ts-ignore
|
|
83
|
-
modulesCursor.content instanceof Buffer)) {
|
|
84
|
-
this.compressedExtensionGenerator.handleResource(cursor.hash, modulesCursor.identifier(),
|
|
85
|
-
// @ts-ignore
|
|
86
|
-
modulesCursor.content, this.compressor);
|
|
87
|
-
}
|
|
88
|
-
else if (cursor.chunkGraph) {
|
|
89
|
-
// webpack 5 and rspack
|
|
90
|
-
if (isRspack) {
|
|
91
|
-
// Identifier contains source type and path, but keys in rspackCodeGenerationResults don't contain the source type.
|
|
92
|
-
const id = modulesCursor.identifier().split('|')[1];
|
|
93
|
-
if (!id) {
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
const codeGenerationResult = rspackCodeGenerationResults.get(id);
|
|
97
|
-
if (!codeGenerationResult || !('get' in codeGenerationResult)) {
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
// @ts-ignore
|
|
101
|
-
const content = codeGenerationResult.get('javascript');
|
|
102
|
-
if (content) {
|
|
103
|
-
concatenated = Buffer.concat([
|
|
104
|
-
// @ts-ignore
|
|
105
|
-
concatenated,
|
|
106
|
-
// @ts-ignore
|
|
107
|
-
content instanceof Buffer ? content : Buffer.from(content),
|
|
108
|
-
]);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
for (const type of modulesCursor.getSourceTypes()) {
|
|
113
|
-
const runtimeChunk = cursor.chunkGraph
|
|
114
|
-
.getModuleChunks(modulesCursor)
|
|
115
|
-
.find((chunk) => chunk.runtime);
|
|
116
|
-
if (runtimeChunk) {
|
|
117
|
-
const source = cursor.codeGenerationResults.getSource(modulesCursor, runtimeChunk.runtime, type);
|
|
118
|
-
if (!source) {
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
const content = source.source();
|
|
122
|
-
concatenated = Buffer.concat([
|
|
123
|
-
// @ts-ignore
|
|
124
|
-
concatenated,
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
content instanceof Buffer ? content : Buffer.from(content),
|
|
127
|
-
]);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
// webpack 4
|
|
134
|
-
try {
|
|
135
|
-
// @ts-ignore
|
|
136
|
-
const source = cursor.moduleTemplates.javascript.render(modulesCursor, cursor.dependencyTemplates, { chunk: modulesCursor.getChunks()[0] });
|
|
137
|
-
const content = source.source();
|
|
138
|
-
concatenated = Buffer.concat([
|
|
139
|
-
// @ts-ignore
|
|
140
|
-
concatenated,
|
|
141
|
-
// @ts-ignore
|
|
142
|
-
content instanceof Buffer ? content : Buffer.from(content),
|
|
143
|
-
]);
|
|
144
|
-
}
|
|
145
|
-
catch (e) {
|
|
146
|
-
// in webpack 4 we can't generate source for all the modules :(
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
if (!concatenated.length) {
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
this.compressedExtensionGenerator.handleResource(cursor.hash, modulesCursor.identifier(), concatenated, this.compressor);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
cb();
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
exports.RspackCompressedExtension = RspackCompressedExtension;
|