https://github.com/pspgbhu/rephic
💼 Rephic 是一个基于 Koa 的 React 服务端渲染工程脚手架。支持 React-Router, Redux 以及 Less, Sass。
https://github.com/pspgbhu/rephic
isomorphic koa react react-isomorphic react-rephic react-server-render rephic
Last synced: about 1 month ago
JSON representation
💼 Rephic 是一个基于 Koa 的 React 服务端渲染工程脚手架。支持 React-Router, Redux 以及 Less, Sass。
- Host: GitHub
- URL: https://github.com/pspgbhu/rephic
- Owner: pspgbhu
- License: mit
- Created: 2018-03-02T02:45:44.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2019-01-04T12:33:59.000Z (over 6 years ago)
- Last Synced: 2025-03-18T19:18:25.562Z (about 1 month ago)
- Topics: isomorphic, koa, react, react-isomorphic, react-rephic, react-server-render, rephic
- Language: JavaScript
- Homepage: http://blog.pspgbhu.me/article/react-isomorphic
- Size: 686 KB
- Stars: 22
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Rephic
Rephic 是一个基于 Koa 的 React 服务端渲染模板。支持 React-Router, Redux 以及 Less, Sass。
- [目录](#目录)
- [环境要求](#环境要求)
- [安装](#安装)
- [模板目录结构](#模板目录结构)
- [运行](#运行)
- [开发环境下运行](#开发环境下运行)
- [预览生产环境](#预览生产环境)
- [生产环境下运行](#生产环境下运行)
- [开发注意事项](#开发注意事项)
- [1. React 在服务端的生命周期和客户端的不同](#1-react-在服务端的生命周期和客户端的不同)
- [2. Node 环境中是不具备 DOM 和 BOM 相关API](#2-node-环境中是不具备-dom-和-bom-相关api)
- [3. 生产环境和开发环境下的静态文件来源的不同](#3-生产环境和开发环境下的静态文件来源的不同)
- [开发帮助](#开发帮助)
- [我该怎么在该脚手架的基础上继续开发页面?](#我该怎么在该脚手架的基础上继续开发页面)
- [如何正确的引入样式文件?](#如何正确的引入样式文件)
- [我想新增几个页面](#我想新增几个页面)
- [Nodemon 使用技巧](#nodemon-使用技巧)
- [Q&A](#qa)
- [1. 在开发环境下运行,页面打开时会出现一瞬间的页面无样式](#1-在开发环境下运行页面打开时会出现一瞬间的页面无样式)
- [2. 报错 'window is not defined' 或 'document is not defined'](#2-报错-window-is-not-defined-或-document-is-not-defined)
- [3. 暂不支持文件修改后自动刷新页面](#3-暂不支持文件修改后自动刷新页面)- Node.js >= 7.9
- PM2(用户生产环境)你可以通过 [smarter](https://github.com/jd-smart-fe/smarter) 脚手架生成工具来安装该模板:
```bash
$ sudo npm i -g smarter # 全局安装 smarter
$ smarter init rephic project # 生成项目到 project 目录下
$ cd project
$ npm i # 使用 npm 来安装项目依赖
```或者直接 clone 该项目:
```bash
$ git clone https://github.com/pspgbhu/rephic.git
$ cd rephic
$ rm -rf .git && git init # 重新初始化 git 仓库
$ npm i
```下面只列出了几个需要重点关注的目录文件
```bash
.
├── bin # 项目脚本文件
│ └── www # 服务端启动脚本
├── client # 客户端专用代码
│ ├── build # Webpack 配置
│ ├── entry # 入口文件目录,包含客户端和服务端的入口
│ ├── store # Redux 相关文件
│ └── App.jsx # React 根组件
└── server # 服务端专用代码
├── controller # 控制器层
├── service # 服务层
├── middlewares # 中间件
├── public # 静态资源
├── utils # 工具函数
├── views # 渲染模板
├── app.js # Node 服务入口文件
└── router.js # 路由
``````bash
# 启动 Node 服务,支持 Node, jsx, less 的热更新
npm run dev# 开发环境下打开页面,页面会在最开始一瞬间没有加载样式。
# 这个请不要担心,在生产环境下不存在这个问题。
```开发阶段 webpack 会将静态资源打包至 `node_modules/.cache/rephic/public/` 文件夹下。且开发环境下该文件夹和 `/server/public` 均为静态资源文件夹,且该文件夹下的资源匹配的优先级更高。
而生产环境下,`/server/public` 将是唯一的静态资源文件夹
上面我们提到,开发环境下打开页面,页面会在最开始一瞬间没有加载样式,在开发环境下不会出现。原因具体可以[参考这里](#1-在开发环境下运行页面打开时会出现一瞬间的页面无样式);
如果你还是担心线上生产环境的运行效果,可以使用下列命名来快速的已生产环境来运行代码:
```bash
npm start # 生产环境预览。仅用于预览,请勿作为生产环境运行。
``````bash
npm run build # 构建生产环境静态资源,将会更新 /public 文件下的资源
npm run prd # 启动 pm2
```服务端中 React 的生命周期只走到了 `componentWillMount()`。但是在客户端 React 拥有着完整的生命周期。
### 2. Node 环境中是不具备 DOM 和 BOM 相关API`/common` 中的同构代码在 Node 环境和浏览器环境下都会执行一遍,因此一定要注意的是,Node 没有 `window` `document` 等对象以及相关 API,如果在 Node 环境下执行了便会报错。
但是我们在很多场景下还是需要用到 DOM 和 BOM 的 API,这里还是有一些处理技巧的:
- Node 中 React 生命周期只会走到 `componentWillMount`,因此我们可以将一些 DOM 操作放在该生命周期之后的一些钩子中,比如在 `componentDidMount` 中来执行 DOM 或 BOM 的 API。
- 或者,我们可以使用一些安全判断来保证只在浏览器环境下才执行 DOM 操作。
```js
// node 中没有 document 全局对象,因此便不会执行括号中的代码。
if (document) {
document.querySelector('#example').classList.add('hide');
}
```生产环境静态资源目录
- `/server/public`
开发环境静态资源目录
- `/node_modules/.cache/rephic/public`
开发环境下的临时资源都会被打包进这个目录。静态资源会优先匹配这个目录下的文件。- `/server/public`
开发环境下,仍会加载这个目录的资源,只不过优先级较低。`/common` 是 React 的同构文件夹,全部的 React 逻辑都应该写在这个文件中,并将 `/common/App.jsx` 作为同构部分的入口文件。
我们需要将将全部的组件都写在 `/common` 文件夹下,写组件时还是依照之前的纯前端开发方式,然后将 `/common/App.jsx` 作为根组件即可。
请使用 `require` 而不是 `import` 来引入样式文件。
由于服务端无法处理也无须处理样式文件,我们便使用了 babel-register 的插件 babel-plugin-transform-require-ignore 来忽略掉 `['.css', '.less', '.sass', '.scss']` 这些后缀的文件。由于该插件的限制,我们必须要使用 `require` 命令来引入样式文件才能使这个插件正常工作。
在打包前端静态资源的时候,webpack 的 loader 会去处理对应的样式文件,目前默认支持 Less 和 Sass 样式处理器。
如果不准备使用 Redux 的话,只需要在 `/common` 中写好 React Router 的逻辑即可。
搭配 Redux 使用的话,请先参考 [Redux 服务端渲染](http://cn.redux.js.org/docs/recipes/ServerRendering.html)。
`/client/index.jsx` 作为浏览器环境下的入口文件,初始化了客户端的 Redux 初始数据。
服务端的 Redux Store 数据首先在 koa-router 中被创建,然后在 `/server/utils/render.jsx` 中被传递进 `/common/App.jsx` 组件中,然后 React 在服务端中便能像在前端中一样使用 Redux 中的数据了。
```js
// /routes/views/index.jsrouter.get('*', filterPageRoute, async (ctx) => {
//..
// 在服务端创建 Redux Store
const store = createStore(reducer, ctx.reactState || {}, applyMiddleware(thunk));
// 通过 renderStaticHtml 方法来讲 store 注入到 React 组件中
const content = renderStaticHtml({ ctx, store, context });
//..
});
```Nodemon 是一款非常实用的 Node.js 开发工具,它能够用来监控 Node.js 源代码的任何变化和自动重启你的服务器。这里有几个技巧或许可以帮到你。
1. **nodemon 启动后,在终端再次输入 rs 命令可以强制重启 Node.js 服务**
### 1. 在开发环境下运行,页面打开时会出现一瞬间的页面无样式在本地开发时,CSS 样式是通过 webpack 的 style-loader 打包在 JS 静态资源中的。待到 JS 静态资源在浏览器端执行时才将 JS 中的样式作为样式表通过 style 标签插入页面中的。
在浏览器请求回 HTML 文档,DOM 解析完毕后,一直到 JS 将样式表插入到页面中的这一段时间,页面会产生暂短的没有样式的情况。**这是开发环境下特有的一种情况。**
在生产环境下,webpack 会将 CSS 作为单独的一个文件打包出来,因此**生产环境下不会有这个问题。**
### 2. 报错 'window is not defined' 或 'document is not defined'参考 [注意事项 - Node 环境中是不具备 DOM 和 BOM 相关API](#markdown-2-node-环境中是不具备-dom-和-bom-相关api)
目前是用 nodemon 来检测 js 变动来重启 node 服务。目前并没有计划加入浏览器自动刷新的功能。