Skip to content

Commit

Permalink
docs: ssr (umijs#2963)
Browse files Browse the repository at this point in the history
* 📝 ssr doc

* init

* 📝 docs

* 📝 diff

* 📝 docs

* 📝 doc

* 📝 init

* fix: optionDeps

* 📝 http server usage

* 📝 pre-render

* 📝 umi ssr docs

* docs: pre render TODO

* 📝 docs

* 📝 prerender

* 📝 readme

* 📝 styled-components SSR, Close umijs#3508.
  • Loading branch information
ycjcl868 authored and sorrycc committed Oct 31, 2019
1 parent b65a74e commit d0db7e4
Show file tree
Hide file tree
Showing 11 changed files with 445 additions and 3 deletions.
8 changes: 8 additions & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
module.exports = {
title: 'UmiJS',
markdown: {
extendMarkdown: md => {
md.use(require('../../website/node_modules/markdown-it-plantuml'));
md.use(require('../../website/node_modules/markdown-it-task-lists'));
},
},
locales: {
'/': {
lang: 'en-US',
Expand Down Expand Up @@ -62,6 +68,7 @@ module.exports = {
'with-dva',
'load-on-demand',
'runtime-config',
'ssr',
'block',
'deploy',
'develop-umi-ui-plugin',
Expand Down Expand Up @@ -133,6 +140,7 @@ module.exports = {
'with-dva',
'load-on-demand',
'runtime-config',
'ssr',
'block',
'deploy',
'develop-umi-ui-plugin',
Expand Down
6 changes: 6 additions & 0 deletions docs/.vuepress/styles/index.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.contains-task-list {
padding-left: 0;
li {
list-style-type: none;
}
}
8 changes: 8 additions & 0 deletions docs/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,11 @@ const App = dynamic({
### umi/babel

Make umi's babel configuration extensible.

## Server-Side Render

### umi-server

```bash
$ npm install umi-server -S
```
21 changes: 20 additions & 1 deletion docs/guide/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,30 @@ Use in css, be careful not to use absolute paths

### document is not defined, navigator is not defined, \* is not not defined

Why: umiJS SSR executes code first server-side, then client-side. The `document`, `navigator` object is only present client-side. Solution:
Why: Umi SSR executes code first server-side, then client-side. The `document`, `navigator` object is only present client-side. Solution:

1. you absolutely need to have access to it in some React component, you should put that code in `componentDidMount` or `useEffect`. This lifecycle method will only be executed on the client.
1. add the judgment with something like `typeof navigator !== 'undefined'` or `typeof document !== 'undefined'`

### SSR has no style, style loading is wrong

Why: The [publicPath](https://umijs.org/config/#publicpath) of the Umijs configuration does not match the route of the server. When the resource path such as `/umi.js` is accessed, it is not mapped correctly to the specified file. solution:

1. Try to access the link `http://yourHost/umi.js` or `http://yourHost/dist/umi.js` to see which link returns the correct js/css file contents.
1. Correspond to modify the `publicPath` path.

### styled-components build error

Add [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components) babel pluign. [#3508](https://github.com/umijs/umi/issues/3508#issuecomment-546610547)

```js
// .umirc.js
extraBabelPlugins: [
"babel-plugin-styled-components"
],
```


## UMI UI

### Umi version is too low, please upgrade to [email protected] or above
Expand Down
3 changes: 3 additions & 0 deletions docs/guide/pre-render.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Pre-rendering

TODO
183 changes: 183 additions & 0 deletions docs/guide/ssr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
---
sidebarDepth: 3
---

# Server-side render

<Badge text="Support in 2.8.0+"/>

<!-- [[toc]] -->

## Introduction

### What is server-side render?

Server-Side Render means that a single-page application (SPA) is rendered as an HTML fragment on the server side, sent to the browser, and then bound to the state and events to become a fully interactive page. the process of.

@startuml
actor "User/Crawler" as user
participant "Server" as server

user -> server : Access
server -> server: server-side render
server -> user: <div id="root">\n...content...\n</div>

@enduml

### Differences from CSR(Client-Side render)

> Subsequently referred to as server-side render as SSR, client-side render as CSR
As shown below:

@startuml
'skinparam handwritten true
'default
top to bottom direction
actor "User/Crawler" as user
' centered
cloud "SSR" as ssr
' centered
cloud "CSR" as csr
user <--> (ssr)
user <--> (csr)

note left of (user)
<div id="root">
...<div>content</div>...
</div>
end note

note right of (user)
<div id="root"></div>
end note

@enduml

The advantages of SSR are:

- **More friendly SEO** : The crawler can directly grab the rendered page. The first time the CSR returns the HTML document, it is an empty node (root) and contains no content. The SSR returns the HTML fragment after rendering, the content is complete, so it can be better analyzed and indexed by the crawler.
- **Faster first screen loading speed**: Show content without waiting for JavaScript to complete the download and execution, and see the fully rendered page faster. Have a better user experience.
- Requires server support: Umijs focuses on application **UI layer rendering**, and SSR requires server (eg Node.js) support.

### Umi SSR features

- [x] Server framework is not relevant
- [x] Support CSS Modules
- [x] Support TypeScript
- [x] Support local development HMR
- [x] Support dva
- [ ] Support Serverless

## Usage

### Umi Configuration

Turn on `ssr: true` in [config file](/guide/config.html#configuration-file), [more Configuration](/config/#ssr):

```js
export default {
ssr: true,
};
```

After enable, running `umi build` will generate the following files:

```bash
.
├── dist
│   ├── index.html
│   ├── ssr-client-mainifest.json
│   ├── umi.css
│   ├── umi.js
│   └── umi.server.js
```

### Server-Side

Regardless of the server-side framework, Umijs focuses on application **UI layer rendering**, which is not coupled to the server-side framework.

In order to reduce the server framework access threshold, Umi provides [umi-server](https://npmjs.com/package/umi-server) and uses the common Node.js server framework ([Koajs](https://koajs.com), [Express](https://expressjs.com/), [Egg.js](https://eggjs.org/)), for example, give specific access methods.

#### Use http module

Use the Node.js native [http](http://nodejs.org/api/http.html#http_http) module to do server-side rendering.

```js
// bar.js
const server = require('umi-server');
const http = require('http');
const { createReadStream } = require('fs');
const { join, extname } = require('path');

const root = join(__dirname, 'dist');
const render = server({
root,
})
const headerMap = {
'.js': 'text/javascript',
'.css': 'text/css',
'.jpg': 'image/jpeg',
'.png': 'image/jpeg',
}

http.createServer(async (req, res) => {
const ext = extname(req.url);
const header = {
'Content-Type': headerMap[ext] || 'text/html'
}
res.writeHead(200, header);

if (!ext) {
// url render
const ctx = {
req,
res,
}
const { ssrHtml } = await render(ctx);
res.write(ssrHtml);
res.end()
} else {
// static file url
const path = join(root, req.url);
const stream = createReadStream(path);
stream.on('error', (error) => {
res.writeHead(404, 'Not Found');
res.end();
});
stream.pipe(res);
}

}).listen(3000)

console.log('http://localhost:3000');
```

Running `node bar.js` and accessing [http://localhost:3000](http://localhost:3000) is a simple example of server-side rendering. learn more [examples/normal](https://github.com/umijs/umi-server/tree/master/examples/normal)

![image](https://user-images.githubusercontent.com/13595509/67446985-0e069700-f645-11e9-85c6-b2ce7f977f74.png)

#### Koa.js

refer to [examples/koajs](https://github.com/umijs/umi-server/tree/master/examples/koajs)


#### Egg.js

refer to [examples/eggjs](https://github.com/umijs/umi-server/tree/master/examples/eggjs)

### Pre Render

Pre Render performs rendering at build time, and renders the rendered HTML snippet into a static html file. No need to use a web server to dynamically compile HTML in real time, **for static sites**.

Umi provides the [@umijs/plugin-prerender](https://www.npmjs.com/package/@umijs/plugin-prerender) plugin to help users pre-render the page at build time. For more usage, please refer to [documentation](https://github.com/umijs/umi-server/tree/master/packages/umi-plugin-prerender).

```js
export default {
plugins: [['@umijs/plugin-prerender', options]],
};
```

### Problems

see [FAQ](https://umijs.org/guide/faq.html#ssr)
9 changes: 9 additions & 0 deletions docs/zh/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,12 @@ const App = dynamic({
### umi/babel

让用户可基于 umi 的 babel 配置进行扩展。


## 服务器端渲染

### umi-server

```bash
$ npm install umi-server -S
```
20 changes: 19 additions & 1 deletion docs/zh/guide/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,29 @@ export default Header;

### document is not defined, navigator is not defined, \* is not not defined

原因:umiJS SSR 先执行服务端代码,再执行客户端。`document``navigator` 等对象只在客户端使用。解决方案:
原因:Umi SSR 先执行服务端代码,再执行客户端。`document``navigator` 等对象只在客户端使用。解决方案:

1. 建议将使用到客户端对象的代码,放在 `componentDidMount``useEffect` 中(服务端不会执行),避免过多副作用代码影响服务端渲染。
1. 在这些对象前加上判断 `typeof navigator !== 'undefined'``typeof document !== 'undefined'`

### SSR 没有样式,样式加载不对

原因:Umijs 配置的 [publicPath](https://umijs.org/zh/config/#publicpath) 未匹配服务端的路由。导致访问 `/umi.js` 等资源路径时,未正确映射到指定文件。解决方案:

1. 试着访问链接 `http://yourHost/umi.js``http://yourHost/dist/umi.js` 看哪个链接能返回正确的 js/css 文件内容。
1. 对应修改 `publicPath` 路径。

### styled-components 编译失败

添加 [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components) babel 插件。[#3508](https://github.com/umijs/umi/issues/3508#issuecomment-546610547)

```js
// .umirc.js
extraBabelPlugins: [
"babel-plugin-styled-components"
],
```

## UMI UI

### Umi 版本过低,请升级到最新
Expand Down
3 changes: 3 additions & 0 deletions docs/zh/guide/pre-render.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 预渲染

TODO
Loading

0 comments on commit d0db7e4

Please sign in to comment.