@tramvai/module-render 1.48.3 → 1.50.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,24 +1,24 @@
1
1
  # RenderModule
2
2
 
3
- Модуль для рендера react-приложения на сервере и в браузере
3
+ Module for rendering React application on the server and in the browser
4
4
 
5
- ## Быстрый обзор
5
+ ## Overview
6
6
 
7
- ![init command](/img/tramvai/render-module.jpg)
7
+ ![init command](/img/render/render-module.drawio.svg)
8
8
 
9
- Модуль который внутри себя содержит логику по генерацию html страницы, начиная от получения текущего компонента, так и заканчивая генерации конечного html c помощью библиотеки htmlpagebuilder.
9
+ Module contains the logic for generating HTML pages, starting from getting current page component, and finishing with the rendering result HTML using the `@tinkoff/htmlpagebuilder` library.
10
10
 
11
- Из особенностей, в этом модуле присутствует код создания верхнеуровнего реакт компонента, получения пэйдж компонента и лайаута из роутинга и создание композиции из провайдеров в приложении
11
+ This module includes code for creating top-level React component with all necessary providers composition, and page and layout components from the current route.
12
12
 
13
- ## Подключение
13
+ ## Installation
14
14
 
15
- Необходимо установить `@tramvai/module-render` с помощью npm
15
+ You need to install `@tramvai/module-render`
16
16
 
17
- ```bash
18
- npm i @tramvai/module-render
17
+ ```bash npm2yarn
18
+ npm install @tramvai/module-render
19
19
  ```
20
20
 
21
- И подключить в проекте
21
+ And connect to the project
22
22
 
23
23
  ```tsx
24
24
  import { createApp } from '@tramvai/core';
@@ -32,25 +32,25 @@ createApp({
32
32
 
33
33
  ## Explanation
34
34
 
35
- ### Разные режимы отрисовки React
35
+ ### Different React rendering modes
36
36
 
37
- Подробнее о режимах рендеринга можете узнать в [официальной доке](https://ru.reactjs.org/docs/concurrent-mode-adoption.html) в module-render есть поддержка всех типов и вы можете выбрать для своего приложения актуальный тип
37
+ More information about rendering modes can be found in the [official documentation](https://reactjs.org/docs/concurrent-mode-adoption.html), `RenderModule` has support for all rendering types and you can choose the right one for your application.
38
38
 
39
- Для задания режима, необходимо при инициализации `RenderModule` передать параметр `mode`
39
+ To set the mode, you must pass the `mode` parameter when initializing the `RenderModule`.
40
40
 
41
41
  ```typescript
42
42
  RenderModule.forRoot({ mode: 'concurrent' });
43
43
  ```
44
44
 
45
- Доступны варианты: `'legacy' | 'strict' | 'blocking' | 'concurrent'`
45
+ Available modes: `'legacy' | 'strict' | 'blocking' | 'concurrent'`
46
46
 
47
- [Постепенная миграция на concurrent режим](#Как-можно-перевести-приложения-на-Concurrent-render-mode)
47
+ [Gradual concurrent mode adoption](#gradual-concurrent-mode-adoption)
48
48
 
49
- ### Ассеты в приложении
49
+ ### Application static assets
50
50
 
51
- Для работы с ресурсами в tramvai был разработан модуль ассетов который позволяет задать в DI список ресурсов и дальше их отрисовать в определенные слоты.
51
+ For static assets (JS, CSS, fonts, etc.) we create special resources registry module, which allow to provide in DI list of resources, and then render them to specifics slots in final HTML.
52
52
 
53
- Пример:
53
+ Example:
54
54
 
55
55
  ```typescript
56
56
  createApp({
@@ -59,12 +59,12 @@ createApp({
59
59
  multi: true,
60
60
  useValue: [
61
61
  {
62
- type: ResourceType.inlineScript, // inlineScript обернет payload в тег <script>
63
- slot: ResourceSlot.HEAD_CORE_SCRIPTS, // определяет позицию где в html будет вставлен ресурс
62
+ type: ResourceType.inlineScript, // inlineScript wrap payload in tag <script>
63
+ slot: ResourceSlot.HEAD_CORE_SCRIPTS, // define position where in HTML will be included resource
64
64
  payload: 'alert("render")',
65
65
  },
66
66
  {
67
- type: ResourceType.asIs, // asIs занчит вставить ресурс как есть. без обработки
67
+ type: ResourceType.asIs, // asIs just add payload as a string, without special processing
68
68
  slot: ResourceSlot.BODY_TAIL,
69
69
  payload: '<div>hello from render slots</div>',
70
70
  },
@@ -74,13 +74,13 @@ createApp({
74
74
  });
75
75
  ```
76
76
 
77
- - **type** - тип ресурса, уже есть готовые пресеты которые упрощает добавление кода на страницу, без прокидывания дополнительных параметров и так далее
78
- - **slot** - место в html странице, куда будет добавлен этот ресурс
79
- - **payload** - что будет отрисовано
77
+ - **type** - presets for different resources types
78
+ - **slot** - slot in HTML where resource will be included
79
+ - **payload** - information that will be rendered
80
80
 
81
81
  <p>
82
82
  <details>
83
- <summary>Доступные слоты</summary>
83
+ <summary>Available slots</summary>
84
84
 
85
85
  @inline src/server/constants/slots.ts
86
86
 
@@ -89,29 +89,30 @@ createApp({
89
89
 
90
90
  <p>
91
91
  <details>
92
- <summary>Схема разметки слотов в HTML странице</summary>
92
+ <summary>Layout of slots in the HTML page</summary>
93
93
 
94
94
  @inline src/server/htmlPageSchema.ts
95
95
 
96
96
  </details>
97
97
  </p>
98
98
 
99
- [Как добавить загрузку ассетов на странице](#Как-добавить-загрузку-ассетов-на-странице)
99
+ [How to add assets loading to a page](#How-to-add-assets-loading-to-a-page)
100
100
 
101
- ### Автоматический инлайнинг ресурсов
101
+ ### Automatic resource inlining
102
102
 
103
- #### Контекст
103
+ #### Concept
104
104
 
105
- Большое количество файлов ресурсов создаёт проблемы при загрузке страницы, т.к. браузеру приходится создавать много соединений на небольшие файлы
105
+ A large number of resource files creates problems when loading the page, because the browser has to create a lot of connections to small files
106
106
 
107
- #### Решение
107
+ #### Solution
108
108
 
109
- Решили добавить возможность включить часть ресурсов прямо в приходящий с сервера HTML. Чтобы не инлайнить вообще всё, добавлена возможность задать верхнюю границу размера файлов.
109
+ To optimize page loading, we've added the ability to include some resources directly in the incoming HTML from the server.
110
+ To avoid inlining everything at all, we've added the ability to set an upper limit for file size.
110
111
 
111
- #### Подключение и конфигурация
112
+ #### Connection and configuration
112
113
 
113
- С версии 0.60.7 инлайнинг для стилей включен по умолчанию, инлайнятся CSS-файлы размером меньше 40kb до gzip (+-10kb после gzip).
114
- Для переопределения этих настроек нужно добавить провайдер с указанием типов ресурсов, которые будут инлайниться (стили и\или скрипты), а также верхнюю границу размера файлов (в байтах, до gzip):
114
+ Since version `0.60.7` inlining for styles is enabled by default, CSS files smaller than 40kb before gzip (+-10kb after gzip) are inlined.
115
+ To override these settings, add a provider specifying types of resources to be inlined (styles and/or scripts) and an upper limit for file size (in bytes, before gzip):
115
116
 
116
117
  ```js
117
118
  import { RESOURCE_INLINE_OPTIONS } from '@tramvai/tokens-render';
@@ -121,61 +122,43 @@ import { provide } from '@tramvai/core';
121
122
  provide({
122
123
  provide: RESOURCE_INLINE_OPTIONS,
123
124
  useValue: {
124
- types: [ResourceType.script, ResourceType.style], // Включаем для стилей и скриптов
125
+ types: [ResourceType.script, ResourceType.style], // Turn on for a CSS and JS files
125
126
  threshold: 1024, // 1kb unzipped
126
127
  },
127
128
  }),
128
129
  ```
129
130
 
130
- #### Особенности
131
+ #### Peculiarities
131
132
 
132
- Инлайнятся все скрипты и\или стили (в зависимости от настроек), зарегистрированные через ResourcesRegistry
133
+ All scripts and styles (depending on the settings) registered through the `ResourcesRegistry` are inlined.
133
134
 
134
- Загрузка файлов на сервере происходит в lazy-режиме асинхронно. Это означает, что при первой загрузке страницы инлайнинга не будет происходить. Также это означает, что никакого дополнительного ожидания загрузки ресурсов на стороне сервера не происходит. После попадания файла в кэш он будет инлайниться. Кэш имеет TTL 30 минут, сброс кэша не предусмотрен.
135
+ File uploading to the server occurs in lazy mode, asynchronously.
136
+ This means that there will be no inlining when the page first loads.
137
+ It also means that there is no extra waiting for resources to load on the server side.
138
+ Once the file is in the cache it will be inline.
139
+ The cache has a TTL of 30 minutes and there is no resetting of the cache.
135
140
 
136
- ### Автоматический предзагрузка ассетов приложений
141
+ ### Automatic resource preloading
137
142
 
138
- Для ускорения загрузки данных добавлена система подзагрузки данных для ресурсов и асинхронных чанков, которая работает по следующему сценарию:
143
+ To speed up data loading, we've added a preloading system for resources and asynchronous chunks, which works according to the following scenario:
139
144
 
140
- - После рендеринга приложения мы получаем информацию о всех используемых в приложении css, js и асинхронных чанках
141
- - Дальше добавляем все css в прелоад тег и навешиваем onload событие. Нам необходимо максимально быстро загрузить блокирующие ресурсы.
142
- - При загрузке любого css файла, добавляем в предзагрузку все необходимые js файлы
145
+ - After rendering the application, we get information about all the CSS, JS bundles and asynchronous chunks used in the application
146
+ - Next we add all the CSS to the **preload** tag and add onload event on them. We need to load the blocking resources as quickly as possible.
147
+ - When loading any CSS file, onload event will be fired (only once time) and add all **preload** tags to the necessary JS files
143
148
 
144
- #### Особенности
149
+ ### Basic layout
145
150
 
146
- Обязательно должен быть синхронизирована последняя часть идентификатора бандла с названием чанка
151
+ The `RenderModule` has a default basic layout that supports different ways of extending and adding functionality
147
152
 
148
- ```
149
- const dashboard = () => require.ensure([], (require) => require('./bundles/dashboard'), 'dashboard');
150
- bundles: {
151
- 'platform/mvno/dashboard': dashboard,
152
- }
153
- ```
154
-
155
- или если используете import
156
-
157
- ```
158
- const dashboard = () => import(/* webpackChunkName: "dashboard" */ './bundles/dashboard');
159
- bundles: {
160
- 'platform/mvno/dashboard': dashboard,
161
- }
162
- ```
163
-
164
- В примере выше, 'dashboard' и last('platform/mvno/dashboard'.split('/')) имеют одинаковое значение. Иначе мы не сможем на стороне сервера узнать, какой из списка чанков подходит в бандлу и подзагрузка произойдет только на стороне клиента.
165
-
166
- ### Базовый layout
153
+ [Read more about layout on the library page](references/libs/layout-factory.md)
167
154
 
168
- В module-render встроен дефолтный базовый layout, который поддерживает различные способы расширения и добавления функциональности
155
+ #### Adding a basic header and footer
169
156
 
170
- [Подробнее про лайаут можете почитать на странице библиотеке](references/libs/layout-factory.md)
157
+ The module allows you to add header and footer components, which will be rendered by default for all pages
171
158
 
172
- #### Добавление базовых header и footer
159
+ ##### Via provider
173
160
 
174
- Можно добавить компоненты header и footer, которые будут отрисовываться по умолчанию для всех страниц
175
-
176
- ##### Через провайдер
177
-
178
- Зарегистрировать компоненты header и footer через провайдеры
161
+ Register header and footer components through providers:
179
162
 
180
163
  ```tsx
181
164
  import { DEFAULT_HEADER_COMPONENT, DEFAULT_FOOTER_COMPONENT } from '@tramvai/tokens-render';
@@ -195,9 +178,9 @@ createApp({
195
178
  });
196
179
  ```
197
180
 
198
- ##### Через бандл
181
+ ##### Via bundle
199
182
 
200
- Можно зарегистрировать в бандле компонент `headerDefault` и `footerDefault`, которые будет отрисовываться для всех роутов, у которых не переопределены `headerComponent` и `footerComponent`.
183
+ You can register a `headerDefault` and `footerDefault` component in the bundle, which will be rendered for all routes that do not have `headerComponent` and `footerComponent` redefined in configuration:
201
184
 
202
185
  ```tsx
203
186
  createBundle({
@@ -209,9 +192,9 @@ createBundle({
209
192
  });
210
193
  ```
211
194
 
212
- #### Добавление компонентов и враперов
195
+ #### Adding components and wrappers
213
196
 
214
- Добавить кастомные компоненты и врапперы для layout можно через токен `LAYOUT_OPTIONS`
197
+ You can add custom components and wrappers for layout via the token `LAYOUT_OPTIONS`
215
198
 
216
199
  ```tsx
217
200
  import { provide } from '@tramvai/core';
@@ -221,17 +204,18 @@ import { provide } from '@tramvai/core';
221
204
  provide: 'LAYOUT_OPTIONS',
222
205
  multi: true,
223
206
  useValue: {
224
- // react компоненты
207
+ // React components
225
208
  components: {
226
- // базовые кастомные компоненты врапперы для отрисовки страницы и контента
209
+ // content component, this component wraps the header, page and footer
227
210
  content: Content,
211
+ // page component
228
212
  page: Page,
229
213
 
230
- // глобальные компоненты
214
+ // any global components
231
215
  alerts: Alerts,
232
216
  feedback: Feedback,
233
217
  },
234
- // HOC для компонентов
218
+ // HOC's for components
235
219
  wrappers: {
236
220
  layout: layoutWrapper,
237
221
  alerts: [alertWrapper1, alertWrapper2],
@@ -243,17 +227,19 @@ import { provide } from '@tramvai/core';
243
227
  export class MyLayoutModule {}
244
228
  ```
245
229
 
246
- Подробнее про опции `components` и `wrappers` можно узнать в [@tinkoff/layout-factory](references/libs/layout-factory.md)
230
+ More details about the `components` and `wrappers` options can be found in [@tinkoff/layout-factory](references/libs/layout-factory.md)
247
231
 
248
- #### Замена базового layout
232
+ #### Replacing the basic layout
249
233
 
250
- Если вам не подходит базовый лайаут, вы можете его подменить на любой другой React компонент. При этом вам нужно самостоятельно реализовывать все врапперы и подключать глобальные компоненты, если они вам нужны.
234
+ If the basic layout doesn't work for you, you can replace it with any other React component.
235
+ In doing so, you need to implement all the wrappers yourself and plug in global components if you need them.
251
236
 
252
- Заменить можно двумя способами:
237
+ You can replace it in two ways:
253
238
 
254
- ##### Добавить layoutComponent у роута
239
+ ##### Add layoutComponent to route
255
240
 
256
- Вы можете прописать параметр `layoutComponent` у роута в `properties` и зарегистрировать компонент в `bundle`. При отрисовке страницы отобразится зарегистрированный компонент
241
+ You can add a `layoutComponent` property to route `config` and register component in `bundle`.
242
+ This layout will be rendered when you go to the corresponding route.
257
243
 
258
244
  ```tsx
259
245
  createBundle({
@@ -264,9 +250,9 @@ createBundle({
264
250
  });
265
251
  ```
266
252
 
267
- ##### Переопределить layoutDefault
253
+ ##### Replace layoutDefault
268
254
 
269
- Вы можете зарегистрировать в бандле компонент `layoutDefault` который автоматически будет отрисовываться для всех роутов, у которых не переопределен `layoutComponent`
255
+ You can register a `layoutDefault` component in `bundle`, which will be automatically rendered for all routes that do not have an `layoutComponent` in `config` property.
270
256
 
271
257
  ```tsx
272
258
  createBundle({
@@ -279,79 +265,79 @@ createBundle({
279
265
 
280
266
  ## How to
281
267
 
282
- ### Как добавить загрузку ассетов на странице
268
+ ### How to add assets loading to a page
283
269
 
284
- Присутствует 2 способа, как можно добавить ресурсы в приложение
270
+ There are 2 main ways how you can add resources to your application
285
271
 
286
- - токен `RENDER_SLOTS`, в который можно передать список ресурсов, например HTML разметка, inline скрипты, тег script
287
- - токен `RESOURCES_REGISTRY` для получения менеджера ресурсов, и регистрации нужных ресурсов вручную
272
+ - The `RENDER_SLOTS` token, where you can pass a list of resources, such as HTML markup, inline scripts, script tag
273
+ - Token `RESOURCES_REGISTRY` to get the resource manager, and register the desired resources manually
288
274
 
289
- Пример:
275
+ Example:
290
276
 
291
277
  <p>
292
278
  <details>
293
- <summary>Пример приложения</summary>
279
+ <summary>Application example</summary>
294
280
 
295
281
  @inline ../../../examples/how-to/render-add-resources/index.tsx
296
282
 
297
283
  </details>
298
284
  </p>
299
285
 
300
- ### Как можно перевести приложения на Concurrent render mode
286
+ ### Gradual concurrent mode adoption
301
287
 
302
- React позволяет выполнить постепенную миграцию приложения
288
+ React allows a gradual migration of an application
303
289
 
304
- **Этапы миграции:**
290
+ **Stages of migration:**
305
291
 
306
- 1. [Strict Mode](https://reactjs.org/docs/strict-mode.html) - строгий режим, в котором React предупреждает об использовании легаси API
292
+ 1. [Strict Mode](https://reactjs.org/docs/strict-mode.html) - strict mode, in which React warns about using the legacy API
307
293
 
308
- Для подключения необходимо сконфигурировать render-module
294
+ To connect, you must configure the `RenderModule`
309
295
 
310
- ```
296
+ ```js
311
297
  modules: [
312
298
  RenderModule.forRoot({ mode: 'strict' })
313
299
  ]
314
300
  ```
315
301
 
316
- Затем необходимо исправить все новые предупреждения, такие как использование легаси методов жизненного цикла и строковые рефы.
302
+ Then you need to fix any new warnings, such as using legacy lifecycle methods and string refs.
317
303
 
318
- 2. [Blocking Mode](https://reactjs.org/docs/concurrent-mode-adoption.html#migration-step-blocking-mode) - добавляет часть возможностей Concurrent Mode, например Suspense на сервере. Подходит для постепенной миграции на Concurrent Mode.
304
+ 2. [Blocking Mode](https://reactjs.org/docs/concurrent-mode-adoption.html#migration-step-blocking-mode) - adds some Concurrent Mode features, such as Suspense on the server. Suitable for gradual migration to Concurrent Mode.
319
305
 
320
- Для подключения необходимо установить экспериментальную версию React и сконфигурировать render-module
306
+ To connect, install an experimental version of React and configure the `RenderModule`
321
307
 
322
- ```bash
308
+ ```bash npm2yarn
323
309
  npm install react@experimental react-dom@experimental
324
310
  ```
325
311
 
326
- ```
312
+ ```js
327
313
  modules: [
328
314
  RenderModule.forRoot({ mode: 'blocking' })
329
315
  ]
330
316
  ```
331
317
 
332
- На этом этапе надо проверить работоспособность приложения, и можно попробовать новые API, например [SuspenseList](https://reactjs.org/docs/concurrent-mode-patterns.html#suspenselist)
318
+ At this stage, you need to check the performance of the application, and you can try new APIs, for example [SuspenseList](https://reactjs.org/docs/concurrent-mode-patterns.html#suspenselist)
333
319
 
334
320
  3. Concurrent Mode
335
321
 
336
- Для подключения необходимо установить экспериментальную версию React и сконфигурировать render-module
322
+ To connect, install an experimental version of React and configure the `RenderModule`
337
323
 
338
- ```bash
324
+ ```bash npm2yarn
339
325
  npm install react@experimental react-dom@experimental
340
326
  ```
341
327
 
342
- ```
328
+ ```js
343
329
  modules: [
344
330
  RenderModule.forRoot({ mode: 'concurrent' })
345
331
  ]
346
332
  ```
347
333
 
348
- На этом этапе надо проверить работоспособность приложения, и можно попробовать новые API, например [useTransition](https://reactjs.org/docs/concurrent-mode-patterns.html#transitions)
334
+ At this stage, you need to check the performance of the application, and you can try new APIs, for example [useTransition](https://reactjs.org/docs/concurrent-mode-patterns.html#transitions)
349
335
 
350
- ### Тестирование
336
+ ### Testing
351
337
 
352
- #### Тестирование расширений рендера через токены RENDER_SLOTS или RESOURCES_REGISTRY
338
+ #### Testing render extensions via RENDER_SLOTS or RESOURCES_REGISTRY tokens
353
339
 
354
- Если у вас имеется модуль или провайдеры которые определяют RENDER_SLOTS или используют RESOURCES_REGISTRY, то удобно будет использовать специальные утилиты для того чтобы протестировать их отдельно
340
+ If you have a module or providers that define `RENDER_SLOTS` or use `RESOURCES_REGISTRY`, it is convenient to use special utilities to test them separately
355
341
 
356
342
  ```ts
357
343
  import {
@@ -401,6 +387,6 @@ describe('testPageResources', () => {
401
387
  });
402
388
  ```
403
389
 
404
- ## Экспортируемые токены
390
+ ## Exported tokens
405
391
 
406
- [ссылка](references/tokens/render-tokens.md)
392
+ [link](references/tokens/render-tokens.md)
package/lib/browser.js CHANGED
@@ -25,15 +25,15 @@ const layoutWrapper = memoOne(withError(), strictEqual);
25
25
  const pageWrapper = memoOne(withError(), strictEqual);
26
26
  const Root = withError()(({ pageService }) => {
27
27
  const { config } = useRoute();
28
- const { pageComponent, layoutComponent = 'layoutDefault', headerComponent = 'headerDefault', footerComponent = 'footerDefault', } = config;
28
+ const { pageComponent } = config;
29
29
  const PageComponent = pageService.getComponent(pageComponent);
30
- // Достаем компоненты для текущей страницы, либо берем default реализации
31
- const LayoutComponent = pageService.getComponent(layoutComponent) || pageService.getComponent('layoutDefault');
32
- const HeaderComponent = pageService.getComponent(headerComponent) || pageService.getComponent('headerDefault');
33
- const FooterComponent = pageService.getComponent(footerComponent) || pageService.getComponent('footerDefault');
34
30
  if (!PageComponent) {
35
31
  throw new Error(`Page component '${pageComponent}' not found`);
36
32
  }
33
+ // Достаем компоненты для текущей страницы, либо берем default реализации
34
+ const LayoutComponent = pageService.resolveComponentFromConfig('layout');
35
+ const HeaderComponent = pageService.resolveComponentFromConfig('header');
36
+ const FooterComponent = pageService.resolveComponentFromConfig('footer');
37
37
  return (React.createElement(RootComponent, { HeaderComponent: HeaderComponent, FooterComponent: FooterComponent, LayoutComponent: layoutWrapper(LayoutComponent), PageComponent: pageWrapper(PageComponent) }));
38
38
  });
39
39
 
package/lib/server.es.js CHANGED
@@ -612,15 +612,15 @@ const layoutWrapper = memoOne(withError(), strictEqual);
612
612
  const pageWrapper = memoOne(withError(), strictEqual);
613
613
  const Root = withError()(({ pageService }) => {
614
614
  const { config } = useRoute();
615
- const { pageComponent, layoutComponent = 'layoutDefault', headerComponent = 'headerDefault', footerComponent = 'footerDefault', } = config;
615
+ const { pageComponent } = config;
616
616
  const PageComponent = pageService.getComponent(pageComponent);
617
- // Достаем компоненты для текущей страницы, либо берем default реализации
618
- const LayoutComponent = pageService.getComponent(layoutComponent) || pageService.getComponent('layoutDefault');
619
- const HeaderComponent = pageService.getComponent(headerComponent) || pageService.getComponent('headerDefault');
620
- const FooterComponent = pageService.getComponent(footerComponent) || pageService.getComponent('footerDefault');
621
617
  if (!PageComponent) {
622
618
  throw new Error(`Page component '${pageComponent}' not found`);
623
619
  }
620
+ // Достаем компоненты для текущей страницы, либо берем default реализации
621
+ const LayoutComponent = pageService.resolveComponentFromConfig('layout');
622
+ const HeaderComponent = pageService.resolveComponentFromConfig('header');
623
+ const FooterComponent = pageService.resolveComponentFromConfig('footer');
624
624
  return (React.createElement(RootComponent, { HeaderComponent: HeaderComponent, FooterComponent: FooterComponent, LayoutComponent: layoutWrapper(LayoutComponent), PageComponent: pageWrapper(PageComponent) }));
625
625
  });
626
626
 
package/lib/server.js CHANGED
@@ -651,15 +651,15 @@ const layoutWrapper = memoOne__default["default"](react.withError(), strictEqual
651
651
  const pageWrapper = memoOne__default["default"](react.withError(), strictEqual__default["default"]);
652
652
  const Root = react.withError()(({ pageService }) => {
653
653
  const { config } = moduleRouter.useRoute();
654
- const { pageComponent, layoutComponent = 'layoutDefault', headerComponent = 'headerDefault', footerComponent = 'footerDefault', } = config;
654
+ const { pageComponent } = config;
655
655
  const PageComponent = pageService.getComponent(pageComponent);
656
- // Достаем компоненты для текущей страницы, либо берем default реализации
657
- const LayoutComponent = pageService.getComponent(layoutComponent) || pageService.getComponent('layoutDefault');
658
- const HeaderComponent = pageService.getComponent(headerComponent) || pageService.getComponent('headerDefault');
659
- const FooterComponent = pageService.getComponent(footerComponent) || pageService.getComponent('footerDefault');
660
656
  if (!PageComponent) {
661
657
  throw new Error(`Page component '${pageComponent}' not found`);
662
658
  }
659
+ // Достаем компоненты для текущей страницы, либо берем default реализации
660
+ const LayoutComponent = pageService.resolveComponentFromConfig('layout');
661
+ const HeaderComponent = pageService.resolveComponentFromConfig('header');
662
+ const FooterComponent = pageService.resolveComponentFromConfig('footer');
663
663
  return (React__default["default"].createElement(RootComponent, { HeaderComponent: HeaderComponent, FooterComponent: FooterComponent, LayoutComponent: layoutWrapper(LayoutComponent), PageComponent: pageWrapper(PageComponent) }));
664
664
  });
665
665
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tramvai/module-render",
3
- "version": "1.48.3",
3
+ "version": "1.50.1",
4
4
  "description": "",
5
5
  "browser": "lib/browser.js",
6
6
  "main": "lib/server.js",
@@ -24,26 +24,26 @@
24
24
  "@tinkoff/htmlpagebuilder": "0.4.22",
25
25
  "@tinkoff/layout-factory": "0.2.28",
26
26
  "@tinkoff/url": "0.7.37",
27
- "@tinkoff/user-agent": "0.3.208",
28
- "@tramvai/module-client-hints": "1.48.3",
29
- "@tramvai/module-router": "1.48.3",
30
- "@tramvai/react": "1.48.3",
27
+ "@tinkoff/user-agent": "0.3.213",
28
+ "@tramvai/module-client-hints": "1.50.1",
29
+ "@tramvai/module-router": "1.50.1",
30
+ "@tramvai/react": "1.50.1",
31
31
  "@tramvai/safe-strings": "0.4.3",
32
- "@tramvai/tokens-render": "1.48.3",
33
- "@tramvai/experiments": "1.48.3",
32
+ "@tramvai/tokens-render": "1.50.1",
33
+ "@tramvai/experiments": "1.50.1",
34
34
  "@types/loadable__server": "^5.12.6",
35
35
  "node-fetch": "^2.6.1"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@tinkoff/dippy": "0.7.36",
39
39
  "@tinkoff/utils": "^2.1.2",
40
- "@tramvai/cli": "1.48.3",
41
- "@tramvai/core": "1.48.3",
42
- "@tramvai/module-common": "1.48.3",
43
- "@tramvai/state": "1.48.3",
44
- "@tramvai/test-helpers": "1.48.3",
45
- "@tramvai/tokens-common": "1.48.3",
46
- "@tramvai/tokens-router": "1.48.3",
40
+ "@tramvai/cli": "1.50.1",
41
+ "@tramvai/core": "1.50.1",
42
+ "@tramvai/module-common": "1.50.1",
43
+ "@tramvai/state": "1.50.1",
44
+ "@tramvai/test-helpers": "1.50.1",
45
+ "@tramvai/tokens-common": "1.50.1",
46
+ "@tramvai/tokens-router": "1.50.1",
47
47
  "prop-types": "^15.6.2",
48
48
  "react": ">=16.8.0",
49
49
  "react-dom": ">=16.8.0",