@tramvai/module-render 4.38.0 → 4.39.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.
@@ -13,12 +13,14 @@ export declare class ResourcesInliner implements ResourcesInlinerType {
13
13
  private resourcesRegistryCache;
14
14
  private log;
15
15
  private runningRequests;
16
+ private assetsPrefix;
16
17
  private scheduleFileLoad;
17
18
  private scheduleFileSizeLoad;
18
- constructor({ resourcesRegistryCache, resourceInlineThreshold, logger }: {
19
+ constructor({ resourcesRegistryCache, resourceInlineThreshold, logger, assetsPrefixFactory }: {
19
20
  resourcesRegistryCache: any;
20
21
  resourceInlineThreshold: any;
21
22
  logger: any;
23
+ assetsPrefixFactory: any;
22
24
  });
23
25
  private getFilesCache;
24
26
  shouldAddResource(resource: PageResource): boolean;
@@ -7,10 +7,6 @@ import { processFile } from './fileProcessor.es.js';
7
7
 
8
8
  const INTERNAL_CACHE_SIZE = 50;
9
9
  const TRAMVAI_CLI_ASSETS_PREFIX = `${process.env.TRAMVAI_CLI_ASSETS_PREFIX}`;
10
- const ASSETS_PREFIX = process.env.NODE_ENV === 'development' &&
11
- (process.env.ASSETS_PREFIX === 'static' || !process.env.ASSETS_PREFIX)
12
- ? TRAMVAI_CLI_ASSETS_PREFIX
13
- : process.env.ASSETS_PREFIX;
14
10
  const getInlineType = (type) => {
15
11
  switch (type) {
16
12
  case ResourceType.style:
@@ -21,13 +17,13 @@ const getInlineType = (type) => {
21
17
  return type;
22
18
  }
23
19
  };
24
- const getResourceUrl = (resource) => {
20
+ const getResourceUrl = (resource, assetsPrefix) => {
25
21
  if (isEmpty(resource.payload) || !isAbsoluteUrl(resource.payload)) {
26
22
  return undefined;
27
23
  }
28
24
  let result = resource.payload.startsWith('//') ? `https:${resource.payload}` : resource.payload;
29
- if (process.env.TRAMVAI_CLI_COMMAND === 'static' && result.startsWith(ASSETS_PREFIX)) {
30
- result = result.replace(ASSETS_PREFIX, TRAMVAI_CLI_ASSETS_PREFIX);
25
+ if (process.env.TRAMVAI_CLI_COMMAND === 'static' && result.startsWith(assetsPrefix)) {
26
+ result = result.replace(assetsPrefix, TRAMVAI_CLI_ASSETS_PREFIX);
31
27
  }
32
28
  return result;
33
29
  };
@@ -35,11 +31,11 @@ const removeSourceMapFromString = (file) => {
35
31
  return file.replace(/(\n\/\/# sourceMappingURL=.*)/g, '');
36
32
  };
37
33
  class ResourcesInliner {
38
- constructor({ resourcesRegistryCache, resourceInlineThreshold, logger }) {
34
+ constructor({ resourcesRegistryCache, resourceInlineThreshold, logger, assetsPrefixFactory }) {
39
35
  this.internalFilesCache = new Map();
40
36
  this.runningRequests = new Set();
41
37
  this.scheduleFileLoad = async (resource, resourceInlineThreshold) => {
42
- const url = getResourceUrl(resource);
38
+ const url = getResourceUrl(resource, this.assetsPrefix);
43
39
  const requestKey = `file${url}`;
44
40
  const filesCache = this.getFilesCache(url);
45
41
  const result = filesCache.get(url);
@@ -73,7 +69,7 @@ class ResourcesInliner {
73
69
  }
74
70
  };
75
71
  this.scheduleFileSizeLoad = async (resource, resourceInlineThreshold, waitForFileLoad) => {
76
- const url = getResourceUrl(resource);
72
+ const url = getResourceUrl(resource, this.assetsPrefix);
77
73
  const requestKey = `size${url}`;
78
74
  const result = this.resourcesRegistryCache.sizeCache.get(url);
79
75
  if (result) {
@@ -112,9 +108,14 @@ class ResourcesInliner {
112
108
  this.resourcesRegistryCache = resourcesRegistryCache;
113
109
  this.resourceInlineThreshold = resourceInlineThreshold;
114
110
  this.log = logger('resources-inliner');
111
+ const assetsPrefix = assetsPrefixFactory();
112
+ this.assetsPrefix =
113
+ process.env.NODE_ENV === 'development' && (assetsPrefix === 'static' || !assetsPrefix)
114
+ ? TRAMVAI_CLI_ASSETS_PREFIX
115
+ : assetsPrefix;
115
116
  }
116
117
  getFilesCache(url) {
117
- if (url.startsWith(ASSETS_PREFIX) ||
118
+ if (url.startsWith(this.assetsPrefix) ||
118
119
  // reverse logic for `static` command in `getResourceUrl` method
119
120
  (process.env.TRAMVAI_CLI_COMMAND === 'static' && url.startsWith(TRAMVAI_CLI_ASSETS_PREFIX))) {
120
121
  // internal resources are resources generated by the current app itself
@@ -130,7 +131,7 @@ class ResourcesInliner {
130
131
  // only checking preload-links
131
132
  return true;
132
133
  }
133
- const url = getResourceUrl(resource);
134
+ const url = getResourceUrl(resource, this.assetsPrefix);
134
135
  if (isUndefined(url)) {
135
136
  // if url is undefined that file is not in cache
136
137
  return true;
@@ -148,7 +149,7 @@ class ResourcesInliner {
148
149
  if (isUndefined(resourceInlineThreshold)) {
149
150
  return false;
150
151
  }
151
- const url = getResourceUrl(resource);
152
+ const url = getResourceUrl(resource, this.assetsPrefix);
152
153
  if (isUndefined(url) || this.resourcesRegistryCache.disabledUrlsCache.has(url)) {
153
154
  return false;
154
155
  }
@@ -181,7 +182,7 @@ class ResourcesInliner {
181
182
  return true;
182
183
  }
183
184
  inlineResource(resource) {
184
- const url = getResourceUrl(resource);
185
+ const url = getResourceUrl(resource, this.assetsPrefix);
185
186
  if (isUndefined(url)) {
186
187
  // usually, it should not happen but anyway check it for safety
187
188
  return [resource];
@@ -221,7 +222,7 @@ class ResourcesInliner {
221
222
  return result;
222
223
  }
223
224
  async prefetchResource(resource) {
224
- const url = getResourceUrl(resource);
225
+ const url = getResourceUrl(resource, this.assetsPrefix);
225
226
  const resourceInlineThreshold = this.resourceInlineThreshold.threshold;
226
227
  if (isUndefined(url) ||
227
228
  isUndefined(resourceInlineThreshold) ||
@@ -16,10 +16,6 @@ var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
16
16
 
17
17
  const INTERNAL_CACHE_SIZE = 50;
18
18
  const TRAMVAI_CLI_ASSETS_PREFIX = `${process.env.TRAMVAI_CLI_ASSETS_PREFIX}`;
19
- const ASSETS_PREFIX = process.env.NODE_ENV === 'development' &&
20
- (process.env.ASSETS_PREFIX === 'static' || !process.env.ASSETS_PREFIX)
21
- ? TRAMVAI_CLI_ASSETS_PREFIX
22
- : process.env.ASSETS_PREFIX;
23
19
  const getInlineType = (type) => {
24
20
  switch (type) {
25
21
  case tokensRender.ResourceType.style:
@@ -30,13 +26,13 @@ const getInlineType = (type) => {
30
26
  return type;
31
27
  }
32
28
  };
33
- const getResourceUrl = (resource) => {
29
+ const getResourceUrl = (resource, assetsPrefix) => {
34
30
  if (isEmpty__default["default"](resource.payload) || !url.isAbsoluteUrl(resource.payload)) {
35
31
  return undefined;
36
32
  }
37
33
  let result = resource.payload.startsWith('//') ? `https:${resource.payload}` : resource.payload;
38
- if (process.env.TRAMVAI_CLI_COMMAND === 'static' && result.startsWith(ASSETS_PREFIX)) {
39
- result = result.replace(ASSETS_PREFIX, TRAMVAI_CLI_ASSETS_PREFIX);
34
+ if (process.env.TRAMVAI_CLI_COMMAND === 'static' && result.startsWith(assetsPrefix)) {
35
+ result = result.replace(assetsPrefix, TRAMVAI_CLI_ASSETS_PREFIX);
40
36
  }
41
37
  return result;
42
38
  };
@@ -44,11 +40,11 @@ const removeSourceMapFromString = (file) => {
44
40
  return file.replace(/(\n\/\/# sourceMappingURL=.*)/g, '');
45
41
  };
46
42
  class ResourcesInliner {
47
- constructor({ resourcesRegistryCache, resourceInlineThreshold, logger }) {
43
+ constructor({ resourcesRegistryCache, resourceInlineThreshold, logger, assetsPrefixFactory }) {
48
44
  this.internalFilesCache = new Map();
49
45
  this.runningRequests = new Set();
50
46
  this.scheduleFileLoad = async (resource, resourceInlineThreshold) => {
51
- const url = getResourceUrl(resource);
47
+ const url = getResourceUrl(resource, this.assetsPrefix);
52
48
  const requestKey = `file${url}`;
53
49
  const filesCache = this.getFilesCache(url);
54
50
  const result = filesCache.get(url);
@@ -82,7 +78,7 @@ class ResourcesInliner {
82
78
  }
83
79
  };
84
80
  this.scheduleFileSizeLoad = async (resource, resourceInlineThreshold, waitForFileLoad) => {
85
- const url = getResourceUrl(resource);
81
+ const url = getResourceUrl(resource, this.assetsPrefix);
86
82
  const requestKey = `size${url}`;
87
83
  const result = this.resourcesRegistryCache.sizeCache.get(url);
88
84
  if (result) {
@@ -121,9 +117,14 @@ class ResourcesInliner {
121
117
  this.resourcesRegistryCache = resourcesRegistryCache;
122
118
  this.resourceInlineThreshold = resourceInlineThreshold;
123
119
  this.log = logger('resources-inliner');
120
+ const assetsPrefix = assetsPrefixFactory();
121
+ this.assetsPrefix =
122
+ process.env.NODE_ENV === 'development' && (assetsPrefix === 'static' || !assetsPrefix)
123
+ ? TRAMVAI_CLI_ASSETS_PREFIX
124
+ : assetsPrefix;
124
125
  }
125
126
  getFilesCache(url) {
126
- if (url.startsWith(ASSETS_PREFIX) ||
127
+ if (url.startsWith(this.assetsPrefix) ||
127
128
  // reverse logic for `static` command in `getResourceUrl` method
128
129
  (process.env.TRAMVAI_CLI_COMMAND === 'static' && url.startsWith(TRAMVAI_CLI_ASSETS_PREFIX))) {
129
130
  // internal resources are resources generated by the current app itself
@@ -139,7 +140,7 @@ class ResourcesInliner {
139
140
  // only checking preload-links
140
141
  return true;
141
142
  }
142
- const url = getResourceUrl(resource);
143
+ const url = getResourceUrl(resource, this.assetsPrefix);
143
144
  if (isUndefined__default["default"](url)) {
144
145
  // if url is undefined that file is not in cache
145
146
  return true;
@@ -157,7 +158,7 @@ class ResourcesInliner {
157
158
  if (isUndefined__default["default"](resourceInlineThreshold)) {
158
159
  return false;
159
160
  }
160
- const url = getResourceUrl(resource);
161
+ const url = getResourceUrl(resource, this.assetsPrefix);
161
162
  if (isUndefined__default["default"](url) || this.resourcesRegistryCache.disabledUrlsCache.has(url)) {
162
163
  return false;
163
164
  }
@@ -190,7 +191,7 @@ class ResourcesInliner {
190
191
  return true;
191
192
  }
192
193
  inlineResource(resource) {
193
- const url = getResourceUrl(resource);
194
+ const url = getResourceUrl(resource, this.assetsPrefix);
194
195
  if (isUndefined__default["default"](url)) {
195
196
  // usually, it should not happen but anyway check it for safety
196
197
  return [resource];
@@ -230,7 +231,7 @@ class ResourcesInliner {
230
231
  return result;
231
232
  }
232
233
  async prefetchResource(resource) {
233
- const url = getResourceUrl(resource);
234
+ const url = getResourceUrl(resource, this.assetsPrefix);
234
235
  const resourceInlineThreshold = this.resourceInlineThreshold.threshold;
235
236
  if (isUndefined__default["default"](url) ||
236
237
  isUndefined__default["default"](resourceInlineThreshold) ||
@@ -15,7 +15,8 @@ export declare class PageBuilder {
15
15
  private fetchWebpackStats;
16
16
  private di;
17
17
  private renderMode;
18
- constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, di, renderMode, }: {
18
+ private assetsPrefixFactory;
19
+ constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, di, renderMode, assetsPrefixFactory, }: {
19
20
  renderSlots: any;
20
21
  pageService: any;
21
22
  resourcesRegistry: any;
@@ -30,6 +31,7 @@ export declare class PageBuilder {
30
31
  fetchWebpackStats: any;
31
32
  di: any;
32
33
  renderMode: any;
34
+ assetsPrefixFactory: any;
33
35
  });
34
36
  flow(): Promise<string>;
35
37
  dehydrateState(): void;
@@ -20,7 +20,7 @@ const mapResourcesToSlots = (resources) => resources.reduce((acc, resource) => {
20
20
  return acc;
21
21
  }, {});
22
22
  class PageBuilder {
23
- constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, di, renderMode, }) {
23
+ constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, di, renderMode, assetsPrefixFactory, }) {
24
24
  this.htmlAttrs = htmlAttrs;
25
25
  this.renderSlots = flatten(renderSlots || []);
26
26
  this.pageService = pageService;
@@ -35,6 +35,7 @@ class PageBuilder {
35
35
  this.fetchWebpackStats = fetchWebpackStats;
36
36
  this.di = di;
37
37
  this.renderMode = renderMode;
38
+ this.assetsPrefixFactory = assetsPrefixFactory;
38
39
  }
39
40
  async flow() {
40
41
  const stats = await this.fetchWebpackStats({ modern: this.modern });
@@ -84,6 +85,7 @@ class PageBuilder {
84
85
  pageComponent,
85
86
  fetchWebpackStats: this.fetchWebpackStats,
86
87
  renderMode: this.renderMode,
88
+ assetsPrefixFactory: this.assetsPrefixFactory,
87
89
  }));
88
90
  this.resourcesRegistry.register(await polyfillResources({
89
91
  condition: this.polyfillCondition,
@@ -28,7 +28,7 @@ const mapResourcesToSlots = (resources) => resources.reduce((acc, resource) => {
28
28
  return acc;
29
29
  }, {});
30
30
  class PageBuilder {
31
- constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, di, renderMode, }) {
31
+ constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, di, renderMode, assetsPrefixFactory, }) {
32
32
  this.htmlAttrs = htmlAttrs;
33
33
  this.renderSlots = flatten__default["default"](renderSlots || []);
34
34
  this.pageService = pageService;
@@ -43,6 +43,7 @@ class PageBuilder {
43
43
  this.fetchWebpackStats = fetchWebpackStats;
44
44
  this.di = di;
45
45
  this.renderMode = renderMode;
46
+ this.assetsPrefixFactory = assetsPrefixFactory;
46
47
  }
47
48
  async flow() {
48
49
  const stats = await this.fetchWebpackStats({ modern: this.modern });
@@ -92,6 +93,7 @@ class PageBuilder {
92
93
  pageComponent,
93
94
  fetchWebpackStats: this.fetchWebpackStats,
94
95
  renderMode: this.renderMode,
96
+ assetsPrefixFactory: this.assetsPrefixFactory,
95
97
  }));
96
98
  this.resourcesRegistry.register(await polyfill.polyfillResources({
97
99
  condition: this.polyfillCondition,
@@ -1,11 +1,13 @@
1
1
  import type { ChunkExtractor } from '@loadable/server';
2
- import type { PageResource, FETCH_WEBPACK_STATS_TOKEN, REACT_SERVER_RENDER_MODE } from '@tramvai/tokens-render';
3
- export declare const bundleResource: ({ bundle, modern, extractor, pageComponent, fetchWebpackStats, renderMode, }: {
2
+ import type { PageResource, FETCH_WEBPACK_STATS_TOKEN, REACT_SERVER_RENDER_MODE, ASSETS_PREFIX_TOKEN } from '@tramvai/tokens-render';
3
+ import type { ExtractDependencyType } from '@tinkoff/dippy';
4
+ export declare const bundleResource: ({ bundle, modern, extractor, pageComponent, fetchWebpackStats, renderMode, assetsPrefixFactory, }: {
4
5
  bundle: string;
5
6
  modern: boolean;
6
7
  extractor: ChunkExtractor;
7
8
  pageComponent?: string;
8
9
  fetchWebpackStats: typeof FETCH_WEBPACK_STATS_TOKEN;
9
10
  renderMode: typeof REACT_SERVER_RENDER_MODE | null;
11
+ assetsPrefixFactory: ExtractDependencyType<typeof ASSETS_PREFIX_TOKEN>;
10
12
  }) => Promise<PageResource[]>;
11
13
  //# sourceMappingURL=bundleResource.d.ts.map
@@ -20,7 +20,7 @@ try {
20
20
  catch (e) {
21
21
  // do nothing
22
22
  }
23
- const bundleResource = async ({ bundle, modern, extractor, pageComponent, fetchWebpackStats, renderMode, }) => {
23
+ const bundleResource = async ({ bundle, modern, extractor, pageComponent, fetchWebpackStats, renderMode, assetsPrefixFactory, }) => {
24
24
  // for file-system pages preload page chunk against bundle chunk
25
25
  const chunkNameFromBundle = isFileSystemPageComponent(pageComponent)
26
26
  ? fileSystemPageToWebpackChunkName(pageComponent)
@@ -37,12 +37,12 @@ const bundleResource = async ({ bundle, modern, extractor, pageComponent, fetchW
37
37
  const { scripts, styles } = flushFiles([...bundles, ...lazyChunks, ...criticalChunks, 'platform'], webpackStats);
38
38
  const genHref = (href) => `${publicPath}${href}`;
39
39
  const result = [];
40
- if (process.env.NODE_ENV === 'production' ||
41
- (process.env.ASSETS_PREFIX && process.env.ASSETS_PREFIX !== 'static')) {
40
+ const assetsPrefix = assetsPrefixFactory();
41
+ if (process.env.NODE_ENV === 'production' || (assetsPrefix && assetsPrefix !== 'static')) {
42
42
  result.push({
43
43
  type: ResourceType.inlineScript,
44
44
  slot: ResourceSlot.HEAD_CORE_SCRIPTS,
45
- payload: `window.ap = ${`"${process.env.ASSETS_PREFIX}"`};`,
45
+ payload: `window.ap = ${`"${assetsPrefix}"`};`,
46
46
  });
47
47
  }
48
48
  // defer scripts is not suitable for React streaming, we need to ability to run them as early as possible
@@ -29,7 +29,7 @@ try {
29
29
  catch (e) {
30
30
  // do nothing
31
31
  }
32
- const bundleResource = async ({ bundle, modern, extractor, pageComponent, fetchWebpackStats, renderMode, }) => {
32
+ const bundleResource = async ({ bundle, modern, extractor, pageComponent, fetchWebpackStats, renderMode, assetsPrefixFactory, }) => {
33
33
  // for file-system pages preload page chunk against bundle chunk
34
34
  const chunkNameFromBundle = experiments.isFileSystemPageComponent(pageComponent)
35
35
  ? experiments.fileSystemPageToWebpackChunkName(pageComponent)
@@ -46,12 +46,12 @@ const bundleResource = async ({ bundle, modern, extractor, pageComponent, fetchW
46
46
  const { scripts, styles } = flushFiles.flushFiles([...bundles, ...lazyChunks, ...criticalChunks, 'platform'], webpackStats);
47
47
  const genHref = (href) => `${publicPath}${href}`;
48
48
  const result = [];
49
- if (process.env.NODE_ENV === 'production' ||
50
- (process.env.ASSETS_PREFIX && process.env.ASSETS_PREFIX !== 'static')) {
49
+ const assetsPrefix = assetsPrefixFactory();
50
+ if (process.env.NODE_ENV === 'production' || (assetsPrefix && assetsPrefix !== 'static')) {
51
51
  result.push({
52
52
  type: tokensRender.ResourceType.inlineScript,
53
53
  slot: tokensRender.ResourceSlot.HEAD_CORE_SCRIPTS,
54
- payload: `window.ap = ${`"${process.env.ASSETS_PREFIX}"`};`,
54
+ payload: `window.ap = ${`"${assetsPrefix}"`};`,
55
55
  });
56
56
  }
57
57
  // defer scripts is not suitable for React streaming, we need to ability to run them as early as possible
@@ -1,3 +1,8 @@
1
- import type { FETCH_WEBPACK_STATS_TOKEN } from '@tramvai/tokens-render';
2
- export declare const fetchWebpackStats: typeof FETCH_WEBPACK_STATS_TOKEN;
1
+ import type { FETCH_WEBPACK_STATS_TOKEN, ASSETS_PREFIX_TOKEN } from '@tramvai/tokens-render';
2
+ import type { ExtractDependencyType } from '@tinkoff/dippy';
3
+ type Deps = {
4
+ assetsPrefixFactory: ExtractDependencyType<typeof ASSETS_PREFIX_TOKEN>;
5
+ };
6
+ export declare const fetchWebpackStats: ({ assetsPrefixFactory }: Deps) => typeof FETCH_WEBPACK_STATS_TOKEN;
7
+ export {};
3
8
  //# sourceMappingURL=fetchWebpackStats.d.ts.map
@@ -15,14 +15,15 @@ let fetchStats = async () => {
15
15
  throw new Error(`Unknown environment`);
16
16
  };
17
17
  if (process.env.NODE_ENV === 'development') {
18
- fetchStats = async () => {
18
+ fetchStats = async (_, assetsPrefixFactory) => {
19
19
  const { modern: configModern, staticHost, staticPort, output, httpProtocol } = appConfig;
20
20
  const getUrl = (filename) => `${httpProtocol}://${staticHost}:${staticPort}/${output.client}/${filename}`;
21
21
  const request = await fetch(getUrl(configModern ? 'stats.modern.json' : 'stats.json'));
22
22
  const stats = await request.json();
23
+ const assetsPrefix = assetsPrefixFactory();
23
24
  // static - популярная заглушка в env.development.js файлах, надо игнорировать, как было раньше
24
- const hasAssetsPrefix = process.env.ASSETS_PREFIX && process.env.ASSETS_PREFIX !== 'static';
25
- const publicPath = hasAssetsPrefix ? process.env.ASSETS_PREFIX : stats.publicPath;
25
+ const hasAssetsPrefix = assetsPrefix && assetsPrefix !== 'static';
26
+ const publicPath = hasAssetsPrefix ? assetsPrefix : stats.publicPath;
26
27
  return {
27
28
  ...stats,
28
29
  publicPath,
@@ -41,7 +42,7 @@ if (process.env.NODE_ENV === 'test') {
41
42
  }
42
43
  if (process.env.NODE_ENV === 'production') {
43
44
  const SEARCH_PATHS = [process.cwd(), __dirname];
44
- const webpackStats = (fileName) => {
45
+ const webpackStats = (fileName, assetsPrefix) => {
45
46
  let stats;
46
47
  for (const dir of SEARCH_PATHS) {
47
48
  try {
@@ -57,7 +58,7 @@ if (process.env.NODE_ENV === 'production') {
57
58
  if (!stats) {
58
59
  return;
59
60
  }
60
- if (!process.env.ASSETS_PREFIX) {
61
+ if (!assetsPrefix) {
61
62
  if (process.env.STATIC_PREFIX) {
62
63
  throw new Error('Required env variable "ASSETS_PREFIX" is not set. Instead of using "STATIC_PREFIX" env please define "ASSETS_PREFIX: STATIC_PREFIX + /compiled"');
63
64
  }
@@ -65,32 +66,41 @@ if (process.env.NODE_ENV === 'production') {
65
66
  }
66
67
  return {
67
68
  ...stats,
68
- publicPath: process.env.ASSETS_PREFIX,
69
+ publicPath: assetsPrefix,
69
70
  };
70
71
  };
71
- const statsLegacy = webpackStats('stats.json');
72
- const statsModern = webpackStats('stats.modern.json') || statsLegacy;
73
- if (!statsLegacy) {
74
- throw new Error(`Cannot find stats.json.
75
- It should be placed in one of the next places:
76
- ${SEARCH_PATHS.join('\n\t')}
77
- In case it happens on deployment:
78
- - In case you are using two independent jobs for building app
79
- - Either do not split build command by two independent jobs and use one common job with "tramvai build" command without --buildType
80
- - Or copy stats.json (and stats.modern.json if present) file from client build output to server output by yourself in your CI
81
- - Otherwise report issue to tramvai team
82
- In case it happens locally:
83
- - prefer to use command "tramvai start-prod" to test prod-build locally
84
- - copy stats.json next to built server.js file
85
- `);
86
- }
87
- fetchStats = (modern) => {
88
- const stats = modern ? statsModern : statsLegacy;
72
+ const statsCache = {};
73
+ fetchStats = (modern, assetsPrefixFactory) => {
74
+ const assetsPrefix = assetsPrefixFactory();
75
+ const legacyStatsKey = `${assetsPrefix}legacy`;
76
+ const modernStatsKey = `${assetsPrefix}modern`;
77
+ if (!statsCache[legacyStatsKey]) {
78
+ statsCache[legacyStatsKey] = webpackStats('stats.json', assetsPrefix);
79
+ }
80
+ if (!statsCache[modernStatsKey]) {
81
+ statsCache[modernStatsKey] =
82
+ webpackStats('stats.modern.json', assetsPrefix) || statsCache[legacyStatsKey];
83
+ }
84
+ if (!statsCache[legacyStatsKey]) {
85
+ throw new Error(`Cannot find stats.json.
86
+ It should be placed in one of the next places:
87
+ ${SEARCH_PATHS.join('\n\t')}
88
+ In case it happens on deployment:
89
+ - In case you are using two independent jobs for building app
90
+ - Either do not split build command by two independent jobs and use one common job with "tramvai build" command without --buildType
91
+ - Or copy stats.json (and stats.modern.json if present) file from client build output to server output by yourself in your CI
92
+ - Otherwise report issue to tramvai team
93
+ In case it happens locally:
94
+ - prefer to use command "tramvai start-prod" to test prod-build locally
95
+ - copy stats.json next to built server.js file
96
+ `);
97
+ }
98
+ const stats = modern ? statsCache[modernStatsKey] : statsCache[legacyStatsKey];
89
99
  return Promise.resolve(stats);
90
100
  };
91
101
  }
92
- const fetchWebpackStats = async ({ modern } = {}) => {
93
- return fetchStats(modern);
102
+ const fetchWebpackStats = ({ assetsPrefixFactory }) => async ({ modern } = {}) => {
103
+ return fetchStats(modern, assetsPrefixFactory);
94
104
  };
95
105
 
96
106
  export { fetchWebpackStats };
@@ -42,14 +42,15 @@ let fetchStats = async () => {
42
42
  throw new Error(`Unknown environment`);
43
43
  };
44
44
  if (process.env.NODE_ENV === 'development') {
45
- fetchStats = async () => {
45
+ fetchStats = async (_, assetsPrefixFactory) => {
46
46
  const { modern: configModern, staticHost, staticPort, output, httpProtocol } = appConfig;
47
47
  const getUrl = (filename) => `${httpProtocol}://${staticHost}:${staticPort}/${output.client}/${filename}`;
48
48
  const request = await fetch__default["default"](getUrl(configModern ? 'stats.modern.json' : 'stats.json'));
49
49
  const stats = await request.json();
50
+ const assetsPrefix = assetsPrefixFactory();
50
51
  // static - популярная заглушка в env.development.js файлах, надо игнорировать, как было раньше
51
- const hasAssetsPrefix = process.env.ASSETS_PREFIX && process.env.ASSETS_PREFIX !== 'static';
52
- const publicPath = hasAssetsPrefix ? process.env.ASSETS_PREFIX : stats.publicPath;
52
+ const hasAssetsPrefix = assetsPrefix && assetsPrefix !== 'static';
53
+ const publicPath = hasAssetsPrefix ? assetsPrefix : stats.publicPath;
53
54
  return {
54
55
  ...stats,
55
56
  publicPath,
@@ -68,7 +69,7 @@ if (process.env.NODE_ENV === 'test') {
68
69
  }
69
70
  if (process.env.NODE_ENV === 'production') {
70
71
  const SEARCH_PATHS = [process.cwd(), __dirname];
71
- const webpackStats = (fileName) => {
72
+ const webpackStats = (fileName, assetsPrefix) => {
72
73
  let stats;
73
74
  for (const dir of SEARCH_PATHS) {
74
75
  try {
@@ -84,7 +85,7 @@ if (process.env.NODE_ENV === 'production') {
84
85
  if (!stats) {
85
86
  return;
86
87
  }
87
- if (!process.env.ASSETS_PREFIX) {
88
+ if (!assetsPrefix) {
88
89
  if (process.env.STATIC_PREFIX) {
89
90
  throw new Error('Required env variable "ASSETS_PREFIX" is not set. Instead of using "STATIC_PREFIX" env please define "ASSETS_PREFIX: STATIC_PREFIX + /compiled"');
90
91
  }
@@ -92,32 +93,41 @@ if (process.env.NODE_ENV === 'production') {
92
93
  }
93
94
  return {
94
95
  ...stats,
95
- publicPath: process.env.ASSETS_PREFIX,
96
+ publicPath: assetsPrefix,
96
97
  };
97
98
  };
98
- const statsLegacy = webpackStats('stats.json');
99
- const statsModern = webpackStats('stats.modern.json') || statsLegacy;
100
- if (!statsLegacy) {
101
- throw new Error(`Cannot find stats.json.
102
- It should be placed in one of the next places:
103
- ${SEARCH_PATHS.join('\n\t')}
104
- In case it happens on deployment:
105
- - In case you are using two independent jobs for building app
106
- - Either do not split build command by two independent jobs and use one common job with "tramvai build" command without --buildType
107
- - Or copy stats.json (and stats.modern.json if present) file from client build output to server output by yourself in your CI
108
- - Otherwise report issue to tramvai team
109
- In case it happens locally:
110
- - prefer to use command "tramvai start-prod" to test prod-build locally
111
- - copy stats.json next to built server.js file
112
- `);
113
- }
114
- fetchStats = (modern) => {
115
- const stats = modern ? statsModern : statsLegacy;
99
+ const statsCache = {};
100
+ fetchStats = (modern, assetsPrefixFactory) => {
101
+ const assetsPrefix = assetsPrefixFactory();
102
+ const legacyStatsKey = `${assetsPrefix}legacy`;
103
+ const modernStatsKey = `${assetsPrefix}modern`;
104
+ if (!statsCache[legacyStatsKey]) {
105
+ statsCache[legacyStatsKey] = webpackStats('stats.json', assetsPrefix);
106
+ }
107
+ if (!statsCache[modernStatsKey]) {
108
+ statsCache[modernStatsKey] =
109
+ webpackStats('stats.modern.json', assetsPrefix) || statsCache[legacyStatsKey];
110
+ }
111
+ if (!statsCache[legacyStatsKey]) {
112
+ throw new Error(`Cannot find stats.json.
113
+ It should be placed in one of the next places:
114
+ ${SEARCH_PATHS.join('\n\t')}
115
+ In case it happens on deployment:
116
+ - In case you are using two independent jobs for building app
117
+ - Either do not split build command by two independent jobs and use one common job with "tramvai build" command without --buildType
118
+ - Or copy stats.json (and stats.modern.json if present) file from client build output to server output by yourself in your CI
119
+ - Otherwise report issue to tramvai team
120
+ In case it happens locally:
121
+ - prefer to use command "tramvai start-prod" to test prod-build locally
122
+ - copy stats.json next to built server.js file
123
+ `);
124
+ }
125
+ const stats = modern ? statsCache[modernStatsKey] : statsCache[legacyStatsKey];
116
126
  return Promise.resolve(stats);
117
127
  };
118
128
  }
119
- const fetchWebpackStats = async ({ modern } = {}) => {
120
- return fetchStats(modern);
129
+ const fetchWebpackStats = ({ assetsPrefixFactory }) => async ({ modern } = {}) => {
130
+ return fetchStats(modern, assetsPrefixFactory);
121
131
  };
122
132
 
123
133
  exports.fetchWebpackStats = fetchWebpackStats;
package/lib/server.es.js CHANGED
@@ -3,7 +3,7 @@ import { Module, provide, commandLineListTokens, DI_TOKEN } from '@tramvai/core'
3
3
  import { CREATE_CACHE_TOKEN, LOGGER_TOKEN, REQUEST_MANAGER_TOKEN, RESPONSE_MANAGER_TOKEN, CONTEXT_TOKEN, DEFERRED_ACTIONS_MAP_TOKEN } from '@tramvai/tokens-common';
4
4
  import { PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
5
5
  import { ClientHintsModule, USER_AGENT_TOKEN } from '@tramvai/module-client-hints';
6
- import { RESOURCES_REGISTRY, RESOURCE_INLINE_OPTIONS, BACK_FORWARD_CACHE_ENABLED, RENDER_SLOTS, POLYFILL_CONDITION, HTML_ATTRS, MODERN_SATISFIES_TOKEN, RENDER_FLOW_AFTER_TOKEN, FETCH_WEBPACK_STATS_TOKEN, REACT_SERVER_RENDER_MODE, CUSTOM_RENDER, EXTEND_RENDER, REACT_STREAMING_RENDER_TIMEOUT, ResourceType } from '@tramvai/tokens-render';
6
+ import { RESOURCES_REGISTRY, RESOURCE_INLINE_OPTIONS, ASSETS_PREFIX_TOKEN, BACK_FORWARD_CACHE_ENABLED, RENDER_SLOTS, POLYFILL_CONDITION, HTML_ATTRS, MODERN_SATISFIES_TOKEN, RENDER_FLOW_AFTER_TOKEN, FETCH_WEBPACK_STATS_TOKEN, REACT_SERVER_RENDER_MODE, CUSTOM_RENDER, EXTEND_RENDER, REACT_STREAMING_RENDER_TIMEOUT, ResourceType, DEFAULT_ASSETS_PREFIX_TOKEN } from '@tramvai/tokens-render';
7
7
  export * from '@tramvai/tokens-render';
8
8
  import { Scope, optional } from '@tinkoff/dippy';
9
9
  import { satisfies } from '@tinkoff/user-agent';
@@ -23,6 +23,7 @@ import { LayoutModule } from './shared/LayoutModule.es.js';
23
23
  import { providers } from './shared/providers.es.js';
24
24
  import { fetchWebpackStats } from './server/blocks/utils/fetchWebpackStats.es.js';
25
25
 
26
+ var _a;
26
27
  var RenderModule_1;
27
28
  const REQUEST_TTL = 5 * 60 * 1000;
28
29
  /**
@@ -102,6 +103,7 @@ RenderModule = RenderModule_1 = __decorate([
102
103
  resourcesRegistryCache: RESOURCES_REGISTRY_CACHE,
103
104
  resourceInlineThreshold: { token: RESOURCE_INLINE_OPTIONS, optional: true },
104
105
  logger: LOGGER_TOKEN,
106
+ assetsPrefixFactory: ASSETS_PREFIX_TOKEN,
105
107
  },
106
108
  }),
107
109
  provide({
@@ -226,6 +228,7 @@ Page Error Boundary will be rendered for the client`,
226
228
  fetchWebpackStats: FETCH_WEBPACK_STATS_TOKEN,
227
229
  di: DI_TOKEN,
228
230
  renderMode: optional(REACT_SERVER_RENDER_MODE),
231
+ assetsPrefixFactory: ASSETS_PREFIX_TOKEN,
229
232
  },
230
233
  }),
231
234
  provide({
@@ -321,9 +324,27 @@ Page Error Boundary will be rendered for the client`,
321
324
  createCache: CREATE_CACHE_TOKEN,
322
325
  },
323
326
  }),
327
+ provide({
328
+ provide: ASSETS_PREFIX_TOKEN,
329
+ useFactory: ({ defaultAssetsPrefix }) => {
330
+ return () => defaultAssetsPrefix;
331
+ },
332
+ deps: {
333
+ defaultAssetsPrefix: DEFAULT_ASSETS_PREFIX_TOKEN,
334
+ },
335
+ }),
336
+ provide({
337
+ provide: DEFAULT_ASSETS_PREFIX_TOKEN,
338
+ useValue: (_a = process.env.ASSETS_PREFIX) !== null && _a !== void 0 ? _a : null,
339
+ }),
324
340
  provide({
325
341
  provide: FETCH_WEBPACK_STATS_TOKEN,
326
- useValue: fetchWebpackStats,
342
+ useFactory: (deps) => {
343
+ return fetchWebpackStats(deps);
344
+ },
345
+ deps: {
346
+ assetsPrefixFactory: ASSETS_PREFIX_TOKEN,
347
+ },
327
348
  }),
328
349
  provide({
329
350
  provide: BACK_FORWARD_CACHE_ENABLED,
package/lib/server.js CHANGED
@@ -24,6 +24,7 @@ var LayoutModule = require('./shared/LayoutModule.js');
24
24
  var providers = require('./shared/providers.js');
25
25
  var fetchWebpackStats = require('./server/blocks/utils/fetchWebpackStats.js');
26
26
 
27
+ var _a;
27
28
  var RenderModule_1;
28
29
  const REQUEST_TTL = 5 * 60 * 1000;
29
30
  /**
@@ -103,6 +104,7 @@ exports.RenderModule = RenderModule_1 = tslib.__decorate([
103
104
  resourcesRegistryCache: tokens.RESOURCES_REGISTRY_CACHE,
104
105
  resourceInlineThreshold: { token: tokensRender.RESOURCE_INLINE_OPTIONS, optional: true },
105
106
  logger: tokensCommon.LOGGER_TOKEN,
107
+ assetsPrefixFactory: tokensRender.ASSETS_PREFIX_TOKEN,
106
108
  },
107
109
  }),
108
110
  core.provide({
@@ -227,6 +229,7 @@ Page Error Boundary will be rendered for the client`,
227
229
  fetchWebpackStats: tokensRender.FETCH_WEBPACK_STATS_TOKEN,
228
230
  di: core.DI_TOKEN,
229
231
  renderMode: dippy.optional(tokensRender.REACT_SERVER_RENDER_MODE),
232
+ assetsPrefixFactory: tokensRender.ASSETS_PREFIX_TOKEN,
230
233
  },
231
234
  }),
232
235
  core.provide({
@@ -322,9 +325,27 @@ Page Error Boundary will be rendered for the client`,
322
325
  createCache: tokensCommon.CREATE_CACHE_TOKEN,
323
326
  },
324
327
  }),
328
+ core.provide({
329
+ provide: tokensRender.ASSETS_PREFIX_TOKEN,
330
+ useFactory: ({ defaultAssetsPrefix }) => {
331
+ return () => defaultAssetsPrefix;
332
+ },
333
+ deps: {
334
+ defaultAssetsPrefix: tokensRender.DEFAULT_ASSETS_PREFIX_TOKEN,
335
+ },
336
+ }),
337
+ core.provide({
338
+ provide: tokensRender.DEFAULT_ASSETS_PREFIX_TOKEN,
339
+ useValue: (_a = process.env.ASSETS_PREFIX) !== null && _a !== void 0 ? _a : null,
340
+ }),
325
341
  core.provide({
326
342
  provide: tokensRender.FETCH_WEBPACK_STATS_TOKEN,
327
- useValue: fetchWebpackStats.fetchWebpackStats,
343
+ useFactory: (deps) => {
344
+ return fetchWebpackStats.fetchWebpackStats(deps);
345
+ },
346
+ deps: {
347
+ assetsPrefixFactory: tokensRender.ASSETS_PREFIX_TOKEN,
348
+ },
328
349
  }),
329
350
  core.provide({
330
351
  provide: tokensRender.BACK_FORWARD_CACHE_ENABLED,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tramvai/module-render",
3
- "version": "4.38.0",
3
+ "version": "4.39.0",
4
4
  "description": "",
5
5
  "browser": "lib/browser.js",
6
6
  "main": "lib/server.js",
@@ -26,15 +26,15 @@
26
26
  "@tinkoff/layout-factory": "0.5.1",
27
27
  "@tinkoff/errors": "0.5.1",
28
28
  "@tinkoff/url": "0.10.1",
29
- "@tinkoff/user-agent": "0.6.124",
29
+ "@tinkoff/user-agent": "0.6.125",
30
30
  "@tinkoff/request-core": "^0.10.0",
31
31
  "@tinkoff/request-plugin-protocol-http": "^0.12.1",
32
- "@tramvai/module-client-hints": "4.38.0",
33
- "@tramvai/module-router": "4.38.0",
34
- "@tramvai/react": "4.38.0",
32
+ "@tramvai/module-client-hints": "4.39.0",
33
+ "@tramvai/module-router": "4.39.0",
34
+ "@tramvai/react": "4.39.0",
35
35
  "@tramvai/safe-strings": "0.7.3",
36
- "@tramvai/tokens-render": "4.38.0",
37
- "@tramvai/experiments": "4.38.0",
36
+ "@tramvai/tokens-render": "4.39.0",
37
+ "@tramvai/experiments": "4.39.0",
38
38
  "@types/loadable__server": "^5.12.6",
39
39
  "node-fetch": "^2.6.1"
40
40
  },
@@ -42,14 +42,14 @@
42
42
  "@tinkoff/dippy": "0.10.8",
43
43
  "@tinkoff/utils": "^2.1.2",
44
44
  "@tinkoff/react-hooks": "0.3.1",
45
- "@tramvai/cli": "4.38.0",
46
- "@tramvai/core": "4.38.0",
47
- "@tramvai/module-common": "4.38.0",
48
- "@tramvai/state": "4.38.0",
49
- "@tramvai/test-helpers": "4.38.0",
50
- "@tramvai/tokens-common": "4.38.0",
51
- "@tramvai/tokens-router": "4.38.0",
52
- "@tramvai/tokens-server-private": "4.38.0",
45
+ "@tramvai/cli": "4.39.0",
46
+ "@tramvai/core": "4.39.0",
47
+ "@tramvai/module-common": "4.39.0",
48
+ "@tramvai/state": "4.39.0",
49
+ "@tramvai/test-helpers": "4.39.0",
50
+ "@tramvai/tokens-common": "4.39.0",
51
+ "@tramvai/tokens-router": "4.39.0",
52
+ "@tramvai/tokens-server-private": "4.39.0",
53
53
  "express": "^4.17.1",
54
54
  "prop-types": "^15.6.2",
55
55
  "react": ">=16.14.0",
package/tests.js CHANGED
@@ -78,11 +78,7 @@ const agent = {
78
78
  };
79
79
  requestFactory__default["default"]([httpPlugin__default["default"]({ agent })]);
80
80
 
81
- const TRAMVAI_CLI_ASSETS_PREFIX = `${process.env.TRAMVAI_CLI_ASSETS_PREFIX}`;
82
- process.env.NODE_ENV === 'development' &&
83
- (process.env.ASSETS_PREFIX === 'static' || !process.env.ASSETS_PREFIX)
84
- ? TRAMVAI_CLI_ASSETS_PREFIX
85
- : process.env.ASSETS_PREFIX;
81
+ `${process.env.TRAMVAI_CLI_ASSETS_PREFIX}`;
86
82
 
87
83
  /**
88
84
  * @description