@gravity-ui/app-builder 0.13.0 → 0.14.0-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/dev/client.js +42 -16
- package/dist/commands/dev/index.js +1 -1
- package/dist/common/models/index.d.ts +4 -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 +221 -163
- 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 +10 -2
- package/package.json +3 -1
|
@@ -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}`]
|
|
@@ -191,6 +191,10 @@ export interface ClientConfig {
|
|
|
191
191
|
* Modify or return a custom [Terser options](https://github.com/terser/terser#minify-options).
|
|
192
192
|
*/
|
|
193
193
|
terser?: (options: TerserOptions) => TerserOptions;
|
|
194
|
+
ssr?: {
|
|
195
|
+
noExternal?: string | RegExp | (string | RegExp)[] | true;
|
|
196
|
+
moduleType?: 'commonjs' | 'esm';
|
|
197
|
+
};
|
|
194
198
|
}
|
|
195
199
|
export interface CdnUploadConfig {
|
|
196
200
|
bucket: string;
|
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/],
|
|
@@ -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,56 +208,69 @@ 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
276
|
presets: [(0, babel_1.babelPreset)(config)],
|
|
@@ -308,22 +339,23 @@ function createWorkerRule(options) {
|
|
|
308
339
|
};
|
|
309
340
|
}
|
|
310
341
|
function createSassStylesRule(options) {
|
|
311
|
-
const loaders = getCssLoaders(options
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
342
|
+
const loaders = getCssLoaders(options, [
|
|
343
|
+
{
|
|
344
|
+
loader: require.resolve('resolve-url-loader'),
|
|
345
|
+
options: {
|
|
346
|
+
sourceMap: !options.config.disableSourceMapGeneration,
|
|
347
|
+
},
|
|
316
348
|
},
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
349
|
+
{
|
|
350
|
+
loader: require.resolve('sass-loader'),
|
|
351
|
+
options: {
|
|
352
|
+
sourceMap: true, // must be always true for work with resolve-url-loader
|
|
353
|
+
sassOptions: {
|
|
354
|
+
loadPaths: [paths_1.default.appClient],
|
|
355
|
+
},
|
|
324
356
|
},
|
|
325
357
|
},
|
|
326
|
-
|
|
358
|
+
]);
|
|
327
359
|
return {
|
|
328
360
|
test: /\.scss$/,
|
|
329
361
|
sideEffects: options.isEnvProduction ? true : undefined,
|
|
@@ -338,29 +370,8 @@ function createStylesRule(options) {
|
|
|
338
370
|
use: loaders,
|
|
339
371
|
};
|
|
340
372
|
}
|
|
341
|
-
function getCssLoaders({ isEnvDevelopment, isEnvProduction, config }) {
|
|
373
|
+
function getCssLoaders({ isEnvDevelopment, isEnvProduction, config, isSsr }, additionalRules) {
|
|
342
374
|
const loaders = [];
|
|
343
|
-
if (isEnvProduction) {
|
|
344
|
-
loaders.push(mini_css_extract_plugin_1.default.loader);
|
|
345
|
-
}
|
|
346
|
-
if (isEnvDevelopment) {
|
|
347
|
-
loaders.push({
|
|
348
|
-
loader: require.resolve('style-loader'),
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
loaders.push({
|
|
352
|
-
loader: require.resolve('css-loader'),
|
|
353
|
-
options: {
|
|
354
|
-
esModule: false,
|
|
355
|
-
sourceMap: !config.disableSourceMapGeneration,
|
|
356
|
-
importLoaders: 2,
|
|
357
|
-
modules: {
|
|
358
|
-
auto: true,
|
|
359
|
-
localIdentName: '[name]__[local]--[hash:base64:5]',
|
|
360
|
-
exportLocalsConvention: 'camelCase',
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
});
|
|
364
375
|
if (!config.transformCssWithLightningCss) {
|
|
365
376
|
loaders.push({
|
|
366
377
|
loader: require.resolve('postcss-loader'),
|
|
@@ -375,9 +386,39 @@ function getCssLoaders({ isEnvDevelopment, isEnvProduction, config }) {
|
|
|
375
386
|
},
|
|
376
387
|
});
|
|
377
388
|
}
|
|
389
|
+
if (Array.isArray(additionalRules) && additionalRules.length > 0) {
|
|
390
|
+
loaders.push(...additionalRules);
|
|
391
|
+
}
|
|
392
|
+
const importLoaders = loaders.length;
|
|
393
|
+
loaders.unshift({
|
|
394
|
+
loader: require.resolve('css-loader'),
|
|
395
|
+
options: {
|
|
396
|
+
sourceMap: !config.disableSourceMapGeneration,
|
|
397
|
+
importLoaders,
|
|
398
|
+
modules: {
|
|
399
|
+
auto: true,
|
|
400
|
+
localIdentName: '[name]__[local]--[hash:base64:5]',
|
|
401
|
+
exportLocalsConvention: 'camelCase',
|
|
402
|
+
exportOnlyLocals: isSsr,
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
if (isEnvProduction) {
|
|
407
|
+
loaders.unshift({ loader: mini_css_extract_plugin_1.default.loader, options: { emit: !isSsr } });
|
|
408
|
+
}
|
|
409
|
+
if (isEnvDevelopment) {
|
|
410
|
+
if (isSsr) {
|
|
411
|
+
loaders.unshift({ loader: mini_css_extract_plugin_1.default.loader, options: { emit: false } });
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
loaders.unshift({
|
|
415
|
+
loader: require.resolve('style-loader'),
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
378
419
|
return loaders;
|
|
379
420
|
}
|
|
380
|
-
function createIconsRule({ isEnvProduction, config }, jsLoader) {
|
|
421
|
+
function createIconsRule({ isEnvProduction, config, isSsr }, jsLoader) {
|
|
381
422
|
const iconIncludes = config.icons || [];
|
|
382
423
|
return {
|
|
383
424
|
// eslint-disable-next-line security/detect-unsafe-regex
|
|
@@ -414,11 +455,12 @@ function createIconsRule({ isEnvProduction, config }, jsLoader) {
|
|
|
414
455
|
generator: {
|
|
415
456
|
filename: 'assets/images/[name].[contenthash:8][ext]',
|
|
416
457
|
publicPath: isEnvProduction ? '../' : undefined,
|
|
458
|
+
emit: !isSsr,
|
|
417
459
|
},
|
|
418
460
|
}),
|
|
419
461
|
};
|
|
420
462
|
}
|
|
421
|
-
function createAssetsRules({ isEnvProduction, config }) {
|
|
463
|
+
function createAssetsRules({ isEnvProduction, config, isSsr }) {
|
|
422
464
|
const imagesRule = {
|
|
423
465
|
test: /\.(ico|bmp|gif|jpe?g|png|svg)$/,
|
|
424
466
|
include: [paths_1.default.appClient, ...(config.images || [])],
|
|
@@ -430,6 +472,7 @@ function createAssetsRules({ isEnvProduction, config }) {
|
|
|
430
472
|
},
|
|
431
473
|
generator: {
|
|
432
474
|
filename: 'assets/images/[name].[contenthash:8][ext]',
|
|
475
|
+
emit: !isSsr,
|
|
433
476
|
},
|
|
434
477
|
};
|
|
435
478
|
const fontsRule = {
|
|
@@ -443,6 +486,7 @@ function createAssetsRules({ isEnvProduction, config }) {
|
|
|
443
486
|
},
|
|
444
487
|
generator: {
|
|
445
488
|
filename: 'assets/fonts/[name].[contenthash:8][ext]',
|
|
489
|
+
emit: !isSsr,
|
|
446
490
|
},
|
|
447
491
|
};
|
|
448
492
|
const rules = [imagesRule, fontsRule];
|
|
@@ -462,6 +506,7 @@ function createAssetsRules({ isEnvProduction, config }) {
|
|
|
462
506
|
generator: {
|
|
463
507
|
filename: 'assets/images/[name].[contenthash:8][ext]',
|
|
464
508
|
publicPath: '../',
|
|
509
|
+
emit: !isSsr,
|
|
465
510
|
},
|
|
466
511
|
}, {
|
|
467
512
|
test: /\.(ttf|eot|woff2?)$/,
|
|
@@ -476,17 +521,19 @@ function createAssetsRules({ isEnvProduction, config }) {
|
|
|
476
521
|
generator: {
|
|
477
522
|
filename: 'assets/fonts/[name].[contenthash:8][ext]',
|
|
478
523
|
publicPath: '../',
|
|
524
|
+
emit: !isSsr,
|
|
479
525
|
},
|
|
480
526
|
});
|
|
481
527
|
}
|
|
482
528
|
return rules;
|
|
483
529
|
}
|
|
484
|
-
function createFallbackRules({ isEnvProduction }) {
|
|
530
|
+
function createFallbackRules({ isEnvProduction, isSsr }) {
|
|
485
531
|
const rules = [
|
|
486
532
|
{
|
|
487
533
|
type: 'asset/resource',
|
|
488
534
|
generator: {
|
|
489
535
|
filename: 'assets/[name].[contenthash:8][ext]',
|
|
536
|
+
emit: !isSsr,
|
|
490
537
|
},
|
|
491
538
|
exclude: [/\.[jt]sx?$/, /\.json$/, /\.[cm]js$/, /\.ejs$/],
|
|
492
539
|
},
|
|
@@ -501,6 +548,7 @@ function createFallbackRules({ isEnvProduction }) {
|
|
|
501
548
|
generator: {
|
|
502
549
|
filename: 'assets/[name].[contenthash:8][ext]',
|
|
503
550
|
publicPath: '../',
|
|
551
|
+
emit: !isSsr,
|
|
504
552
|
},
|
|
505
553
|
});
|
|
506
554
|
}
|
|
@@ -515,7 +563,7 @@ function createMomentTimezoneDataPlugin(options = {}) {
|
|
|
515
563
|
return new moment_timezone_data_webpack_plugin_1.default({ ...options, startYear, endYear });
|
|
516
564
|
}
|
|
517
565
|
function configurePlugins(options) {
|
|
518
|
-
const { isEnvDevelopment, isEnvProduction, config } = options;
|
|
566
|
+
const { isEnvDevelopment, isEnvProduction, config, isSsr } = options;
|
|
519
567
|
const excludeFromClean = config.excludeFromClean || [];
|
|
520
568
|
const manifestFile = 'assets-manifest.json';
|
|
521
569
|
const plugins = [
|
|
@@ -539,9 +587,8 @@ function configurePlugins(options) {
|
|
|
539
587
|
: {
|
|
540
588
|
entrypoints: true,
|
|
541
589
|
writeToDisk: true,
|
|
542
|
-
output: path.resolve(
|
|
590
|
+
output: path.resolve(options.buildDirectory, manifestFile),
|
|
543
591
|
}),
|
|
544
|
-
createMomentTimezoneDataPlugin(config.momentTz),
|
|
545
592
|
new webpack.DefinePlugin({
|
|
546
593
|
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
|
547
594
|
...config.definitions,
|
|
@@ -553,51 +600,12 @@ function configurePlugins(options) {
|
|
|
553
600
|
if (process.env.WEBPACK_PROFILE === 'true') {
|
|
554
601
|
plugins.push(new webpack.debug.ProfilingPlugin());
|
|
555
602
|
}
|
|
556
|
-
const contextReplacement = config.contextReplacement || {};
|
|
557
|
-
plugins.push(new webpack.ContextReplacementPlugin(/moment[\\/]locale$/,
|
|
558
|
-
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
559
|
-
new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})$`)));
|
|
560
|
-
plugins.push(new webpack.ContextReplacementPlugin(/dayjs[\\/]locale$/,
|
|
561
|
-
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
562
|
-
new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})\\.js$`)));
|
|
563
|
-
if (contextReplacement['highlight.js']) {
|
|
564
|
-
plugins.push(new webpack.ContextReplacementPlugin(/highlight\.js[\\/]lib[\\/]languages$/,
|
|
565
|
-
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
566
|
-
new RegExp(`^\\./(${contextReplacement['highlight.js'].join('|')})$`)));
|
|
567
|
-
}
|
|
568
|
-
if (config.monaco) {
|
|
569
|
-
const MonacoEditorWebpackPlugin = require('monaco-editor-webpack-plugin');
|
|
570
|
-
plugins.push(new MonacoEditorWebpackPlugin({
|
|
571
|
-
filename: isEnvProduction ? '[name].[hash:8].worker.js' : undefined,
|
|
572
|
-
...config.monaco,
|
|
573
|
-
// currently, workers located on cdn are not working properly, so we are enforcing loading workers from
|
|
574
|
-
// service instead
|
|
575
|
-
publicPath: path.normalize(config.publicPathPrefix + '/build/'),
|
|
576
|
-
}));
|
|
577
|
-
}
|
|
578
|
-
if (isEnvDevelopment && config.reactRefresh !== false) {
|
|
579
|
-
const { webSocketPath = path.normalize(`/${config.publicPathPrefix}/build/sockjs-node`) } = config.devServer || {};
|
|
580
|
-
plugins.push(new react_refresh_webpack_plugin_1.default(config.reactRefresh({
|
|
581
|
-
overlay: { sockPath: webSocketPath },
|
|
582
|
-
exclude: [/node_modules/, /\.worker\.[jt]sx?$/],
|
|
583
|
-
})));
|
|
584
|
-
}
|
|
585
|
-
if (config.detectCircularDependencies) {
|
|
586
|
-
let circularPluginOptions = {
|
|
587
|
-
exclude: /node_modules/,
|
|
588
|
-
allowAsyncCycles: true,
|
|
589
|
-
};
|
|
590
|
-
if (typeof config.detectCircularDependencies === 'object') {
|
|
591
|
-
circularPluginOptions = config.detectCircularDependencies;
|
|
592
|
-
}
|
|
593
|
-
plugins.push(new circular_dependency_plugin_1.default(circularPluginOptions));
|
|
594
|
-
}
|
|
595
603
|
if (config.forkTsChecker !== false) {
|
|
596
604
|
plugins.push(new fork_ts_checker_webpack_plugin_1.default({
|
|
597
605
|
...config.forkTsChecker,
|
|
598
606
|
typescript: {
|
|
599
607
|
typescriptPath: (0, utils_2.resolveTypescript)(),
|
|
600
|
-
configFile: path.resolve(paths_1.default.
|
|
608
|
+
configFile: path.resolve(paths_1.default.appClient, 'tsconfig.json'),
|
|
601
609
|
diagnosticOptions: {
|
|
602
610
|
syntactic: true,
|
|
603
611
|
},
|
|
@@ -606,19 +614,17 @@ function configurePlugins(options) {
|
|
|
606
614
|
},
|
|
607
615
|
}));
|
|
608
616
|
}
|
|
609
|
-
if (config.
|
|
610
|
-
|
|
617
|
+
if (config.detectCircularDependencies) {
|
|
618
|
+
let circularPluginOptions = {
|
|
619
|
+
exclude: /node_modules/,
|
|
620
|
+
allowAsyncCycles: true,
|
|
621
|
+
};
|
|
622
|
+
if (typeof config.detectCircularDependencies === 'object') {
|
|
623
|
+
circularPluginOptions = config.detectCircularDependencies;
|
|
624
|
+
}
|
|
625
|
+
plugins.push(new circular_dependency_plugin_1.default(circularPluginOptions));
|
|
611
626
|
}
|
|
612
627
|
if (isEnvProduction) {
|
|
613
|
-
plugins.push(new mini_css_extract_plugin_1.default({
|
|
614
|
-
filename: 'css/[name].[contenthash:8].css',
|
|
615
|
-
chunkFilename: 'css/[name].[contenthash:8].chunk.css',
|
|
616
|
-
ignoreOrder: true,
|
|
617
|
-
}));
|
|
618
|
-
if (config.sentryConfig) {
|
|
619
|
-
const sentryPlugin = require('@sentry/webpack-plugin').sentryWebpackPlugin;
|
|
620
|
-
plugins.push(sentryPlugin({ ...config.sentryConfig }));
|
|
621
|
-
}
|
|
622
628
|
if (config.analyzeBundle === 'true') {
|
|
623
629
|
plugins.push(new webpack_bundle_analyzer_1.BundleAnalyzerPlugin({
|
|
624
630
|
openAnalyzer: false,
|
|
@@ -629,8 +635,8 @@ function configurePlugins(options) {
|
|
|
629
635
|
if (config.analyzeBundle === 'statoscope') {
|
|
630
636
|
const customStatoscopeConfig = config.statoscopeConfig || {};
|
|
631
637
|
plugins.push(new webpack_plugin_1.default({
|
|
632
|
-
saveReportTo: path.resolve(
|
|
633
|
-
saveStatsTo: path.resolve(
|
|
638
|
+
saveReportTo: path.resolve(options.buildDirectory, 'report.html'),
|
|
639
|
+
saveStatsTo: path.resolve(options.buildDirectory, 'stats.json'),
|
|
634
640
|
open: false,
|
|
635
641
|
statsOptions: {
|
|
636
642
|
all: true,
|
|
@@ -639,50 +645,102 @@ function configurePlugins(options) {
|
|
|
639
645
|
}));
|
|
640
646
|
}
|
|
641
647
|
}
|
|
642
|
-
if (
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
648
|
+
if (isEnvProduction || isSsr) {
|
|
649
|
+
plugins.push(new mini_css_extract_plugin_1.default({
|
|
650
|
+
filename: 'css/[name].[contenthash:8].css',
|
|
651
|
+
chunkFilename: 'css/[name].[contenthash:8].chunk.css',
|
|
652
|
+
ignoreOrder: true,
|
|
653
|
+
}));
|
|
654
|
+
}
|
|
655
|
+
if (config.monaco) {
|
|
656
|
+
const MonacoEditorWebpackPlugin = require('monaco-editor-webpack-plugin');
|
|
657
|
+
plugins.push(new MonacoEditorWebpackPlugin({
|
|
658
|
+
filename: isEnvProduction ? '[name].[hash:8].worker.js' : undefined,
|
|
659
|
+
...config.monaco,
|
|
660
|
+
// currently, workers located on cdn are not working properly, so we are enforcing loading workers from
|
|
661
|
+
// service instead
|
|
662
|
+
publicPath: path.normalize(config.publicPathPrefix + '/build/'),
|
|
663
|
+
}));
|
|
664
|
+
}
|
|
665
|
+
if (!isSsr) {
|
|
666
|
+
const contextReplacement = config.contextReplacement || {};
|
|
667
|
+
plugins.push(createMomentTimezoneDataPlugin(config.momentTz));
|
|
668
|
+
plugins.push(new webpack.ContextReplacementPlugin(/moment[\\/]locale$/,
|
|
669
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
670
|
+
new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})$`)));
|
|
671
|
+
plugins.push(new webpack.ContextReplacementPlugin(/dayjs[\\/]locale$/,
|
|
672
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
673
|
+
new RegExp(`^\\./(${(contextReplacement.locale || ['ru']).join('|')})\\.js$`)));
|
|
674
|
+
if (contextReplacement['highlight.js']) {
|
|
675
|
+
plugins.push(new webpack.ContextReplacementPlugin(/highlight\.js[\\/]lib[\\/]languages$/,
|
|
676
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
677
|
+
new RegExp(`^\\./(${contextReplacement['highlight.js'].join('|')})$`)));
|
|
649
678
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
679
|
+
if (isEnvDevelopment && config.reactRefresh !== false) {
|
|
680
|
+
const { webSocketPath = path.normalize(`/${config.publicPathPrefix}/build/sockjs-node`), } = config.devServer || {};
|
|
681
|
+
plugins.push(new react_refresh_webpack_plugin_1.default(config.reactRefresh({
|
|
682
|
+
overlay: { sockPath: webSocketPath },
|
|
683
|
+
exclude: [/node_modules/, /\.worker\.[jt]sx?$/],
|
|
684
|
+
})));
|
|
685
|
+
}
|
|
686
|
+
if (config.polyfill?.process) {
|
|
687
|
+
plugins.push(new webpack.ProvidePlugin({ process: 'process/browser.js' }));
|
|
688
|
+
}
|
|
689
|
+
if (isEnvProduction) {
|
|
690
|
+
if (config.sentryConfig) {
|
|
691
|
+
const sentryPlugin = require('@sentry/webpack-plugin').sentryWebpackPlugin;
|
|
692
|
+
plugins.push(sentryPlugin({ ...config.sentryConfig }));
|
|
655
693
|
}
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
if (
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
694
|
+
}
|
|
695
|
+
if (config.cdn) {
|
|
696
|
+
let credentialsGlobal;
|
|
697
|
+
if (process.env.FRONTEND_S3_ACCESS_KEY_ID &&
|
|
698
|
+
process.env.FRONTEND_S3_SECRET_ACCESS_KEY) {
|
|
699
|
+
credentialsGlobal = {
|
|
700
|
+
accessKeyId: process.env.FRONTEND_S3_ACCESS_KEY_ID,
|
|
701
|
+
secretAccessKey: process.env.FRONTEND_S3_SECRET_ACCESS_KEY,
|
|
663
702
|
};
|
|
664
703
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
704
|
+
const cdns = Array.isArray(config.cdn) ? config.cdn : [config.cdn];
|
|
705
|
+
for (let index = 0; index < cdns.length; index++) {
|
|
706
|
+
const cdn = cdns[index];
|
|
707
|
+
if (!cdn) {
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
let credentials = credentialsGlobal;
|
|
711
|
+
const accessKeyId = process.env[`FRONTEND_S3_ACCESS_KEY_ID_${index}`];
|
|
712
|
+
const secretAccessKey = process.env[`FRONTEND_S3_SECRET_ACCESS_KEY_${index}`];
|
|
713
|
+
if (accessKeyId && secretAccessKey) {
|
|
714
|
+
credentials = {
|
|
715
|
+
accessKeyId,
|
|
716
|
+
secretAccessKey,
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
plugins.push(new s3_upload_1.S3UploadPlugin({
|
|
720
|
+
exclude: config.hiddenSourceMap ? /\.map$/ : undefined,
|
|
721
|
+
compress: cdn.compress,
|
|
722
|
+
s3ClientOptions: {
|
|
723
|
+
region: cdn.region,
|
|
724
|
+
endpoint: cdn.endpoint,
|
|
725
|
+
credentials,
|
|
726
|
+
},
|
|
727
|
+
s3UploadOptions: {
|
|
728
|
+
bucket: cdn.bucket,
|
|
729
|
+
targetPath: cdn.prefix,
|
|
730
|
+
cacheControl: cdn.cacheControl,
|
|
731
|
+
},
|
|
732
|
+
additionalPattern: cdn.additionalPattern,
|
|
733
|
+
logger: options.logger,
|
|
734
|
+
}));
|
|
735
|
+
}
|
|
681
736
|
}
|
|
682
737
|
}
|
|
683
738
|
return plugins;
|
|
684
739
|
}
|
|
685
|
-
function configureOptimization({ config }) {
|
|
740
|
+
function configureOptimization({ config, isSsr }) {
|
|
741
|
+
if (isSsr) {
|
|
742
|
+
return {};
|
|
743
|
+
}
|
|
686
744
|
const configVendors = config.vendors ?? [];
|
|
687
745
|
let vendorsList = [
|
|
688
746
|
'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,13 +50,21 @@ 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
|
else {
|
|
58
59
|
logger.success(`Client was successfully compiled`);
|
|
59
60
|
}
|
|
61
|
+
if (ssrStats) {
|
|
62
|
+
const time = ssrStats.endTime - ssrStats.startTime;
|
|
63
|
+
logger.success(`SSR: Client was successfully compiled in ${(0, pretty_time_1.prettyTime)(BigInt(time) * BigInt(1_000_000))}`);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
logger.success(`SSR: Client was successfully compiled`);
|
|
67
|
+
}
|
|
60
68
|
};
|
|
61
69
|
}
|
|
62
70
|
const endStarRe = /\/?\*$/;
|
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.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",
|
|
@@ -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",
|