@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 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
+ ```
@@ -0,0 +1,3 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ export declare const PageRenderWrapper: ({ children }: PropsWithChildren<{}>) => JSX.Element;
3
+ export declare const pageRenderHOC: (WrapperPage: any) => (props: any) => JSX.Element;
package/lib/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export * from './tokens';
3
+ export declare class PageRenderModeModule {
4
+ }
@@ -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;
@@ -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
+ }