@tramvai/module-page-render-mode 1.72.2
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 +169 -0
- package/lib/PageRenderWrapper.d.ts +3 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.es.js +73 -0
- package/lib/index.js +83 -0
- package/lib/tokens.d.ts +5 -0
- package/lib/types.d.ts +1 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# @tramvai/module-page-render-mode
|
|
2
|
+
|
|
3
|
+
Enable different rendering modes for specific pages:
|
|
4
|
+
|
|
5
|
+
- `ssr`
|
|
6
|
+
|
|
7
|
+
SSR mode - provides default `tramvai` behaviour, render full page on server-side.
|
|
8
|
+
|
|
9
|
+
- `client`
|
|
10
|
+
|
|
11
|
+
Client mode - render only fallback for page component, then render full page on browser, after hydration.
|
|
12
|
+
This mode can significally improve server rendering performance, but not recommended for pages with high SEO impact.
|
|
13
|
+
Header and Footer will be rendered as usual.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
You need to install `@tramvai/module-page-render-mode`
|
|
18
|
+
|
|
19
|
+
```bash npm2yarn
|
|
20
|
+
yarn add @tramvai/module-page-render-mode
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
And connect in the project
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { createApp } from '@tramvai/core';
|
|
27
|
+
import { PageRenderModeModule } from '@tramvai/module-page-render-mode';
|
|
28
|
+
|
|
29
|
+
createApp({
|
|
30
|
+
name: 'tincoin',
|
|
31
|
+
modules: [ PageRenderModeModule ],
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Rendering mode
|
|
38
|
+
|
|
39
|
+
By default, this module connection has no changes, because default rendering mode is `ssr`.
|
|
40
|
+
You can change this mode for all pages or for specific pages only.
|
|
41
|
+
|
|
42
|
+
#### Default mode
|
|
43
|
+
|
|
44
|
+
For global rendering mode changing, use token `PAGE_RENDER_DEFAULT_MODE`:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { PAGE_RENDER_DEFAULT_MODE } from '@tramvai/module-page-render-mode';
|
|
48
|
+
|
|
49
|
+
const provider = {
|
|
50
|
+
provide: PAGE_RENDER_DEFAULT_MODE,
|
|
51
|
+
useValue: 'client',
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### Mode for specifig pages
|
|
56
|
+
|
|
57
|
+
For specific pages available two options:
|
|
58
|
+
|
|
59
|
+
- setting mode in route config:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const routes = [
|
|
63
|
+
{
|
|
64
|
+
name: 'main',
|
|
65
|
+
path: '/',
|
|
66
|
+
config: {
|
|
67
|
+
bundle: 'mainDefault',
|
|
68
|
+
pageComponent: 'pageDefault',
|
|
69
|
+
pageRenderMode: 'client',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- setting mode in page component static property:
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
const PageComponent = () => <div>Page</div>;
|
|
79
|
+
|
|
80
|
+
PageComponent.renderMode = 'client';
|
|
81
|
+
|
|
82
|
+
export default PageComponent;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Fallback
|
|
86
|
+
|
|
87
|
+
Standard behaviour for SPA applications - render some fallback with spinner or page skeleton before application was rendered.
|
|
88
|
+
You can set default fallback for all pages with `client` render mode, or only for specific pages.
|
|
89
|
+
|
|
90
|
+
#### Default fallback
|
|
91
|
+
|
|
92
|
+
For setting default fallback, use token `PAGE_RENDER_DEFAULT_MODE`:
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
import { PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT } from '@tramvai/module-page-render-mode';
|
|
96
|
+
|
|
97
|
+
const DefaultFallback = () => <div>Loading...</div>;
|
|
98
|
+
|
|
99
|
+
const provider = {
|
|
100
|
+
provide: PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT,
|
|
101
|
+
useValue: DefaultFallback,
|
|
102
|
+
};
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
#### Fallback for specific pages
|
|
107
|
+
|
|
108
|
+
For specific pages available few options:
|
|
109
|
+
|
|
110
|
+
- add fallback to page component static property, use name `pageRenderFallbackDefault`:
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
const PageComponent = () => <div>Page</div>;
|
|
114
|
+
|
|
115
|
+
const PageFallback = () => <div>Loading...</div>;
|
|
116
|
+
|
|
117
|
+
PageComponent.components = {
|
|
118
|
+
'pageRenderFallbackDefault': PageFallback,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export default PageComponent;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- add default fallback to bundle, use name `pageRenderFallbackDefault`:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
const DefaultFallback = () => <div>Loading...</div>;
|
|
128
|
+
|
|
129
|
+
const mainDefaultBundle = createBundle({
|
|
130
|
+
name: 'mainDefault',
|
|
131
|
+
components: {
|
|
132
|
+
'pageRenderFallbackDefault': DefaultFallback,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
export default mainDefaultBundle;
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
- and you can add fallback in route config, use key `pageRenderFallbackComponent` with any fallback name you provided in bundle or page component:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
const routes = [
|
|
143
|
+
{
|
|
144
|
+
name: 'main',
|
|
145
|
+
path: '/',
|
|
146
|
+
config: {
|
|
147
|
+
bundle: 'mainDefault',
|
|
148
|
+
pageComponent: 'pageDefault',
|
|
149
|
+
pageRenderFallbackComponent: 'myOwnFallbackComponent',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Troubleshooting
|
|
156
|
+
|
|
157
|
+
### Fallback name conflicts
|
|
158
|
+
|
|
159
|
+
You might have a potential issue with conflict existing components and render fallback component names - `pageRenderFallbackComponent` and `pageRenderFallbackDefault`.
|
|
160
|
+
For avoiding this issues, just change fallback name prefix using token `PAGE_RENDER_FALLBACK_COMPONENT_PREFIX`:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
import { PAGE_RENDER_FALLBACK_COMPONENT_PREFIX } from '@tramvai/module-page-render-mode';
|
|
164
|
+
|
|
165
|
+
const provider = {
|
|
166
|
+
provide: PAGE_RENDER_FALLBACK_COMPONENT_PREFIX,
|
|
167
|
+
useValue: 'myOwnRenderFallback',
|
|
168
|
+
};
|
|
169
|
+
```
|
package/lib/index.d.ts
ADDED
package/lib/index.es.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
|
+
import { Module } from '@tramvai/core';
|
|
3
|
+
import { LAYOUT_OPTIONS } from '@tramvai/tokens-render';
|
|
4
|
+
import React, { useState, useEffect } from 'react';
|
|
5
|
+
import { useDi } from '@tramvai/react';
|
|
6
|
+
import { PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
|
|
7
|
+
import { useRoute } from '@tramvai/module-router';
|
|
8
|
+
import { createToken } from '@tinkoff/dippy';
|
|
9
|
+
|
|
10
|
+
const PAGE_RENDER_FALLBACK_COMPONENT_PREFIX = createToken('pageRenderFallbackComponentName');
|
|
11
|
+
const PAGE_RENDER_DEFAULT_MODE = createToken('pageRenderDefaultMode');
|
|
12
|
+
const PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT = createToken('pageRenderDefaultFallbackComponent');
|
|
13
|
+
|
|
14
|
+
const PageRenderWrapper = ({ children }) => {
|
|
15
|
+
const [mounted, setMounted] = useState(false);
|
|
16
|
+
const { config } = useRoute();
|
|
17
|
+
const pageService = useDi(PAGE_SERVICE_TOKEN);
|
|
18
|
+
const fallbackKey = useDi(PAGE_RENDER_FALLBACK_COMPONENT_PREFIX);
|
|
19
|
+
const defaultRenderMode = useDi(PAGE_RENDER_DEFAULT_MODE);
|
|
20
|
+
const DefaultFallbackComponent = useDi({
|
|
21
|
+
token: PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT,
|
|
22
|
+
optional: true,
|
|
23
|
+
});
|
|
24
|
+
const { pageComponent, pageRenderMode } = config;
|
|
25
|
+
const { renderMode } = pageService.getComponent(pageComponent);
|
|
26
|
+
const FallbackComponent = pageService.resolveComponentFromConfig(fallbackKey) || DefaultFallbackComponent;
|
|
27
|
+
const mode = renderMode || pageRenderMode || defaultRenderMode;
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (mode === 'client') {
|
|
30
|
+
setMounted(true);
|
|
31
|
+
}
|
|
32
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
|
+
}, []);
|
|
34
|
+
if (mode === 'client' && !mounted) {
|
|
35
|
+
if (FallbackComponent) {
|
|
36
|
+
return React.createElement(FallbackComponent, null);
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return React.createElement(React.Fragment, null, children);
|
|
41
|
+
};
|
|
42
|
+
const pageRenderHOC = (WrapperPage) => (props) => {
|
|
43
|
+
return (React.createElement(PageRenderWrapper, null,
|
|
44
|
+
React.createElement(WrapperPage, Object.assign({}, props))));
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
let PageRenderModeModule = class PageRenderModeModule {
|
|
48
|
+
};
|
|
49
|
+
PageRenderModeModule = __decorate([
|
|
50
|
+
Module({
|
|
51
|
+
providers: [
|
|
52
|
+
{
|
|
53
|
+
provide: LAYOUT_OPTIONS,
|
|
54
|
+
multi: true,
|
|
55
|
+
useValue: {
|
|
56
|
+
wrappers: {
|
|
57
|
+
page: pageRenderHOC,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
provide: PAGE_RENDER_FALLBACK_COMPONENT_PREFIX,
|
|
63
|
+
useValue: 'pageRenderFallback',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
provide: PAGE_RENDER_DEFAULT_MODE,
|
|
67
|
+
useValue: 'ssr',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
})
|
|
71
|
+
], PageRenderModeModule);
|
|
72
|
+
|
|
73
|
+
export { PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT, PAGE_RENDER_DEFAULT_MODE, PAGE_RENDER_FALLBACK_COMPONENT_PREFIX, PageRenderModeModule };
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tslib = require('tslib');
|
|
6
|
+
var core = require('@tramvai/core');
|
|
7
|
+
var tokensRender = require('@tramvai/tokens-render');
|
|
8
|
+
var React = require('react');
|
|
9
|
+
var react = require('@tramvai/react');
|
|
10
|
+
var tokensRouter = require('@tramvai/tokens-router');
|
|
11
|
+
var moduleRouter = require('@tramvai/module-router');
|
|
12
|
+
var dippy = require('@tinkoff/dippy');
|
|
13
|
+
|
|
14
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
15
|
+
|
|
16
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
17
|
+
|
|
18
|
+
const PAGE_RENDER_FALLBACK_COMPONENT_PREFIX = dippy.createToken('pageRenderFallbackComponentName');
|
|
19
|
+
const PAGE_RENDER_DEFAULT_MODE = dippy.createToken('pageRenderDefaultMode');
|
|
20
|
+
const PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT = dippy.createToken('pageRenderDefaultFallbackComponent');
|
|
21
|
+
|
|
22
|
+
const PageRenderWrapper = ({ children }) => {
|
|
23
|
+
const [mounted, setMounted] = React.useState(false);
|
|
24
|
+
const { config } = moduleRouter.useRoute();
|
|
25
|
+
const pageService = react.useDi(tokensRouter.PAGE_SERVICE_TOKEN);
|
|
26
|
+
const fallbackKey = react.useDi(PAGE_RENDER_FALLBACK_COMPONENT_PREFIX);
|
|
27
|
+
const defaultRenderMode = react.useDi(PAGE_RENDER_DEFAULT_MODE);
|
|
28
|
+
const DefaultFallbackComponent = react.useDi({
|
|
29
|
+
token: PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT,
|
|
30
|
+
optional: true,
|
|
31
|
+
});
|
|
32
|
+
const { pageComponent, pageRenderMode } = config;
|
|
33
|
+
const { renderMode } = pageService.getComponent(pageComponent);
|
|
34
|
+
const FallbackComponent = pageService.resolveComponentFromConfig(fallbackKey) || DefaultFallbackComponent;
|
|
35
|
+
const mode = renderMode || pageRenderMode || defaultRenderMode;
|
|
36
|
+
React.useEffect(() => {
|
|
37
|
+
if (mode === 'client') {
|
|
38
|
+
setMounted(true);
|
|
39
|
+
}
|
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
+
}, []);
|
|
42
|
+
if (mode === 'client' && !mounted) {
|
|
43
|
+
if (FallbackComponent) {
|
|
44
|
+
return React__default["default"].createElement(FallbackComponent, null);
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return React__default["default"].createElement(React__default["default"].Fragment, null, children);
|
|
49
|
+
};
|
|
50
|
+
const pageRenderHOC = (WrapperPage) => (props) => {
|
|
51
|
+
return (React__default["default"].createElement(PageRenderWrapper, null,
|
|
52
|
+
React__default["default"].createElement(WrapperPage, Object.assign({}, props))));
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
exports.PageRenderModeModule = class PageRenderModeModule {
|
|
56
|
+
};
|
|
57
|
+
exports.PageRenderModeModule = tslib.__decorate([
|
|
58
|
+
core.Module({
|
|
59
|
+
providers: [
|
|
60
|
+
{
|
|
61
|
+
provide: tokensRender.LAYOUT_OPTIONS,
|
|
62
|
+
multi: true,
|
|
63
|
+
useValue: {
|
|
64
|
+
wrappers: {
|
|
65
|
+
page: pageRenderHOC,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
provide: PAGE_RENDER_FALLBACK_COMPONENT_PREFIX,
|
|
71
|
+
useValue: 'pageRenderFallback',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
provide: PAGE_RENDER_DEFAULT_MODE,
|
|
75
|
+
useValue: 'ssr',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
})
|
|
79
|
+
], exports.PageRenderModeModule);
|
|
80
|
+
|
|
81
|
+
exports.PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT = PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT;
|
|
82
|
+
exports.PAGE_RENDER_DEFAULT_MODE = PAGE_RENDER_DEFAULT_MODE;
|
|
83
|
+
exports.PAGE_RENDER_FALLBACK_COMPONENT_PREFIX = PAGE_RENDER_FALLBACK_COMPONENT_PREFIX;
|
package/lib/tokens.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ComponentType } from 'react';
|
|
2
|
+
import type { PageRenderMode } from '.';
|
|
3
|
+
export declare const PAGE_RENDER_FALLBACK_COMPONENT_PREFIX: string;
|
|
4
|
+
export declare const PAGE_RENDER_DEFAULT_MODE: PageRenderMode;
|
|
5
|
+
export declare const PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT: ComponentType<any>;
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare type PageRenderMode = 'ssr' | 'client';
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tramvai/module-page-render-mode",
|
|
3
|
+
"version": "1.72.2",
|
|
4
|
+
"description": "Enable different rendering modes for pages",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"module": "lib/index.es.js",
|
|
7
|
+
"typings": "lib/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"lib"
|
|
10
|
+
],
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git@github.com:Tinkoff/tramvai.git"
|
|
15
|
+
},
|
|
16
|
+
"license": "Apache-2.0",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tramvai-build --for-publish",
|
|
19
|
+
"watch": "tsc -w",
|
|
20
|
+
"build-for-publish": "true"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"registry": "https://registry.npmjs.org/"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@tinkoff/dippy": "0.7.38",
|
|
28
|
+
"@tramvai/core": "1.72.2",
|
|
29
|
+
"@tramvai/react": "1.72.2",
|
|
30
|
+
"@tramvai/module-router": "1.72.2",
|
|
31
|
+
"@tramvai/tokens-render": "1.72.2",
|
|
32
|
+
"@tramvai/tokens-router": "1.72.2",
|
|
33
|
+
"react": ">=16.8.0",
|
|
34
|
+
"tslib": "^2.0.3"
|
|
35
|
+
}
|
|
36
|
+
}
|