@tramvai/cli 7.5.3 → 7.11.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/lib/api/build/providers/shared.d.ts.map +1 -1
- package/lib/api/build/providers/shared.js +11 -1
- package/lib/api/build/providers/shared.js.map +1 -1
- package/lib/api/start/application.d.ts.map +1 -1
- package/lib/api/start/application.js +13 -4
- package/lib/api/start/application.js.map +1 -1
- package/lib/api/start/providers/application/shared.d.ts.map +1 -1
- package/lib/api/start/providers/application/shared.js +4 -1
- package/lib/api/start/providers/application/shared.js.map +1 -1
- package/lib/api/start/providers/shared.d.ts.map +1 -1
- package/lib/api/start/providers/shared.js +8 -0
- package/lib/api/start/providers/shared.js.map +1 -1
- package/lib/api/start-prod/providers/application.d.ts.map +1 -1
- package/lib/api/start-prod/providers/application.js +4 -1
- package/lib/api/start-prod/providers/application.js.map +1 -1
- package/lib/api/start-prod/providers/shared.d.ts.map +1 -1
- package/lib/api/start-prod/providers/shared.js +8 -0
- package/lib/api/start-prod/providers/shared.js.map +1 -1
- package/lib/builder/webpack/devServer/pool/process/pool.d.ts.map +1 -1
- package/lib/builder/webpack/devServer/pool/process/pool.js +1 -0
- package/lib/builder/webpack/devServer/pool/process/pool.js.map +1 -1
- package/lib/builder/webpack/devServer/pool/thread/pool.d.ts.map +1 -1
- package/lib/builder/webpack/devServer/pool/thread/pool.js +1 -0
- package/lib/builder/webpack/devServer/pool/thread/pool.js.map +1 -1
- package/lib/builder/webpack/providers/build/client.d.ts.map +1 -1
- package/lib/builder/webpack/providers/build/client.js +3 -1
- package/lib/builder/webpack/providers/build/client.js.map +1 -1
- package/lib/builder/webpack/providers/build/clientShared.d.ts.map +1 -1
- package/lib/builder/webpack/providers/build/clientShared.js +7 -2
- package/lib/builder/webpack/providers/build/clientShared.js.map +1 -1
- package/lib/builder/webpack/providers/build/server.d.ts.map +1 -1
- package/lib/builder/webpack/providers/build/server.js +7 -2
- package/lib/builder/webpack/providers/build/server.js.map +1 -1
- package/lib/builder/webpack/providers/shared.d.ts.map +1 -1
- package/lib/builder/webpack/providers/shared.js.map +1 -1
- package/lib/builder/webpack/providers/start/shared.d.ts.map +1 -1
- package/lib/builder/webpack/providers/start/shared.js +17 -0
- package/lib/builder/webpack/providers/start/shared.js.map +1 -1
- package/lib/builder/webpack/tokens.d.ts +7 -0
- package/lib/builder/webpack/tokens.d.ts.map +1 -1
- package/lib/builder/webpack/tokens.js +2 -1
- package/lib/builder/webpack/tokens.js.map +1 -1
- package/lib/cli/index.d.ts.map +1 -1
- package/lib/cli/index.js +1 -0
- package/lib/cli/index.js.map +1 -1
- package/lib/commands/static/generate.d.ts +9 -1
- package/lib/commands/static/generate.d.ts.map +1 -1
- package/lib/commands/static/generate.js +67 -19
- package/lib/commands/static/generate.js.map +1 -1
- package/lib/commands/update/update.d.ts.map +1 -1
- package/lib/commands/update/update.js +1 -0
- package/lib/commands/update/update.js.map +1 -1
- package/lib/config/configManager.d.ts +3 -0
- package/lib/config/configManager.d.ts.map +1 -1
- package/lib/config/configManager.js +8 -0
- package/lib/config/configManager.js.map +1 -1
- package/lib/di/tokens/config.d.ts +2 -0
- package/lib/di/tokens/config.d.ts.map +1 -1
- package/lib/library/webpack/blocks/configToEnv.d.ts.map +1 -1
- package/lib/library/webpack/blocks/configToEnv.js +5 -1
- package/lib/library/webpack/blocks/configToEnv.js.map +1 -1
- package/lib/utils/dev-app/request.d.ts +3 -0
- package/lib/utils/dev-app/request.d.ts.map +1 -1
- package/lib/utils/dev-app/request.js +11 -1
- package/lib/utils/dev-app/request.js.map +1 -1
- package/lib/utils/tramvaiVersions.d.ts.map +1 -1
- package/lib/utils/tramvaiVersions.js +1 -0
- package/lib/utils/tramvaiVersions.js.map +1 -1
- package/package.json +9 -8
- package/src/api/build/providers/shared.ts +11 -1
- package/src/api/start/application.ts +16 -4
- package/src/api/start/providers/application/shared.ts +4 -1
- package/src/api/start/providers/shared.ts +8 -0
- package/src/api/start-prod/providers/application.ts +4 -1
- package/src/api/start-prod/providers/shared.ts +8 -0
- package/src/builder/webpack/devServer/pool/process/pool.ts +1 -0
- package/src/builder/webpack/devServer/pool/thread/pool.ts +1 -0
- package/src/builder/webpack/providers/build/client.ts +4 -1
- package/src/builder/webpack/providers/build/clientShared.ts +10 -3
- package/src/builder/webpack/providers/build/server.ts +9 -3
- package/src/builder/webpack/providers/shared.ts +1 -0
- package/src/builder/webpack/providers/start/shared.ts +19 -0
- package/src/builder/webpack/tokens.ts +2 -0
- package/src/cli/index.ts +1 -0
- package/src/commands/static/generate.ts +96 -22
- package/src/commands/update/update.ts +2 -0
- package/src/config/configManager.ts +11 -0
- package/src/library/webpack/blocks/configToEnv.ts +4 -1
- package/src/utils/dev-app/request.ts +16 -0
- package/src/utils/tramvaiVersions.ts +1 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { Provider } from '@tinkoff/dippy';
|
|
2
2
|
import { provide } from '@tinkoff/dippy';
|
|
3
|
+
import { nanoid } from 'nanoid';
|
|
3
4
|
import { STRICT_ERROR_HANDLE } from '../tokens';
|
|
4
5
|
import { COMMAND_PARAMETERS_TOKEN } from '../../../di/tokens';
|
|
5
6
|
import type { Params } from '../index';
|
|
7
|
+
import { BUILD_ID_TOKEN } from '../../../builder/webpack/tokens';
|
|
6
8
|
|
|
7
9
|
export const sharedProviders: readonly Provider[] = [
|
|
8
10
|
provide({
|
|
@@ -14,4 +16,10 @@ export const sharedProviders: readonly Provider[] = [
|
|
|
14
16
|
parameters: COMMAND_PARAMETERS_TOKEN,
|
|
15
17
|
},
|
|
16
18
|
}),
|
|
19
|
+
provide({
|
|
20
|
+
provide: BUILD_ID_TOKEN,
|
|
21
|
+
useFactory: () => {
|
|
22
|
+
return nanoid();
|
|
23
|
+
},
|
|
24
|
+
}),
|
|
17
25
|
] as const;
|
|
@@ -18,6 +18,7 @@ import type { ConfigManager } from '../../../config/configManager';
|
|
|
18
18
|
import { createConfigManager } from '../../../config/configManager';
|
|
19
19
|
import { selfSignedCertificateProvider } from '../../shared/providers/selfSignedCertificateProvider';
|
|
20
20
|
import { createServer } from '../../start/utils/createServer';
|
|
21
|
+
import { BUILD_ID_TOKEN } from '../../../builder/webpack/tokens';
|
|
21
22
|
|
|
22
23
|
export const applicationsProviders: readonly Provider[] = [
|
|
23
24
|
...selfSignedCertificateProvider,
|
|
@@ -35,8 +36,9 @@ export const applicationsProviders: readonly Provider[] = [
|
|
|
35
36
|
}),
|
|
36
37
|
provide({
|
|
37
38
|
provide: CONFIG_MANAGER_TOKEN,
|
|
38
|
-
useFactory: ({ configEntry, parameters, portManager }) =>
|
|
39
|
+
useFactory: ({ configEntry, parameters, portManager, buildId }) =>
|
|
39
40
|
createConfigManager(configEntry as ApplicationConfigEntry, {
|
|
41
|
+
buildId,
|
|
40
42
|
...parameters,
|
|
41
43
|
appEnv: parameters.env,
|
|
42
44
|
env: 'production',
|
|
@@ -48,6 +50,7 @@ export const applicationsProviders: readonly Provider[] = [
|
|
|
48
50
|
configEntry: CONFIG_ENTRY_TOKEN,
|
|
49
51
|
parameters: COMMAND_PARAMETERS_TOKEN,
|
|
50
52
|
portManager: PORT_MANAGER_TOKEN,
|
|
53
|
+
buildId: BUILD_ID_TOKEN,
|
|
51
54
|
},
|
|
52
55
|
}),
|
|
53
56
|
provide({
|
|
@@ -4,11 +4,13 @@ import fastify from 'fastify';
|
|
|
4
4
|
import fastifyCompress from '@fastify/compress';
|
|
5
5
|
import fastifyStatic from '@fastify/static';
|
|
6
6
|
import zlib from 'zlib';
|
|
7
|
+
import { nanoid } from 'nanoid';
|
|
7
8
|
import { CLOSE_HANDLER_TOKEN, INIT_HANDLER_TOKEN, PROCESS_HANDLER_TOKEN } from '../tokens';
|
|
8
9
|
import { CONFIG_MANAGER_TOKEN, PORT_MANAGER_TOKEN, STATIC_SERVER_TOKEN } from '../../../di/tokens';
|
|
9
10
|
import { stopServer } from '../../start/utils/stopServer';
|
|
10
11
|
import { listenServer } from '../../start/utils/listenServer';
|
|
11
12
|
import { isApplication, isChildApp } from '../../../config/validate';
|
|
13
|
+
import { BUILD_ID_TOKEN } from '../../../builder/webpack/tokens';
|
|
12
14
|
|
|
13
15
|
export const sharedProviders: readonly Provider[] = [
|
|
14
16
|
provide({
|
|
@@ -89,4 +91,10 @@ export const sharedProviders: readonly Provider[] = [
|
|
|
89
91
|
portManager: PORT_MANAGER_TOKEN,
|
|
90
92
|
},
|
|
91
93
|
}),
|
|
94
|
+
provide({
|
|
95
|
+
provide: BUILD_ID_TOKEN,
|
|
96
|
+
useFactory: () => {
|
|
97
|
+
return nanoid();
|
|
98
|
+
},
|
|
99
|
+
}),
|
|
92
100
|
] as const;
|
|
@@ -41,6 +41,7 @@ export const ProcessWorkerBridge: WorkerBridgeFactory<Worker> = (di) => {
|
|
|
41
41
|
// https://nodejs.org/dist/latest-v15.x/docs/api/all.html#cluster_how_it_works
|
|
42
42
|
PORT: `${configManager.port}`,
|
|
43
43
|
PORT_SERVER: `${configManager.port}`,
|
|
44
|
+
HOST: `${configManager.host}`,
|
|
44
45
|
HOST_STATIC: `${configManager.staticHost}`,
|
|
45
46
|
PORT_STATIC: `${configManager.staticPort}`,
|
|
46
47
|
TRAMVAI_CLI_WATCH_INITIAL_BUILD: firstWorker,
|
|
@@ -39,6 +39,7 @@ export const ThreadWorkerBridge: WorkerBridgeFactory<Worker> = (di) => {
|
|
|
39
39
|
// https://nodejs.org/dist/latest-v15.x/docs/api/all.html#cluster_how_it_works
|
|
40
40
|
PORT: `${configManager.port}`,
|
|
41
41
|
PORT_SERVER: `${configManager.port}`,
|
|
42
|
+
HOST: `${configManager.host}`,
|
|
42
43
|
HOST_STATIC: `${configManager.staticHost}`,
|
|
43
44
|
PORT_STATIC: `${configManager.staticPort}`,
|
|
44
45
|
TRAMVAI_CLI_WATCH_INITIAL_BUILD: firstWorker,
|
|
@@ -3,6 +3,7 @@ import { DI_TOKEN, provide } from '@tinkoff/dippy';
|
|
|
3
3
|
import { COMMAND_PARAMETERS_TOKEN, CONFIG_MANAGER_TOKEN } from '../../../../di/tokens';
|
|
4
4
|
import { toWebpackConfig } from '../../../../library/webpack/utils/toWebpackConfig';
|
|
5
5
|
import {
|
|
6
|
+
BUILD_ID_TOKEN,
|
|
6
7
|
CLIENT_CONFIG_MANAGER_TOKEN,
|
|
7
8
|
CLOSE_HANDLER_TOKEN,
|
|
8
9
|
PROCESS_HANDLER_TOKEN,
|
|
@@ -17,13 +18,15 @@ import { createCompiler } from '../../utils/compiler';
|
|
|
17
18
|
export const buildClientProviders: Provider[] = [
|
|
18
19
|
provide({
|
|
19
20
|
provide: CLIENT_CONFIG_MANAGER_TOKEN,
|
|
20
|
-
useFactory: ({ configManager }) => {
|
|
21
|
+
useFactory: ({ configManager, buildId }) => {
|
|
21
22
|
return configManager.withSettings({
|
|
22
23
|
buildType: 'client',
|
|
24
|
+
buildId,
|
|
23
25
|
});
|
|
24
26
|
},
|
|
25
27
|
deps: {
|
|
26
28
|
configManager: CONFIG_MANAGER_TOKEN,
|
|
29
|
+
buildId: BUILD_ID_TOKEN,
|
|
27
30
|
},
|
|
28
31
|
}),
|
|
29
32
|
provide({
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import type { Provider } from '@tinkoff/dippy';
|
|
2
2
|
import { optional } from '@tinkoff/dippy';
|
|
3
3
|
import { provide } from '@tinkoff/dippy';
|
|
4
|
-
import
|
|
4
|
+
import rimrafCb from 'rimraf';
|
|
5
|
+
import { promisify } from 'util';
|
|
6
|
+
|
|
5
7
|
import { CLI_PACKAGE_MANAGER, CLI_ROOT_DIR_TOKEN } from '../../../../di/tokens';
|
|
6
8
|
import { npmRequire } from '../../../../utils/npmRequire';
|
|
7
9
|
import { CLIENT_CONFIG_MANAGER_TOKEN, INIT_HANDLER_TOKEN } from '../../tokens';
|
|
8
10
|
|
|
11
|
+
const rimraf = promisify(rimrafCb);
|
|
12
|
+
|
|
9
13
|
export const buildClientSharedProviders: Provider[] = [
|
|
10
14
|
provide({
|
|
11
15
|
provide: INIT_HANDLER_TOKEN,
|
|
12
16
|
multi: true,
|
|
13
17
|
useFactory: ({ configManager }) => {
|
|
14
|
-
return function clearBuildDir() {
|
|
15
|
-
|
|
18
|
+
return async function clearBuildDir() {
|
|
19
|
+
await Promise.all([
|
|
20
|
+
rimraf(`${configManager.buildPath}/**`),
|
|
21
|
+
configManager.prerenderPagesPath && rimraf(`${configManager.prerenderPagesPath}/**`),
|
|
22
|
+
]);
|
|
16
23
|
};
|
|
17
24
|
},
|
|
18
25
|
deps: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Provider } from '@tinkoff/dippy';
|
|
2
2
|
import { DI_TOKEN, provide } from '@tinkoff/dippy';
|
|
3
|
-
import
|
|
3
|
+
import rimrafCb from 'rimraf';
|
|
4
|
+
import { promisify } from 'util';
|
|
4
5
|
import { toWebpackConfig } from '../../../../library/webpack/utils/toWebpackConfig';
|
|
5
6
|
import { CONFIG_MANAGER_TOKEN } from '../../../../di/tokens';
|
|
6
7
|
import {
|
|
@@ -17,6 +18,8 @@ import { closeWebpack } from '../../utils/closeWebpack';
|
|
|
17
18
|
import { runWebpack } from '../../utils/runWebpack';
|
|
18
19
|
import { createCompiler } from '../../utils/compiler';
|
|
19
20
|
|
|
21
|
+
const rimraf = promisify(rimrafCb);
|
|
22
|
+
|
|
20
23
|
export const buildServerProviders: Provider[] = [
|
|
21
24
|
provide({
|
|
22
25
|
provide: WEBPACK_SERVER_COMPILER_TOKEN,
|
|
@@ -40,8 +43,11 @@ export const buildServerProviders: Provider[] = [
|
|
|
40
43
|
provide: INIT_HANDLER_TOKEN,
|
|
41
44
|
multi: true,
|
|
42
45
|
useFactory: ({ configManager }) => {
|
|
43
|
-
return function clearBuildDir() {
|
|
44
|
-
|
|
46
|
+
return async function clearBuildDir() {
|
|
47
|
+
await Promise.all([
|
|
48
|
+
rimraf(`${configManager.buildPath}/**`),
|
|
49
|
+
configManager.prerenderPagesPath && rimraf(`${configManager.prerenderPagesPath}/**`),
|
|
50
|
+
]);
|
|
45
51
|
};
|
|
46
52
|
},
|
|
47
53
|
deps: {
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
WEBPACK_SERVER_COMPILER_TOKEN,
|
|
14
14
|
WEBPACK_ANALYZE_PLUGIN_NAME_TOKEN,
|
|
15
15
|
WEBPACK_ANALYZE_PLUGIN_TOKEN,
|
|
16
|
+
BUILD_ID_TOKEN,
|
|
16
17
|
} from '../tokens';
|
|
17
18
|
import { emitWebpackEvents } from '../utils/webpackEvents';
|
|
18
19
|
import { BundleAnalyzePlugin } from '../analyzePlugins/bundle';
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Provider } from '@tinkoff/dippy';
|
|
2
2
|
import { DI_TOKEN, provide } from '@tinkoff/dippy';
|
|
3
3
|
import webpack from 'webpack';
|
|
4
|
+
import rimrafCb from 'rimraf';
|
|
5
|
+
import { promisify } from 'util';
|
|
4
6
|
import { toWebpackConfig } from '../../../../library/webpack/utils/toWebpackConfig';
|
|
5
7
|
import {
|
|
6
8
|
PROCESS_HANDLER_TOKEN,
|
|
@@ -10,10 +12,13 @@ import {
|
|
|
10
12
|
WEBPACK_SERVER_COMPILER_TOKEN,
|
|
11
13
|
WEBPACK_SERVER_CONFIG_TOKEN,
|
|
12
14
|
WEBPACK_ANALYZE_PLUGIN_TOKEN,
|
|
15
|
+
CLOSE_HANDLER_TOKEN,
|
|
13
16
|
} from '../../tokens';
|
|
14
17
|
import { createDevServer } from '../../devServer/setup';
|
|
15
18
|
import { CONFIG_MANAGER_TOKEN, STATIC_SERVER_TOKEN } from '../../../../di/tokens';
|
|
16
19
|
|
|
20
|
+
const rimraf = promisify(rimrafCb);
|
|
21
|
+
|
|
17
22
|
export const startSharedProviders: Provider[] = [
|
|
18
23
|
provide({
|
|
19
24
|
provide: WEBPACK_COMPILER_TOKEN,
|
|
@@ -112,4 +117,18 @@ export const startSharedProviders: Provider[] = [
|
|
|
112
117
|
staticServer: STATIC_SERVER_TOKEN,
|
|
113
118
|
},
|
|
114
119
|
}),
|
|
120
|
+
provide({
|
|
121
|
+
provide: CLOSE_HANDLER_TOKEN,
|
|
122
|
+
multi: true,
|
|
123
|
+
useFactory: ({ configManager }) => {
|
|
124
|
+
return async () => {
|
|
125
|
+
if (configManager.prerenderPagesPath) {
|
|
126
|
+
await rimraf(`${configManager.prerenderPagesPath}/**`);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
deps: {
|
|
131
|
+
configManager: CONFIG_MANAGER_TOKEN,
|
|
132
|
+
},
|
|
133
|
+
}),
|
|
115
134
|
];
|
package/src/cli/index.ts
CHANGED
|
@@ -68,6 +68,7 @@ export async function cliInitialized(cliArgs = process.argv) {
|
|
|
68
68
|
}>('package.json');
|
|
69
69
|
const { content: config } = getTramvaiConfig();
|
|
70
70
|
|
|
71
|
+
// todo: different build id here, can be a problem?
|
|
71
72
|
const configManager = new ConfigManager({ config, syncConfigFile: syncJsonFile });
|
|
72
73
|
const packageManager = resolvePackageManager({ rootDir: process.cwd() });
|
|
73
74
|
|
|
@@ -1,25 +1,39 @@
|
|
|
1
1
|
import { resolve, join } from 'path';
|
|
2
2
|
import PQueue from 'promise-queue';
|
|
3
3
|
import { outputFile } from 'fs-extra';
|
|
4
|
-
import { getHeaders } from '@tinkoff/request-plugin-protocol-http';
|
|
4
|
+
import { getHeader, getHeaders, getStatus } from '@tinkoff/request-plugin-protocol-http';
|
|
5
5
|
import type { Context } from '../../models/context';
|
|
6
6
|
import type { ConfigManager } from '../../config/configManager';
|
|
7
7
|
import type { ApplicationConfigEntry } from '../../typings/configEntry/application';
|
|
8
|
-
import {
|
|
8
|
+
import { appFetch } from '../../utils/dev-app/request';
|
|
9
9
|
import type { Params } from './command';
|
|
10
10
|
|
|
11
11
|
const MAX_CONCURRENT = 10;
|
|
12
12
|
|
|
13
|
+
export interface PrerenderRequest {
|
|
14
|
+
/**
|
|
15
|
+
* Page path, for example, '/product/123/', without query parameters
|
|
16
|
+
*/
|
|
17
|
+
pathname: string;
|
|
18
|
+
headers?: Record<string, string>;
|
|
19
|
+
query?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
export const generateStatic = async (
|
|
14
23
|
context: Context,
|
|
15
24
|
params: Params,
|
|
16
25
|
configManager: ConfigManager<ApplicationConfigEntry>,
|
|
17
|
-
paths: string
|
|
26
|
+
paths: Array<string | PrerenderRequest>
|
|
18
27
|
) => {
|
|
28
|
+
const meta: {
|
|
29
|
+
staticPages: Record<string, any>[];
|
|
30
|
+
} = {
|
|
31
|
+
staticPages: [],
|
|
32
|
+
};
|
|
19
33
|
const { header = [], folder = '' } = params;
|
|
20
34
|
const q = new PQueue(MAX_CONCURRENT);
|
|
21
35
|
const promises = [];
|
|
22
|
-
const
|
|
36
|
+
const baseHeaders = header.reduce(
|
|
23
37
|
(result, item) => {
|
|
24
38
|
const [key, value] = item.split(':');
|
|
25
39
|
|
|
@@ -36,50 +50,110 @@ export const generateStatic = async (
|
|
|
36
50
|
const { rootDir, output } = configManager;
|
|
37
51
|
const staticPath = resolve(rootDir, output.static, folder);
|
|
38
52
|
|
|
39
|
-
for (const
|
|
53
|
+
for (const pathOrRequest of paths) {
|
|
40
54
|
promises.push(
|
|
55
|
+
// eslint-disable-next-line max-statements
|
|
41
56
|
q.add(async () => {
|
|
42
|
-
let response:
|
|
57
|
+
let response: Response;
|
|
58
|
+
|
|
59
|
+
const request: PrerenderRequest =
|
|
60
|
+
typeof pathOrRequest === 'string' ? { pathname: pathOrRequest } : pathOrRequest;
|
|
61
|
+
|
|
62
|
+
const { pathname, headers: requestHeaders = {}, query = {} } = request;
|
|
63
|
+
|
|
64
|
+
const mergedHeaders = {
|
|
65
|
+
...baseHeaders,
|
|
66
|
+
...requestHeaders,
|
|
67
|
+
};
|
|
43
68
|
|
|
44
69
|
try {
|
|
45
70
|
context.logger.event({
|
|
46
71
|
type: 'debug',
|
|
47
72
|
event: 'COMMAND:STATIC:PAGE_FETCH',
|
|
48
|
-
message: `path: ${
|
|
73
|
+
message: `path: ${pathname}, message: start fetching page`,
|
|
74
|
+
payload: {
|
|
75
|
+
headers: mergedHeaders,
|
|
76
|
+
query,
|
|
77
|
+
},
|
|
49
78
|
});
|
|
50
79
|
|
|
51
|
-
response =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
context.logger.event({
|
|
57
|
-
type: 'debug',
|
|
58
|
-
event: 'COMMAND:STATIC:PAGE_CREATED',
|
|
59
|
-
message: `path: ${path}, message: page created successfully`,
|
|
80
|
+
response = await appFetch(configManager, pathname, {
|
|
81
|
+
query,
|
|
82
|
+
headers: mergedHeaders,
|
|
83
|
+
// we need to save raw redirect response status code and headers
|
|
84
|
+
redirect: 'manual',
|
|
60
85
|
});
|
|
61
|
-
} catch (e) {
|
|
62
|
-
const responseHeaders = response ? getHeaders(response) : {};
|
|
63
86
|
|
|
64
|
-
if (
|
|
87
|
+
if (response?.headers?.get('x-tramvai-prerender-skip') === 'true') {
|
|
65
88
|
context.logger.event({
|
|
66
89
|
type: 'debug',
|
|
67
90
|
event: 'COMMAND:STATIC:PAGE_SKIP',
|
|
68
|
-
message: `path: ${
|
|
91
|
+
message: `path: ${pathname}, message: page prerender skipped`,
|
|
92
|
+
payload: {
|
|
93
|
+
headers: mergedHeaders,
|
|
94
|
+
query,
|
|
95
|
+
},
|
|
69
96
|
});
|
|
70
97
|
|
|
71
98
|
return;
|
|
72
99
|
}
|
|
73
100
|
|
|
101
|
+
const keyHeader = response.headers.get('x-tramvai-static-page-key');
|
|
102
|
+
const routeHeader = response.headers.get('x-tramvai-static-page-route');
|
|
103
|
+
const filename = keyHeader ? `index.${keyHeader}.html` : 'index.html';
|
|
104
|
+
const metaFilename = keyHeader ? `index.${keyHeader}.json` : 'index.json';
|
|
105
|
+
const outputPath = join(staticPath, pathname, filename);
|
|
106
|
+
const metaOutputPath = join(staticPath, pathname, metaFilename);
|
|
107
|
+
|
|
108
|
+
if (typeof routeHeader === 'string') {
|
|
109
|
+
const route = JSON.parse(routeHeader);
|
|
110
|
+
|
|
111
|
+
if (
|
|
112
|
+
!meta.staticPages.some((item) => item.name === route.name || item.path === route.path)
|
|
113
|
+
) {
|
|
114
|
+
meta.staticPages.push(route);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
await outputFile(outputPath, await response.text());
|
|
119
|
+
await outputFile(
|
|
120
|
+
metaOutputPath,
|
|
121
|
+
JSON.stringify(
|
|
122
|
+
{
|
|
123
|
+
// @ts-expect-error
|
|
124
|
+
headers: Object.fromEntries(response.headers),
|
|
125
|
+
status: response.status,
|
|
126
|
+
},
|
|
127
|
+
null,
|
|
128
|
+
2
|
|
129
|
+
)
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
context.logger.event({
|
|
133
|
+
type: 'debug',
|
|
134
|
+
event: 'COMMAND:STATIC:PAGE_CREATED',
|
|
135
|
+
message: `path: ${pathname}${keyHeader ? `, key: ${keyHeader}` : ''}, message: page created successfully at ${outputPath}`,
|
|
136
|
+
payload: {
|
|
137
|
+
headers: mergedHeaders,
|
|
138
|
+
query,
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
} catch (e) {
|
|
74
142
|
context.logger.event({
|
|
75
143
|
type: 'error',
|
|
76
144
|
event: 'COMMAND:STATIC:ERROR',
|
|
77
|
-
message: `path: ${
|
|
145
|
+
message: `path: ${pathname}, message: ${e.message}`,
|
|
146
|
+
payload: {
|
|
147
|
+
headers: mergedHeaders,
|
|
148
|
+
query,
|
|
149
|
+
},
|
|
78
150
|
});
|
|
79
151
|
}
|
|
80
152
|
})
|
|
81
153
|
);
|
|
82
154
|
}
|
|
83
155
|
|
|
84
|
-
return Promise.all(promises)
|
|
156
|
+
return Promise.all(promises).then(() => {
|
|
157
|
+
return outputFile(join(staticPath, 'meta.json'), JSON.stringify(meta, null, 2));
|
|
158
|
+
});
|
|
85
159
|
};
|
|
@@ -58,6 +58,8 @@ export default async (
|
|
|
58
58
|
|
|
59
59
|
await context.packageManager.install({ stdio: 'inherit' });
|
|
60
60
|
|
|
61
|
+
// todo если с --tag то для npm надо запустить `npm update --no-save`
|
|
62
|
+
|
|
61
63
|
if (context.packageManager.name !== 'npm') {
|
|
62
64
|
// npm dedupe is extremely slow in most cases
|
|
63
65
|
// so execute it only for yarn
|
|
@@ -5,6 +5,7 @@ import prop from '@tinkoff/utils/object/prop';
|
|
|
5
5
|
import mapObj from '@tinkoff/utils/object/map';
|
|
6
6
|
import { resolve } from 'path';
|
|
7
7
|
import fs from 'fs';
|
|
8
|
+
import { nanoid } from 'nanoid';
|
|
8
9
|
import type { BuildType } from '../typings/projectType';
|
|
9
10
|
import type { Env } from '../typings/Env';
|
|
10
11
|
import type { ConfigEntry, OverridableOption } from '../typings/configEntry/common';
|
|
@@ -25,6 +26,7 @@ export interface Settings<E extends Env> {
|
|
|
25
26
|
rootDir?: string;
|
|
26
27
|
version?: string;
|
|
27
28
|
buildType?: BuildType;
|
|
29
|
+
buildId?: string;
|
|
28
30
|
debug?: string | boolean;
|
|
29
31
|
verboseWebpack?: boolean;
|
|
30
32
|
trace?: boolean;
|
|
@@ -91,8 +93,10 @@ export type ConfigManager<
|
|
|
91
93
|
E extends Env = Env,
|
|
92
94
|
> = OmitOverridable<C> &
|
|
93
95
|
Required<Settings<E>> & {
|
|
96
|
+
buildId: string;
|
|
94
97
|
target: Target;
|
|
95
98
|
buildPath: string;
|
|
99
|
+
prerenderPagesPath?: string;
|
|
96
100
|
withSettings(settings: Settings<E>): ConfigManager<C, E>;
|
|
97
101
|
dehydrate(): [C, Settings<E>];
|
|
98
102
|
assetsPrefix?: string;
|
|
@@ -106,6 +110,7 @@ export const createConfigManager = <C extends ConfigEntry = ConfigEntry, E exten
|
|
|
106
110
|
configEntry: C,
|
|
107
111
|
settings: Settings<E>
|
|
108
112
|
): ConfigManager<C, E> => {
|
|
113
|
+
const buildId = settings.buildId ?? nanoid();
|
|
109
114
|
const env: E = settings.env ?? ('development' as E);
|
|
110
115
|
const normalizedConfigEntry = omitEnvOptions(env, configEntry);
|
|
111
116
|
|
|
@@ -122,6 +127,7 @@ export const createConfigManager = <C extends ConfigEntry = ConfigEntry, E exten
|
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
const config: ConfigManager<C, E> = {
|
|
130
|
+
buildId,
|
|
125
131
|
...normalizedConfigEntry,
|
|
126
132
|
version:
|
|
127
133
|
(type === 'module' ? moduleVersion(configEntry) : '') ||
|
|
@@ -179,6 +185,7 @@ export const createConfigManager = <C extends ConfigEntry = ConfigEntry, E exten
|
|
|
179
185
|
return [
|
|
180
186
|
configEntry,
|
|
181
187
|
{
|
|
188
|
+
buildId,
|
|
182
189
|
...settings,
|
|
183
190
|
// drop options that couldn't be serialized
|
|
184
191
|
stdout: undefined,
|
|
@@ -199,6 +206,10 @@ export const createConfigManager = <C extends ConfigEntry = ConfigEntry, E exten
|
|
|
199
206
|
rootDir,
|
|
200
207
|
buildType === 'server' ? config.output.server : config.output.client
|
|
201
208
|
);
|
|
209
|
+
config.prerenderPagesPath =
|
|
210
|
+
env === 'development'
|
|
211
|
+
? resolve(rootDir, config.output.static, config.buildId)
|
|
212
|
+
: resolve(rootDir, config.output.static);
|
|
202
213
|
|
|
203
214
|
const pwa = config.experiments?.pwa;
|
|
204
215
|
if (pwa.webmanifest?.enabled) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
import type Config from 'webpack-chain';
|
|
2
3
|
import type { ConfigManager } from '../../../config/configManager';
|
|
3
4
|
import { isApplication } from '../../../config/validate';
|
|
@@ -5,12 +6,13 @@ import type { ConfigEntry } from '../../../typings/configEntry/common';
|
|
|
5
6
|
import { shouldUseReactRoot } from '../../../utils/shouldUseReactRoot';
|
|
6
7
|
|
|
7
8
|
export const configToEnv = (configManager: ConfigManager<ConfigEntry>) => (config: Config) => {
|
|
8
|
-
const { fileSystemPages, shared, experiments } = isApplication(configManager)
|
|
9
|
+
const { fileSystemPages, shared, experiments, output } = isApplication(configManager)
|
|
9
10
|
? configManager
|
|
10
11
|
: {
|
|
11
12
|
fileSystemPages: { enabled: false, routesDir: false, pagesDir: false },
|
|
12
13
|
shared: { criticalChunks: [] },
|
|
13
14
|
experiments: {},
|
|
15
|
+
output: { static: 'dist/client' },
|
|
14
16
|
};
|
|
15
17
|
|
|
16
18
|
config.plugin('define').tap((args) => [
|
|
@@ -31,6 +33,7 @@ export const configToEnv = (configManager: ConfigManager<ConfigEntry>) => (confi
|
|
|
31
33
|
'process.env.__TRAMVAI_REACT_TRANSITIONS': `'${JSON.stringify(
|
|
32
34
|
experiments.reactTransitions
|
|
33
35
|
)}'`,
|
|
36
|
+
'process.env.__TRAMVAI_OUTPUT_STATIC': `${JSON.stringify(configManager.env === 'development' ? path.join(output.static, configManager.buildId) : output.static)}`,
|
|
34
37
|
},
|
|
35
38
|
]);
|
|
36
39
|
};
|
|
@@ -14,6 +14,22 @@ export const appRequest = <T>(configManager: ConfigManager, path: string, option
|
|
|
14
14
|
return request<T>({ url: `${serverPath}${path}`, ...options });
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
export const appFetch = (
|
|
18
|
+
configManager: ConfigManager,
|
|
19
|
+
path: string,
|
|
20
|
+
{ query = {}, ...options }: RequestInit & { query?: Record<string, string> } = {}
|
|
21
|
+
) => {
|
|
22
|
+
const { host, port } = configManager;
|
|
23
|
+
const serverPath = `http://${host}:${port}/`;
|
|
24
|
+
const url = new URL(path, serverPath);
|
|
25
|
+
|
|
26
|
+
Object.entries(query).forEach(([key, value]) => {
|
|
27
|
+
url.searchParams.append(key, value);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return fetch(url, options);
|
|
31
|
+
};
|
|
32
|
+
|
|
17
33
|
interface BundleInfoResponse {
|
|
18
34
|
resultCode: string;
|
|
19
35
|
payload: string[];
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// actual version to update will be calculated from the some of the @tramvai/module
|
|
4
4
|
export const DEPENDANT_LIBS_MAP = new Map([
|
|
5
5
|
['@tinkoff/logger', '@tramvai/module-log'],
|
|
6
|
+
['@tinkoff/env-validators', '@tramvai/module-client-hints'],
|
|
6
7
|
['@tinkoff/dippy', '@tramvai/core'],
|
|
7
8
|
['@tinkoff/router', '@tramvai/module-router'],
|
|
8
9
|
['@tinkoff/url', '@tramvai/module-common'],
|