@gravity-ui/app-builder 0.13.1 → 0.14.0-beta.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/README.md +5 -2
- package/dist/commands/dev/client.js +42 -16
- package/dist/commands/dev/index.js +1 -1
- package/dist/common/babel/index.d.ts +4 -0
- package/dist/common/babel/index.js +5 -1
- package/dist/common/models/index.d.ts +8 -0
- package/dist/common/paths.d.ts +2 -0
- package/dist/common/paths.js +2 -0
- package/dist/common/webpack/compile.js +7 -2
- package/dist/common/webpack/config.d.ts +6 -2
- package/dist/common/webpack/config.js +193 -137
- package/dist/common/webpack/public-path.js +2 -1
- package/dist/common/webpack/storybook.js +4 -0
- package/dist/common/webpack/utils.d.ts +1 -1
- package/dist/common/webpack/utils.js +8 -3
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -192,8 +192,11 @@ With this `{rootDir}/src/ui/tsconfig.json`:
|
|
|
192
192
|
- `forkTsCheker` (`false | ForkTsCheckerWebpackPluginOptions`) - config for ForkTsCheckerWebpackPlugin [more](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#options). If `false`, ForkTsCheckerWebpackPlugin will be disabled.
|
|
193
193
|
- `cache` (`boolean | FileCacheOptions | MemoryCacheOptions`) — Cache the generated webpack modules and chunks to improve build speed. [more](https://webpack.js.org/configuration/cache/)
|
|
194
194
|
- `babelCacheDirectory` (`boolean | string`) — Set directory for babel-loader cache (`default: node_modules/.cache/babel-loader``)
|
|
195
|
-
- `babel` (`(config: babel.TransformOptions, options: {configType: 'development' | 'production'}) => babel.TransformOptions | Promise<babel.TransformOptions>`) - Allow override the default babel transform options.
|
|
196
|
-
- `webpack` (`(config: webpack.Configuration, options: {configType: 'development' | 'production'}) => webpack.Configuration | Promise<webpack.Configuration>`) - Allow override the default configuration.
|
|
195
|
+
- `babel` (`(config: babel.TransformOptions, options: {configType: 'development' | 'production'; isSsr: boolean}) => babel.TransformOptions | Promise<babel.TransformOptions>`) - Allow override the default babel transform options.
|
|
196
|
+
- `webpack` (`(config: webpack.Configuration, options: {configType: 'development' | 'production'; isSsr: boolean}) => webpack.Configuration | Promise<webpack.Configuration>`) - Allow override the default configuration.
|
|
197
|
+
- `ssr` - build SSR bundle. The SSR entries should be inside `src/ui/ssr` directory and match the client entries.
|
|
198
|
+
- `noExternal` (`string | RegExp | (string | RegExp)[] | true`) - prevent listed dependencies from being externalized for SSR. By default, all dependencies are externalized.
|
|
199
|
+
- `moduleType`: (`'commonjs' | 'esm'`) - library type for the SSR bundle, by default `commonjs`.
|
|
197
200
|
|
|
198
201
|
##### Dev build
|
|
199
202
|
|
|
@@ -40,9 +40,6 @@ const config_1 = require("../../common/webpack/config");
|
|
|
40
40
|
async function watchClientCompilation(config, onManifestReady) {
|
|
41
41
|
const clientCompilation = await buildWebpackServer(config);
|
|
42
42
|
const compiler = clientCompilation.compiler;
|
|
43
|
-
if ('compilers' in compiler) {
|
|
44
|
-
throw new Error('Unexpected multi compiler');
|
|
45
|
-
}
|
|
46
43
|
subscribeToManifestReadyEvent(compiler, onManifestReady);
|
|
47
44
|
return clientCompilation;
|
|
48
45
|
}
|
|
@@ -50,7 +47,14 @@ async function buildWebpackServer(config) {
|
|
|
50
47
|
const logger = new logger_1.Logger('webpack', config.verbose);
|
|
51
48
|
const { webSocketPath = path.normalize(`/${config.client.publicPathPrefix}/build/sockjs-node`), writeToDisk, ...devServer } = config.client.devServer || {};
|
|
52
49
|
const normalizedConfig = { ...config.client, devServer: { ...devServer, webSocketPath } };
|
|
53
|
-
const
|
|
50
|
+
const webpackConfigs = [
|
|
51
|
+
await (0, config_1.webpackConfigFactory)("development" /* WebpackMode.Dev */, normalizedConfig, { logger }),
|
|
52
|
+
];
|
|
53
|
+
const isSsr = Boolean(normalizedConfig.ssr);
|
|
54
|
+
if (isSsr) {
|
|
55
|
+
const logger = new logger_1.Logger('webpack(SSR)', config.verbose);
|
|
56
|
+
webpackConfigs.push(await (0, config_1.webpackConfigFactory)("development" /* WebpackMode.Dev */, normalizedConfig, { logger, isSsr }));
|
|
57
|
+
}
|
|
54
58
|
const publicPath = path.normalize(config.client.publicPathPrefix + '/build/');
|
|
55
59
|
const staticFolder = path.resolve(paths_1.default.appDist, 'public');
|
|
56
60
|
const options = {
|
|
@@ -58,7 +62,18 @@ async function buildWebpackServer(config) {
|
|
|
58
62
|
devMiddleware: {
|
|
59
63
|
publicPath,
|
|
60
64
|
stats: 'errors-warnings',
|
|
61
|
-
writeToDisk
|
|
65
|
+
writeToDisk: (target) => {
|
|
66
|
+
if (writeToDisk === true) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (isSsr && target.startsWith(paths_1.default.appSsrBuild)) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
if (typeof writeToDisk === 'function') {
|
|
73
|
+
return writeToDisk(target);
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
},
|
|
62
77
|
},
|
|
63
78
|
liveReload: false,
|
|
64
79
|
hot: true,
|
|
@@ -116,7 +131,7 @@ async function buildWebpackServer(config) {
|
|
|
116
131
|
});
|
|
117
132
|
}
|
|
118
133
|
options.proxy = proxy;
|
|
119
|
-
const compiler = (0, webpack_1.default)(
|
|
134
|
+
const compiler = (0, webpack_1.default)(webpackConfigs);
|
|
120
135
|
const server = new webpack_dev_server_1.default(options, compiler);
|
|
121
136
|
try {
|
|
122
137
|
await server.start();
|
|
@@ -129,17 +144,28 @@ async function buildWebpackServer(config) {
|
|
|
129
144
|
}
|
|
130
145
|
return server;
|
|
131
146
|
}
|
|
132
|
-
function subscribeToManifestReadyEvent(
|
|
147
|
+
function subscribeToManifestReadyEvent(webpackCompiler, onManifestReady) {
|
|
133
148
|
const promises = [];
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
149
|
+
const options = Array.isArray(webpackCompiler.options)
|
|
150
|
+
? webpackCompiler.options
|
|
151
|
+
: [webpackCompiler.options];
|
|
152
|
+
const compilers = 'compilers' in webpackCompiler ? webpackCompiler.compilers : [webpackCompiler];
|
|
153
|
+
for (let i = 0; i < options.length; i++) {
|
|
154
|
+
const config = options[i];
|
|
155
|
+
const compiler = compilers[i];
|
|
156
|
+
if (!config || !compiler) {
|
|
157
|
+
throw new Error('Something goes wrong!');
|
|
158
|
+
}
|
|
159
|
+
const assetsManifestPlugin = config.plugins.find((plugin) => plugin instanceof webpack_assets_manifest_1.default);
|
|
160
|
+
if (assetsManifestPlugin) {
|
|
161
|
+
const assetsManifestReady = (0, utils_1.deferredPromise)();
|
|
162
|
+
promises.push(assetsManifestReady.promise);
|
|
163
|
+
assetsManifestPlugin.hooks.done.tap('app-builder', assetsManifestReady.resolve);
|
|
164
|
+
}
|
|
165
|
+
const manifestReady = (0, utils_1.deferredPromise)();
|
|
166
|
+
promises.push(manifestReady.promise);
|
|
167
|
+
const { afterEmit } = (0, webpack_manifest_plugin_1.getCompilerHooks)(compiler);
|
|
168
|
+
afterEmit.tap('app-builder', manifestReady.resolve);
|
|
139
169
|
}
|
|
140
|
-
const manifestReady = (0, utils_1.deferredPromise)();
|
|
141
|
-
promises.push(manifestReady.promise);
|
|
142
|
-
const { afterEmit } = (0, webpack_manifest_plugin_1.getCompilerHooks)(compiler);
|
|
143
|
-
afterEmit.tap('app-builder', manifestReady.resolve);
|
|
144
170
|
Promise.all(promises).then(() => onManifestReady());
|
|
145
171
|
}
|
|
@@ -56,7 +56,7 @@ async function default_1(config) {
|
|
|
56
56
|
script: `${serverPath}/index.js`,
|
|
57
57
|
args: ['--dev', config.server.port ? `--port=${config.server.port}` : ''],
|
|
58
58
|
env: {
|
|
59
|
-
...(config.server.port ? { APP_PORT: config.server.port } : undefined),
|
|
59
|
+
...(config.server.port ? { APP_PORT: `${config.server.port}` } : undefined),
|
|
60
60
|
},
|
|
61
61
|
nodeArgs: inspect || inspectBrk
|
|
62
62
|
? [`--${inspect ? 'inspect' : 'inspect-brk'}=:::${inspect || inspectBrk}`]
|
|
@@ -5,7 +5,11 @@ function babelPreset(config) {
|
|
|
5
5
|
return [
|
|
6
6
|
require.resolve('./ui-preset'),
|
|
7
7
|
{
|
|
8
|
-
env: {
|
|
8
|
+
env: {
|
|
9
|
+
modules: false,
|
|
10
|
+
bugfixes: true,
|
|
11
|
+
targets: config.isSsr ? { node: 'current' } : undefined,
|
|
12
|
+
},
|
|
9
13
|
runtime: { version: '^7.13.10' },
|
|
10
14
|
typescript: true,
|
|
11
15
|
react: {
|
|
@@ -180,17 +180,23 @@ export interface ClientConfig {
|
|
|
180
180
|
*/
|
|
181
181
|
webpack?: (config: Configuration, options: {
|
|
182
182
|
configType: `${WebpackMode}`;
|
|
183
|
+
isSsr?: boolean;
|
|
183
184
|
}) => Configuration | Promise<Configuration>;
|
|
184
185
|
/**
|
|
185
186
|
* Modify or return a custom Babel config.
|
|
186
187
|
*/
|
|
187
188
|
babel?: (config: Babel.TransformOptions, options: {
|
|
188
189
|
configType: `${WebpackMode}`;
|
|
190
|
+
isSsr: boolean;
|
|
189
191
|
}) => Babel.TransformOptions | Promise<Babel.TransformOptions>;
|
|
190
192
|
/**
|
|
191
193
|
* Modify or return a custom [Terser options](https://github.com/terser/terser#minify-options).
|
|
192
194
|
*/
|
|
193
195
|
terser?: (options: TerserOptions) => TerserOptions;
|
|
196
|
+
ssr?: {
|
|
197
|
+
noExternal?: string | RegExp | (string | RegExp)[] | true;
|
|
198
|
+
moduleType?: 'commonjs' | 'esm';
|
|
199
|
+
};
|
|
194
200
|
}
|
|
195
201
|
export interface CdnUploadConfig {
|
|
196
202
|
bucket: string;
|
|
@@ -230,10 +236,12 @@ export type NormalizedClientConfig = Omit<ClientConfig, 'publicPathPrefix' | 'hi
|
|
|
230
236
|
verbose?: boolean;
|
|
231
237
|
webpack: (config: Configuration, options: {
|
|
232
238
|
configType: `${WebpackMode}`;
|
|
239
|
+
isSsr: boolean;
|
|
233
240
|
}) => Configuration | Promise<Configuration>;
|
|
234
241
|
debugWebpack?: boolean;
|
|
235
242
|
babel: (config: Babel.TransformOptions, options: {
|
|
236
243
|
configType: `${WebpackMode}`;
|
|
244
|
+
isSsr: boolean;
|
|
237
245
|
}) => Babel.TransformOptions | Promise<Babel.TransformOptions>;
|
|
238
246
|
reactRefresh: NonNullable<ClientConfig['reactRefresh']>;
|
|
239
247
|
};
|
package/dist/common/paths.d.ts
CHANGED
package/dist/common/paths.js
CHANGED
|
@@ -36,6 +36,8 @@ exports.default = {
|
|
|
36
36
|
appDist: resolveApp('dist'),
|
|
37
37
|
appRun: resolveApp('dist/run'),
|
|
38
38
|
appBuild: resolveApp('dist/public/build'),
|
|
39
|
+
appSsrEntry: resolveApp('src/ui/ssr'),
|
|
40
|
+
appSsrBuild: resolveApp('dist/ssr'),
|
|
39
41
|
src: resolveApp('src'),
|
|
40
42
|
libBuild: resolveApp('build'),
|
|
41
43
|
libBuildEsm: resolveApp('build/esm'),
|
|
@@ -10,10 +10,15 @@ const config_1 = require("./config");
|
|
|
10
10
|
const utils_1 = require("./utils");
|
|
11
11
|
async function webpackCompile(config) {
|
|
12
12
|
const logger = new logger_1.Logger('webpack', config.verbose);
|
|
13
|
-
const
|
|
13
|
+
const webpackConfigs = [await (0, config_1.webpackConfigFactory)("production" /* WebpackMode.Prod */, config, { logger })];
|
|
14
|
+
const isSsr = Boolean(config.ssr);
|
|
15
|
+
if (isSsr) {
|
|
16
|
+
const logger = new logger_1.Logger('webpack(SSR)', config.verbose);
|
|
17
|
+
webpackConfigs.push(await (0, config_1.webpackConfigFactory)("production" /* WebpackMode.Prod */, config, { logger, isSsr }));
|
|
18
|
+
}
|
|
14
19
|
logger.verbose('Config created');
|
|
15
20
|
return new Promise((resolve) => {
|
|
16
|
-
const compiler = (0, webpack_1.default)(
|
|
21
|
+
const compiler = (0, webpack_1.default)(webpackConfigs, (0, utils_1.webpackCompilerHandlerFactory)(logger, async () => {
|
|
17
22
|
resolve();
|
|
18
23
|
}));
|
|
19
24
|
process.on('SIGINT', async () => {
|
|
@@ -7,16 +7,20 @@ export interface HelperOptions {
|
|
|
7
7
|
isEnvDevelopment: boolean;
|
|
8
8
|
isEnvProduction: boolean;
|
|
9
9
|
configType: `${WebpackMode}`;
|
|
10
|
+
buildDirectory: string;
|
|
11
|
+
entriesDirectory: string;
|
|
12
|
+
isSsr: boolean;
|
|
10
13
|
}
|
|
11
14
|
export declare const enum WebpackMode {
|
|
12
15
|
Prod = "production",
|
|
13
16
|
Dev = "development"
|
|
14
17
|
}
|
|
15
|
-
export declare function webpackConfigFactory(webpackMode: WebpackMode, config: NormalizedClientConfig, { logger }?: {
|
|
18
|
+
export declare function webpackConfigFactory(webpackMode: WebpackMode, config: NormalizedClientConfig, { logger, isSsr }?: {
|
|
16
19
|
logger?: Logger;
|
|
20
|
+
isSsr?: boolean;
|
|
17
21
|
}): Promise<webpack.Configuration>;
|
|
18
22
|
export declare function configureModuleRules(helperOptions: HelperOptions, additionalRules?: NonNullable<webpack.RuleSetRule['oneOf']>): webpack.RuleSetRule[];
|
|
19
23
|
export declare function configureResolve({ isEnvProduction, config }: HelperOptions): webpack.ResolveOptions;
|
|
20
24
|
type Optimization = NonNullable<webpack.Configuration['optimization']>;
|
|
21
|
-
export declare function configureOptimization({ config }: HelperOptions): Optimization;
|
|
25
|
+
export declare function configureOptimization({ config, isSsr }: HelperOptions): Optimization;
|
|
22
26
|
export {};
|
|
@@ -44,6 +44,7 @@ const react_refresh_webpack_plugin_1 = __importDefault(require("@pmmmwh/react-re
|
|
|
44
44
|
const moment_timezone_data_webpack_plugin_1 = __importDefault(require("moment-timezone-data-webpack-plugin"));
|
|
45
45
|
const webpack_plugin_1 = __importDefault(require("@statoscope/webpack-plugin"));
|
|
46
46
|
const circular_dependency_plugin_1 = __importDefault(require("circular-dependency-plugin"));
|
|
47
|
+
const webpack_node_externals_1 = __importDefault(require("webpack-node-externals"));
|
|
47
48
|
const paths_1 = __importDefault(require("../paths"));
|
|
48
49
|
const babel_1 = require("../babel");
|
|
49
50
|
const progress_plugin_1 = require("./progress-plugin");
|
|
@@ -53,7 +54,7 @@ const log_config_1 = require("../logger/log-config");
|
|
|
53
54
|
const utils_2 = require("../typescript/utils");
|
|
54
55
|
const imagesSizeLimit = 2048;
|
|
55
56
|
const fontSizeLimit = 8192;
|
|
56
|
-
async function webpackConfigFactory(webpackMode, config, { logger } = {}) {
|
|
57
|
+
async function webpackConfigFactory(webpackMode, config, { logger, isSsr = false } = {}) {
|
|
57
58
|
const isEnvDevelopment = webpackMode === "development" /* WebpackMode.Dev */;
|
|
58
59
|
const isEnvProduction = webpackMode === "production" /* WebpackMode.Prod */;
|
|
59
60
|
const helperOptions = {
|
|
@@ -62,11 +63,25 @@ async function webpackConfigFactory(webpackMode, config, { logger } = {}) {
|
|
|
62
63
|
isEnvDevelopment,
|
|
63
64
|
isEnvProduction,
|
|
64
65
|
configType: webpackMode,
|
|
66
|
+
buildDirectory: isSsr ? paths_1.default.appSsrBuild : paths_1.default.appBuild,
|
|
67
|
+
entriesDirectory: isSsr ? paths_1.default.appSsrEntry : paths_1.default.appEntry,
|
|
68
|
+
isSsr,
|
|
65
69
|
};
|
|
70
|
+
let externals = config.externals;
|
|
71
|
+
if (isSsr) {
|
|
72
|
+
externals =
|
|
73
|
+
config.ssr?.noExternal === true
|
|
74
|
+
? undefined
|
|
75
|
+
: (0, webpack_node_externals_1.default)({
|
|
76
|
+
allowlist: config.ssr?.noExternal,
|
|
77
|
+
importType: config.ssr?.moduleType === 'esm' ? 'module' : 'commonjs',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
66
80
|
let webpackConfig = {
|
|
67
81
|
mode: webpackMode,
|
|
68
82
|
context: paths_1.default.app,
|
|
69
83
|
bail: isEnvProduction,
|
|
84
|
+
target: isSsr ? 'node' : undefined,
|
|
70
85
|
devtool: configureDevTool(helperOptions),
|
|
71
86
|
entry: configureEntry(helperOptions),
|
|
72
87
|
output: configureOutput(helperOptions),
|
|
@@ -76,7 +91,7 @@ async function webpackConfigFactory(webpackMode, config, { logger } = {}) {
|
|
|
76
91
|
},
|
|
77
92
|
plugins: configurePlugins(helperOptions),
|
|
78
93
|
optimization: configureOptimization(helperOptions),
|
|
79
|
-
externals
|
|
94
|
+
externals,
|
|
80
95
|
node: config.node,
|
|
81
96
|
watchOptions: configureWatchOptions(helperOptions),
|
|
82
97
|
ignoreWarnings: [/Failed to parse source map/],
|
|
@@ -92,7 +107,7 @@ async function webpackConfigFactory(webpackMode, config, { logger } = {}) {
|
|
|
92
107
|
},
|
|
93
108
|
cache: config.cache,
|
|
94
109
|
};
|
|
95
|
-
webpackConfig = await config.webpack(webpackConfig, { configType: webpackMode });
|
|
110
|
+
webpackConfig = await config.webpack(webpackConfig, { configType: webpackMode, isSsr });
|
|
96
111
|
if (config.debugWebpack) {
|
|
97
112
|
(0, log_config_1.logConfig)('Preview webpack config', webpackConfig);
|
|
98
113
|
}
|
|
@@ -135,7 +150,10 @@ function configureWatchOptions({ config }) {
|
|
|
135
150
|
delete watchOptions.watchPackages;
|
|
136
151
|
return watchOptions;
|
|
137
152
|
}
|
|
138
|
-
function configureExperiments({ config, isEnvProduction, }) {
|
|
153
|
+
function configureExperiments({ config, isEnvProduction, isSsr, }) {
|
|
154
|
+
if (isSsr) {
|
|
155
|
+
return config.ssr?.moduleType === 'esm' ? { outputModule: true } : undefined;
|
|
156
|
+
}
|
|
139
157
|
if (isEnvProduction) {
|
|
140
158
|
return undefined;
|
|
141
159
|
}
|
|
@@ -190,61 +208,74 @@ function createEntryArray(entry) {
|
|
|
190
208
|
return [require.resolve('./public-path'), entry];
|
|
191
209
|
}
|
|
192
210
|
function addEntry(entry, file) {
|
|
193
|
-
const newEntry = path.resolve(paths_1.default.appEntry, file);
|
|
194
211
|
return {
|
|
195
212
|
...entry,
|
|
196
|
-
[path.parse(file).name]: createEntryArray(
|
|
213
|
+
[path.parse(file).name]: createEntryArray(file),
|
|
197
214
|
};
|
|
198
215
|
}
|
|
199
|
-
function configureEntry({ config }) {
|
|
200
|
-
let entries = fs.readdirSync(
|
|
216
|
+
function configureEntry({ config, entriesDirectory }) {
|
|
217
|
+
let entries = fs.readdirSync(entriesDirectory).filter((file) => /\.[jt]sx?$/.test(file));
|
|
201
218
|
if (Array.isArray(config.entryFilter) && config.entryFilter.length) {
|
|
202
219
|
entries = entries.filter((entry) => config.entryFilter?.includes(entry.split('.')[0] ?? ''));
|
|
203
220
|
}
|
|
204
221
|
if (!entries.length) {
|
|
205
|
-
throw new Error('No entries were found after applying
|
|
222
|
+
throw new Error('No entries were found after applying entry filter');
|
|
206
223
|
}
|
|
207
|
-
return entries.reduce((entry, file) => addEntry(entry, file), {});
|
|
224
|
+
return entries.reduce((entry, file) => addEntry(entry, path.resolve(entriesDirectory, file)), {});
|
|
208
225
|
}
|
|
209
|
-
function getFileNames({ isEnvProduction }) {
|
|
226
|
+
function getFileNames({ isEnvProduction, isSsr, config }) {
|
|
227
|
+
let ext = 'js';
|
|
228
|
+
if (isSsr) {
|
|
229
|
+
ext = config.ssr?.moduleType === 'esm' ? 'mjs' : 'cjs';
|
|
230
|
+
}
|
|
210
231
|
return {
|
|
211
|
-
filename: isEnvProduction ?
|
|
232
|
+
filename: isEnvProduction ? `js/[name].[contenthash:8].${ext}` : `js/[name].${ext}`,
|
|
212
233
|
chunkFilename: isEnvProduction
|
|
213
234
|
? 'js/[name].[contenthash:8].chunk.js'
|
|
214
235
|
: 'js/[name].chunk.js',
|
|
215
236
|
};
|
|
216
237
|
}
|
|
217
|
-
function configureOutput(
|
|
238
|
+
function configureOutput(options) {
|
|
239
|
+
let ssrOptions;
|
|
240
|
+
if (options.isSsr) {
|
|
241
|
+
ssrOptions = {
|
|
242
|
+
library: { type: options.config.ssr?.moduleType === 'esm' ? 'module' : 'commonjs2' },
|
|
243
|
+
chunkFormat: false,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
218
246
|
return {
|
|
219
|
-
...getFileNames(
|
|
220
|
-
path:
|
|
221
|
-
pathinfo: isEnvDevelopment,
|
|
247
|
+
...getFileNames(options),
|
|
248
|
+
path: options.buildDirectory,
|
|
249
|
+
pathinfo: options.isEnvDevelopment,
|
|
250
|
+
...ssrOptions,
|
|
222
251
|
};
|
|
223
252
|
}
|
|
224
|
-
function createJavaScriptLoader({ isEnvProduction, isEnvDevelopment, configType, config, }) {
|
|
253
|
+
function createJavaScriptLoader({ isEnvProduction, isEnvDevelopment, configType, config, isSsr, }) {
|
|
225
254
|
const plugins = [];
|
|
226
|
-
if (
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
255
|
+
if (!isSsr) {
|
|
256
|
+
if (isEnvDevelopment && config.reactRefresh !== false) {
|
|
257
|
+
plugins.push([
|
|
258
|
+
require.resolve('react-refresh/babel'),
|
|
259
|
+
config.devServer?.webSocketPath
|
|
260
|
+
? {
|
|
261
|
+
overlay: {
|
|
262
|
+
sockPath: config.devServer.webSocketPath,
|
|
263
|
+
},
|
|
264
|
+
}
|
|
265
|
+
: undefined,
|
|
266
|
+
]);
|
|
267
|
+
}
|
|
268
|
+
if (isEnvProduction) {
|
|
269
|
+
plugins.push([
|
|
270
|
+
require.resolve('babel-plugin-import'),
|
|
271
|
+
{ libraryName: 'lodash', libraryDirectory: '', camel2DashComponentName: false },
|
|
272
|
+
]);
|
|
273
|
+
}
|
|
243
274
|
}
|
|
244
275
|
const transformOptions = config.babel({
|
|
245
|
-
presets: [(0, babel_1.babelPreset)(config)],
|
|
276
|
+
presets: [(0, babel_1.babelPreset)({ newJsxTransform: config.newJsxTransform, isSsr })],
|
|
246
277
|
plugins,
|
|
247
|
-
}, { configType });
|
|
278
|
+
}, { configType, isSsr });
|
|
248
279
|
return {
|
|
249
280
|
loader: require.resolve('babel-loader'),
|
|
250
281
|
options: {
|
|
@@ -339,7 +370,7 @@ function createStylesRule(options) {
|
|
|
339
370
|
use: loaders,
|
|
340
371
|
};
|
|
341
372
|
}
|
|
342
|
-
function getCssLoaders({ isEnvDevelopment, isEnvProduction, config }, additionalRules) {
|
|
373
|
+
function getCssLoaders({ isEnvDevelopment, isEnvProduction, config, isSsr }, additionalRules) {
|
|
343
374
|
const loaders = [];
|
|
344
375
|
if (!config.transformCssWithLightningCss) {
|
|
345
376
|
loaders.push({
|
|
@@ -362,27 +393,32 @@ function getCssLoaders({ isEnvDevelopment, isEnvProduction, config }, additional
|
|
|
362
393
|
loaders.unshift({
|
|
363
394
|
loader: require.resolve('css-loader'),
|
|
364
395
|
options: {
|
|
365
|
-
esModule: false,
|
|
366
396
|
sourceMap: !config.disableSourceMapGeneration,
|
|
367
397
|
importLoaders,
|
|
368
398
|
modules: {
|
|
369
399
|
auto: true,
|
|
370
400
|
localIdentName: '[name]__[local]--[hash:base64:5]',
|
|
371
401
|
exportLocalsConvention: 'camelCase',
|
|
402
|
+
exportOnlyLocals: isSsr,
|
|
372
403
|
},
|
|
373
404
|
},
|
|
374
405
|
});
|
|
375
406
|
if (isEnvProduction) {
|
|
376
|
-
loaders.unshift(mini_css_extract_plugin_1.default.loader);
|
|
407
|
+
loaders.unshift({ loader: mini_css_extract_plugin_1.default.loader, options: { emit: !isSsr } });
|
|
377
408
|
}
|
|
378
409
|
if (isEnvDevelopment) {
|
|
379
|
-
|
|
380
|
-
loader:
|
|
381
|
-
}
|
|
410
|
+
if (isSsr || config.ssr) {
|
|
411
|
+
loaders.unshift({ loader: mini_css_extract_plugin_1.default.loader, options: { emit: !isSsr } });
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
loaders.unshift({
|
|
415
|
+
loader: require.resolve('style-loader'),
|
|
416
|
+
});
|
|
417
|
+
}
|
|
382
418
|
}
|
|
383
419
|
return loaders;
|
|
384
420
|
}
|
|
385
|
-
function createIconsRule({ isEnvProduction, config }, jsLoader) {
|
|
421
|
+
function createIconsRule({ isEnvProduction, config, isSsr }, jsLoader) {
|
|
386
422
|
const iconIncludes = config.icons || [];
|
|
387
423
|
return {
|
|
388
424
|
// eslint-disable-next-line security/detect-unsafe-regex
|
|
@@ -419,11 +455,12 @@ function createIconsRule({ isEnvProduction, config }, jsLoader) {
|
|
|
419
455
|
generator: {
|
|
420
456
|
filename: 'assets/images/[name].[contenthash:8][ext]',
|
|
421
457
|
publicPath: isEnvProduction ? '../' : undefined,
|
|
458
|
+
emit: isSsr ? false : undefined,
|
|
422
459
|
},
|
|
423
460
|
}),
|
|
424
461
|
};
|
|
425
462
|
}
|
|
426
|
-
function createAssetsRules({ isEnvProduction, config }) {
|
|
463
|
+
function createAssetsRules({ isEnvProduction, config, isSsr }) {
|
|
427
464
|
const imagesRule = {
|
|
428
465
|
test: /\.(ico|bmp|gif|jpe?g|png|svg)$/,
|
|
429
466
|
include: [paths_1.default.appClient, ...(config.images || [])],
|
|
@@ -435,6 +472,7 @@ function createAssetsRules({ isEnvProduction, config }) {
|
|
|
435
472
|
},
|
|
436
473
|
generator: {
|
|
437
474
|
filename: 'assets/images/[name].[contenthash:8][ext]',
|
|
475
|
+
emit: isSsr ? false : undefined,
|
|
438
476
|
},
|
|
439
477
|
};
|
|
440
478
|
const fontsRule = {
|
|
@@ -448,6 +486,7 @@ function createAssetsRules({ isEnvProduction, config }) {
|
|
|
448
486
|
},
|
|
449
487
|
generator: {
|
|
450
488
|
filename: 'assets/fonts/[name].[contenthash:8][ext]',
|
|
489
|
+
emit: isSsr ? false : undefined,
|
|
451
490
|
},
|
|
452
491
|
};
|
|
453
492
|
const rules = [imagesRule, fontsRule];
|
|
@@ -467,6 +506,7 @@ function createAssetsRules({ isEnvProduction, config }) {
|
|
|
467
506
|
generator: {
|
|
468
507
|
filename: 'assets/images/[name].[contenthash:8][ext]',
|
|
469
508
|
publicPath: '../',
|
|
509
|
+
emit: isSsr ? false : undefined,
|
|
470
510
|
},
|
|
471
511
|
}, {
|
|
472
512
|
test: /\.(ttf|eot|woff2?)$/,
|
|
@@ -481,17 +521,19 @@ function createAssetsRules({ isEnvProduction, config }) {
|
|
|
481
521
|
generator: {
|
|
482
522
|
filename: 'assets/fonts/[name].[contenthash:8][ext]',
|
|
483
523
|
publicPath: '../',
|
|
524
|
+
emit: isSsr ? false : undefined,
|
|
484
525
|
},
|
|
485
526
|
});
|
|
486
527
|
}
|
|
487
528
|
return rules;
|
|
488
529
|
}
|
|
489
|
-
function createFallbackRules({ isEnvProduction }) {
|
|
530
|
+
function createFallbackRules({ isEnvProduction, isSsr }) {
|
|
490
531
|
const rules = [
|
|
491
532
|
{
|
|
492
533
|
type: 'asset/resource',
|
|
493
534
|
generator: {
|
|
494
535
|
filename: 'assets/[name].[contenthash:8][ext]',
|
|
536
|
+
emit: isSsr ? false : undefined,
|
|
495
537
|
},
|
|
496
538
|
exclude: [/\.[jt]sx?$/, /\.json$/, /\.[cm]js$/, /\.ejs$/],
|
|
497
539
|
},
|
|
@@ -506,6 +548,7 @@ function createFallbackRules({ isEnvProduction }) {
|
|
|
506
548
|
generator: {
|
|
507
549
|
filename: 'assets/[name].[contenthash:8][ext]',
|
|
508
550
|
publicPath: '../',
|
|
551
|
+
emit: isSsr ? false : undefined,
|
|
509
552
|
},
|
|
510
553
|
});
|
|
511
554
|
}
|
|
@@ -520,7 +563,7 @@ function createMomentTimezoneDataPlugin(options = {}) {
|
|
|
520
563
|
return new moment_timezone_data_webpack_plugin_1.default({ ...options, startYear, endYear });
|
|
521
564
|
}
|
|
522
565
|
function configurePlugins(options) {
|
|
523
|
-
const { isEnvDevelopment, isEnvProduction, config } = options;
|
|
566
|
+
const { isEnvDevelopment, isEnvProduction, config, isSsr } = options;
|
|
524
567
|
const excludeFromClean = config.excludeFromClean || [];
|
|
525
568
|
const manifestFile = 'assets-manifest.json';
|
|
526
569
|
const plugins = [
|
|
@@ -544,11 +587,11 @@ function configurePlugins(options) {
|
|
|
544
587
|
: {
|
|
545
588
|
entrypoints: true,
|
|
546
589
|
writeToDisk: true,
|
|
547
|
-
output: path.resolve(
|
|
590
|
+
output: path.resolve(options.buildDirectory, manifestFile),
|
|
548
591
|
}),
|
|
549
|
-
createMomentTimezoneDataPlugin(config.momentTz),
|
|
550
592
|
new webpack.DefinePlugin({
|
|
551
593
|
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
|
594
|
+
'process.env.IS_SSR': JSON.stringify(isSsr),
|
|
552
595
|
...config.definitions,
|
|
553
596
|
}),
|
|
554
597
|
];
|
|
@@ -558,51 +601,12 @@ function configurePlugins(options) {
|
|
|
558
601
|
if (process.env.WEBPACK_PROFILE === 'true') {
|
|
559
602
|
plugins.push(new webpack.debug.ProfilingPlugin());
|
|
560
603
|
}
|
|
561
|
-
const contextReplacement = config.contextReplacement || {};
|
|
562
|
-
plugins.push(new webpack.ContextReplacementPlugin(/moment[\\/]locale$/,
|
|
563
|
-
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
564
|
-
new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})$`)));
|
|
565
|
-
plugins.push(new webpack.ContextReplacementPlugin(/dayjs[\\/]locale$/,
|
|
566
|
-
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
567
|
-
new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})\\.js$`)));
|
|
568
|
-
if (contextReplacement['highlight.js']) {
|
|
569
|
-
plugins.push(new webpack.ContextReplacementPlugin(/highlight\.js[\\/]lib[\\/]languages$/,
|
|
570
|
-
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
571
|
-
new RegExp(`^\\./(${contextReplacement['highlight.js'].join('|')})$`)));
|
|
572
|
-
}
|
|
573
|
-
if (config.monaco) {
|
|
574
|
-
const MonacoEditorWebpackPlugin = require('monaco-editor-webpack-plugin');
|
|
575
|
-
plugins.push(new MonacoEditorWebpackPlugin({
|
|
576
|
-
filename: isEnvProduction ? '[name].[hash:8].worker.js' : undefined,
|
|
577
|
-
...config.monaco,
|
|
578
|
-
// currently, workers located on cdn are not working properly, so we are enforcing loading workers from
|
|
579
|
-
// service instead
|
|
580
|
-
publicPath: path.normalize(config.publicPathPrefix + '/build/'),
|
|
581
|
-
}));
|
|
582
|
-
}
|
|
583
|
-
if (isEnvDevelopment && config.reactRefresh !== false) {
|
|
584
|
-
const { webSocketPath = path.normalize(`/${config.publicPathPrefix}/build/sockjs-node`) } = config.devServer || {};
|
|
585
|
-
plugins.push(new react_refresh_webpack_plugin_1.default(config.reactRefresh({
|
|
586
|
-
overlay: { sockPath: webSocketPath },
|
|
587
|
-
exclude: [/node_modules/, /\.worker\.[jt]sx?$/],
|
|
588
|
-
})));
|
|
589
|
-
}
|
|
590
|
-
if (config.detectCircularDependencies) {
|
|
591
|
-
let circularPluginOptions = {
|
|
592
|
-
exclude: /node_modules/,
|
|
593
|
-
allowAsyncCycles: true,
|
|
594
|
-
};
|
|
595
|
-
if (typeof config.detectCircularDependencies === 'object') {
|
|
596
|
-
circularPluginOptions = config.detectCircularDependencies;
|
|
597
|
-
}
|
|
598
|
-
plugins.push(new circular_dependency_plugin_1.default(circularPluginOptions));
|
|
599
|
-
}
|
|
600
604
|
if (config.forkTsChecker !== false) {
|
|
601
605
|
plugins.push(new fork_ts_checker_webpack_plugin_1.default({
|
|
602
606
|
...config.forkTsChecker,
|
|
603
607
|
typescript: {
|
|
604
608
|
typescriptPath: (0, utils_2.resolveTypescript)(),
|
|
605
|
-
configFile: path.resolve(paths_1.default.
|
|
609
|
+
configFile: path.resolve(paths_1.default.appClient, 'tsconfig.json'),
|
|
606
610
|
diagnosticOptions: {
|
|
607
611
|
syntactic: true,
|
|
608
612
|
},
|
|
@@ -611,19 +615,17 @@ function configurePlugins(options) {
|
|
|
611
615
|
},
|
|
612
616
|
}));
|
|
613
617
|
}
|
|
614
|
-
if (config.
|
|
615
|
-
|
|
618
|
+
if (config.detectCircularDependencies) {
|
|
619
|
+
let circularPluginOptions = {
|
|
620
|
+
exclude: /node_modules/,
|
|
621
|
+
allowAsyncCycles: true,
|
|
622
|
+
};
|
|
623
|
+
if (typeof config.detectCircularDependencies === 'object') {
|
|
624
|
+
circularPluginOptions = config.detectCircularDependencies;
|
|
625
|
+
}
|
|
626
|
+
plugins.push(new circular_dependency_plugin_1.default(circularPluginOptions));
|
|
616
627
|
}
|
|
617
628
|
if (isEnvProduction) {
|
|
618
|
-
plugins.push(new mini_css_extract_plugin_1.default({
|
|
619
|
-
filename: 'css/[name].[contenthash:8].css',
|
|
620
|
-
chunkFilename: 'css/[name].[contenthash:8].chunk.css',
|
|
621
|
-
ignoreOrder: true,
|
|
622
|
-
}));
|
|
623
|
-
if (config.sentryConfig) {
|
|
624
|
-
const sentryPlugin = require('@sentry/webpack-plugin').sentryWebpackPlugin;
|
|
625
|
-
plugins.push(sentryPlugin({ ...config.sentryConfig }));
|
|
626
|
-
}
|
|
627
629
|
if (config.analyzeBundle === 'true') {
|
|
628
630
|
plugins.push(new webpack_bundle_analyzer_1.BundleAnalyzerPlugin({
|
|
629
631
|
openAnalyzer: false,
|
|
@@ -634,8 +636,8 @@ function configurePlugins(options) {
|
|
|
634
636
|
if (config.analyzeBundle === 'statoscope') {
|
|
635
637
|
const customStatoscopeConfig = config.statoscopeConfig || {};
|
|
636
638
|
plugins.push(new webpack_plugin_1.default({
|
|
637
|
-
saveReportTo: path.resolve(
|
|
638
|
-
saveStatsTo: path.resolve(
|
|
639
|
+
saveReportTo: path.resolve(options.buildDirectory, 'report.html'),
|
|
640
|
+
saveStatsTo: path.resolve(options.buildDirectory, 'stats.json'),
|
|
639
641
|
open: false,
|
|
640
642
|
statsOptions: {
|
|
641
643
|
all: true,
|
|
@@ -644,50 +646,104 @@ function configurePlugins(options) {
|
|
|
644
646
|
}));
|
|
645
647
|
}
|
|
646
648
|
}
|
|
647
|
-
if (config.
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
649
|
+
if (isEnvProduction || isSsr || config.ssr) {
|
|
650
|
+
plugins.push(new mini_css_extract_plugin_1.default({
|
|
651
|
+
filename: isEnvProduction ? 'css/[name].[contenthash:8].css' : 'css/[name].css',
|
|
652
|
+
chunkFilename: isEnvProduction
|
|
653
|
+
? 'css/[name].[contenthash:8].chunk.css'
|
|
654
|
+
: 'css/[name].chunk.css',
|
|
655
|
+
ignoreOrder: true,
|
|
656
|
+
}));
|
|
657
|
+
}
|
|
658
|
+
if (!isSsr) {
|
|
659
|
+
if (config.monaco) {
|
|
660
|
+
const MonacoEditorWebpackPlugin = require('monaco-editor-webpack-plugin');
|
|
661
|
+
plugins.push(new MonacoEditorWebpackPlugin({
|
|
662
|
+
filename: isEnvProduction ? '[name].[hash:8].worker.js' : undefined,
|
|
663
|
+
...config.monaco,
|
|
664
|
+
// currently, workers located on cdn are not working properly, so we are enforcing loading workers from
|
|
665
|
+
// service instead
|
|
666
|
+
publicPath: path.normalize(config.publicPathPrefix + '/build/'),
|
|
667
|
+
}));
|
|
654
668
|
}
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
669
|
+
const contextReplacement = config.contextReplacement || {};
|
|
670
|
+
plugins.push(createMomentTimezoneDataPlugin(config.momentTz));
|
|
671
|
+
plugins.push(new webpack.ContextReplacementPlugin(/moment[\\/]locale$/,
|
|
672
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
673
|
+
new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})$`)));
|
|
674
|
+
plugins.push(new webpack.ContextReplacementPlugin(/dayjs[\\/]locale$/,
|
|
675
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
676
|
+
new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})\\.js$`)));
|
|
677
|
+
if (contextReplacement['highlight.js']) {
|
|
678
|
+
plugins.push(new webpack.ContextReplacementPlugin(/highlight\.js[\\/]lib[\\/]languages$/,
|
|
679
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
680
|
+
new RegExp(`^\\./(${contextReplacement['highlight.js'].join('|')})$`)));
|
|
681
|
+
}
|
|
682
|
+
if (isEnvDevelopment && config.reactRefresh !== false) {
|
|
683
|
+
const { webSocketPath = path.normalize(`/${config.publicPathPrefix}/build/sockjs-node`), } = config.devServer || {};
|
|
684
|
+
plugins.push(new react_refresh_webpack_plugin_1.default(config.reactRefresh({
|
|
685
|
+
overlay: { sockPath: webSocketPath },
|
|
686
|
+
exclude: [/node_modules/, /\.worker\.[jt]sx?$/],
|
|
687
|
+
})));
|
|
688
|
+
}
|
|
689
|
+
if (config.polyfill?.process) {
|
|
690
|
+
plugins.push(new webpack.ProvidePlugin({ process: 'process/browser.js' }));
|
|
691
|
+
}
|
|
692
|
+
if (isEnvProduction) {
|
|
693
|
+
if (config.sentryConfig) {
|
|
694
|
+
const sentryPlugin = require('@sentry/webpack-plugin').sentryWebpackPlugin;
|
|
695
|
+
plugins.push(sentryPlugin({ ...config.sentryConfig }));
|
|
660
696
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
697
|
+
}
|
|
698
|
+
if (config.cdn) {
|
|
699
|
+
let credentialsGlobal;
|
|
700
|
+
if (process.env.FRONTEND_S3_ACCESS_KEY_ID &&
|
|
701
|
+
process.env.FRONTEND_S3_SECRET_ACCESS_KEY) {
|
|
702
|
+
credentialsGlobal = {
|
|
703
|
+
accessKeyId: process.env.FRONTEND_S3_ACCESS_KEY_ID,
|
|
704
|
+
secretAccessKey: process.env.FRONTEND_S3_SECRET_ACCESS_KEY,
|
|
668
705
|
};
|
|
669
706
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
707
|
+
const cdns = Array.isArray(config.cdn) ? config.cdn : [config.cdn];
|
|
708
|
+
for (let index = 0; index < cdns.length; index++) {
|
|
709
|
+
const cdn = cdns[index];
|
|
710
|
+
if (!cdn) {
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
713
|
+
let credentials = credentialsGlobal;
|
|
714
|
+
const accessKeyId = process.env[`FRONTEND_S3_ACCESS_KEY_ID_${index}`];
|
|
715
|
+
const secretAccessKey = process.env[`FRONTEND_S3_SECRET_ACCESS_KEY_${index}`];
|
|
716
|
+
if (accessKeyId && secretAccessKey) {
|
|
717
|
+
credentials = {
|
|
718
|
+
accessKeyId,
|
|
719
|
+
secretAccessKey,
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
plugins.push(new s3_upload_1.S3UploadPlugin({
|
|
723
|
+
exclude: config.hiddenSourceMap ? /\.map$/ : undefined,
|
|
724
|
+
compress: cdn.compress,
|
|
725
|
+
s3ClientOptions: {
|
|
726
|
+
region: cdn.region,
|
|
727
|
+
endpoint: cdn.endpoint,
|
|
728
|
+
credentials,
|
|
729
|
+
},
|
|
730
|
+
s3UploadOptions: {
|
|
731
|
+
bucket: cdn.bucket,
|
|
732
|
+
targetPath: cdn.prefix,
|
|
733
|
+
cacheControl: cdn.cacheControl,
|
|
734
|
+
},
|
|
735
|
+
additionalPattern: cdn.additionalPattern,
|
|
736
|
+
logger: options.logger,
|
|
737
|
+
}));
|
|
738
|
+
}
|
|
686
739
|
}
|
|
687
740
|
}
|
|
688
741
|
return plugins;
|
|
689
742
|
}
|
|
690
|
-
function configureOptimization({ config }) {
|
|
743
|
+
function configureOptimization({ config, isSsr }) {
|
|
744
|
+
if (isSsr) {
|
|
745
|
+
return {};
|
|
746
|
+
}
|
|
691
747
|
const configVendors = config.vendors ?? [];
|
|
692
748
|
let vendorsList = [
|
|
693
749
|
'react',
|
|
@@ -35,6 +35,7 @@ const css_minimizer_webpack_plugin_1 = __importDefault(require("css-minimizer-we
|
|
|
35
35
|
const config_1 = require("./config");
|
|
36
36
|
const config_2 = require("../config");
|
|
37
37
|
const models_1 = require("../models");
|
|
38
|
+
const paths_1 = __importDefault(require("../paths"));
|
|
38
39
|
async function configureServiceWebpackConfig(mode, storybookConfig) {
|
|
39
40
|
const serviceConfig = await (0, config_2.getProjectConfig)(mode === "production" /* WebpackMode.Prod */ ? 'build' : 'dev', {
|
|
40
41
|
storybook: true,
|
|
@@ -104,6 +105,9 @@ async function configureWebpackConfigForStorybook(mode, userConfig = {}, storybo
|
|
|
104
105
|
isEnvProduction,
|
|
105
106
|
config: config.client,
|
|
106
107
|
configType: mode,
|
|
108
|
+
buildDirectory: paths_1.default.appBuild,
|
|
109
|
+
entriesDirectory: paths_1.default.appEntry,
|
|
110
|
+
isSsr: false,
|
|
107
111
|
};
|
|
108
112
|
return {
|
|
109
113
|
module: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type webpack from 'webpack';
|
|
2
2
|
import type { Logger } from '../logger';
|
|
3
|
-
export declare function webpackCompilerHandlerFactory(logger: Logger, onCompilationEnd?: () => void): (err?: Error | null, stats?: webpack.
|
|
3
|
+
export declare function webpackCompilerHandlerFactory(logger: Logger, onCompilationEnd?: () => void): (err?: Error | null, stats?: webpack.MultiStats) => Promise<void>;
|
|
4
4
|
export declare function resolveTsconfigPathsToAlias(tsConfigPath: string): {
|
|
5
5
|
aliases: Record<string, string[]>;
|
|
6
6
|
modules: string[];
|
|
@@ -50,11 +50,16 @@ function webpackCompilerHandlerFactory(logger, onCompilationEnd) {
|
|
|
50
50
|
if (onCompilationEnd) {
|
|
51
51
|
await onCompilationEnd();
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
const [clientStats, ssrStats] = stats?.stats ?? [];
|
|
54
|
+
if (clientStats) {
|
|
55
|
+
const time = clientStats.endTime - clientStats.startTime;
|
|
55
56
|
logger.success(`Client was successfully compiled in ${(0, pretty_time_1.prettyTime)(BigInt(time) * BigInt(1_000_000))}`);
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
+
if (ssrStats) {
|
|
59
|
+
const time = ssrStats.endTime - ssrStats.startTime;
|
|
60
|
+
logger.success(`SSR: Client was successfully compiled in ${(0, pretty_time_1.prettyTime)(BigInt(time) * BigInt(1_000_000))}`);
|
|
61
|
+
}
|
|
62
|
+
if (!clientStats && !ssrStats) {
|
|
58
63
|
logger.success(`Client was successfully compiled`);
|
|
59
64
|
}
|
|
60
65
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravity-ui/app-builder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0-beta.1",
|
|
4
4
|
"description": "Develop and build your React client-server projects, powered by typescript and webpack",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -129,6 +129,7 @@
|
|
|
129
129
|
"webpack-bundle-analyzer": "^4.10.2",
|
|
130
130
|
"webpack-dev-server": "^5.1.0",
|
|
131
131
|
"webpack-manifest-plugin": "^5.0.0",
|
|
132
|
+
"webpack-node-externals": "^3.0.0",
|
|
132
133
|
"worker-loader": "^3.0.8",
|
|
133
134
|
"yargs": "^17.7.2"
|
|
134
135
|
},
|
|
@@ -152,6 +153,7 @@
|
|
|
152
153
|
"@types/webpack-assets-manifest": "^5.1.4",
|
|
153
154
|
"@types/webpack-bundle-analyzer": "^4.7.0",
|
|
154
155
|
"@types/webpack-manifest-plugin": "^3.0.8",
|
|
156
|
+
"@types/webpack-node-externals": "^3.0.4",
|
|
155
157
|
"@types/yargs": "17.0.11",
|
|
156
158
|
"babel-plugin-tester": "^11.0.4",
|
|
157
159
|
"eslint": "^8.57.0",
|