Skip to content
/ Rephic Public

💼 Rephic 是一个基于 Koa 的 React 服务端渲染工程脚手架。支持 React-Router, Redux 以及 Less, Sass。

License

Notifications You must be signed in to change notification settings

pspgbhu/Rephic

Repository files navigation

Rephic

Rephic 是一个基于 Koa 的 React 服务端渲染模板。支持 React-Router, Redux 以及 Less, Sass。

目录

环境要求

  • Node.js >= 7.9
  • PM2(用户生产环境)

安装

你可以通过 smarter 脚手架生成工具来安装该模板:

$ sudo npm i -g smarter                     # 全局安装 smarter
$ smarter init rephic project               # 生成项目到 project 目录下
$ cd project
$ npm i                                     # 使用 npm 来安装项目依赖

或者直接 clone 该项目:

$ git clone https://github.com/pspgbhu/rephic.git
$ cd rephic
$ rm -rf .git && git init                   # 重新初始化 git 仓库
$ npm i

模板目录结构

下面只列出了几个需要重点关注的目录文件

.
├── bin                   # 项目脚本文件
│   └── www               # 服务端启动脚本
├── client                # 客户端专用代码
│   ├── build             # Webpack 配置
│   ├── entry             # 入口文件目录,包含客户端和服务端的入口
│   ├── store             # Redux 相关文件
│   └── App.jsx           # React 根组件
└── server                # 服务端专用代码
    ├── controller        # 控制器层
    ├── service           # 服务层
    ├── middlewares       # 中间件
    ├── public            # 静态资源
    ├── utils             # 工具函数
    ├── views             # 渲染模板
    ├── app.js            # Node 服务入口文件
    └── router.js         # 路由

运行

开发环境下运行

# 启动 Node 服务,支持 Node, jsx, less 的热更新
npm run dev

# 开发环境下打开页面,页面会在最开始一瞬间没有加载样式。
# 这个请不要担心,在生产环境下不存在这个问题。

开发阶段 webpack 会将静态资源打包至 node_modules/.cache/rephic/public/ 文件夹下。且开发环境下该文件夹和 /server/public 均为静态资源文件夹,且该文件夹下的资源匹配的优先级更高。

而生产环境下,/server/public 将是唯一的静态资源文件夹

预览生产环境

上面我们提到,开发环境下打开页面,页面会在最开始一瞬间没有加载样式,在开发环境下不会出现。原因具体可以参考这里;

如果你还是担心线上生产环境的运行效果,可以使用下列命名来快速的已生产环境来运行代码:

npm start       # 生产环境预览。仅用于预览,请勿作为生产环境运行。

生产环境下运行

npm run build   # 构建生产环境静态资源,将会更新 /public 文件下的资源
npm run prd     # 启动 pm2

开发注意事项

1. React 在服务端的生命周期和客户端的不同

服务端中 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 操作。
    // node 中没有 document 全局对象,因此便不会执行括号中的代码。
    if (document) {
      document.querySelector('#example').classList.add('hide');
    }

3. 生产环境和开发环境下的静态文件来源的不同

生产环境静态资源目录

  • /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 服务端渲染

/client/index.jsx 作为浏览器环境下的入口文件,初始化了客户端的 Redux 初始数据。

服务端的 Redux Store 数据首先在 koa-router 中被创建,然后在 /server/utils/render.jsx 中被传递进 /common/App.jsx 组件中,然后 React 在服务端中便能像在前端中一样使用 Redux 中的数据了。

// /routes/views/index.js

router.get('*', filterPageRoute, async (ctx) => {
  //..
  // 在服务端创建 Redux Store
  const store = createStore(reducer, ctx.reactState || {}, applyMiddleware(thunk));
  // 通过 renderStaticHtml 方法来讲 store 注入到 React 组件中
  const content = renderStaticHtml({ ctx, store, context });
  //..
});

Nodemon 使用技巧

Nodemon 是一款非常实用的 Node.js 开发工具,它能够用来监控 Node.js 源代码的任何变化和自动重启你的服务器。这里有几个技巧或许可以帮到你。

  1. nodemon 启动后,在终端再次输入 rs 命令可以强制重启 Node.js 服务

Q&A

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

3. 暂不支持文件修改后自动刷新页面

目前是用 nodemon 来检测 js 变动来重启 node 服务。目前并没有计划加入浏览器自动刷新的功能。

About

💼 Rephic 是一个基于 Koa 的 React 服务端渲染工程脚手架。支持 React-Router, Redux 以及 Less, Sass。

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published