{"id":16441961,"url":"https://github.com/pspgbhu/rephic","last_synced_at":"2025-03-23T08:31:59.100Z","repository":{"id":80416247,"uuid":"123521105","full_name":"pspgbhu/Rephic","owner":"pspgbhu","description":"💼 Rephic 是一个基于 Koa 的 React 服务端渲染工程脚手架。支持 React-Router, Redux 以及 Less, Sass。","archived":false,"fork":false,"pushed_at":"2019-01-04T12:33:59.000Z","size":702,"stargazers_count":22,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-18T19:18:25.562Z","etag":null,"topics":["isomorphic","koa","react","react-isomorphic","react-rephic","react-server-render","rephic"],"latest_commit_sha":null,"homepage":"http://blog.pspgbhu.me/article/react-isomorphic","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pspgbhu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-02T02:45:44.000Z","updated_at":"2023-04-20T20:13:22.000Z","dependencies_parsed_at":"2023-06-07T15:30:50.688Z","dependency_job_id":null,"html_url":"https://github.com/pspgbhu/Rephic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pspgbhu%2FRephic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pspgbhu%2FRephic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pspgbhu%2FRephic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pspgbhu%2FRephic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pspgbhu","download_url":"https://codeload.github.com/pspgbhu/Rephic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245078067,"owners_count":20557274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["isomorphic","koa","react","react-isomorphic","react-rephic","react-server-render","rephic"],"created_at":"2024-10-11T09:15:56.238Z","updated_at":"2025-03-23T08:31:59.080Z","avatar_url":"https://github.com/pspgbhu.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rephic\n\nRephic 是一个基于 Koa 的 React 服务端渲染模板。支持 React-Router, Redux 以及 Less, Sass。\n\n\u003ca id=\"markdown-目录\" name=\"目录\"\u003e\u003c/a\u003e\n## 目录\n\n\u003c!-- TOC depthFrom:2 --\u003e\n\n- [目录](#目录)\n- [环境要求](#环境要求)\n- [安装](#安装)\n- [模板目录结构](#模板目录结构)\n- [运行](#运行)\n    - [开发环境下运行](#开发环境下运行)\n    - [预览生产环境](#预览生产环境)\n    - [生产环境下运行](#生产环境下运行)\n- [开发注意事项](#开发注意事项)\n    - [1. React 在服务端的生命周期和客户端的不同](#1-react-在服务端的生命周期和客户端的不同)\n    - [2. Node 环境中是不具备 DOM 和 BOM 相关API](#2-node-环境中是不具备-dom-和-bom-相关api)\n    - [3. 生产环境和开发环境下的静态文件来源的不同](#3-生产环境和开发环境下的静态文件来源的不同)\n- [开发帮助](#开发帮助)\n    - [我该怎么在该脚手架的基础上继续开发页面？](#我该怎么在该脚手架的基础上继续开发页面)\n    - [如何正确的引入样式文件?](#如何正确的引入样式文件)\n    - [我想新增几个页面](#我想新增几个页面)\n    - [Nodemon 使用技巧](#nodemon-使用技巧)\n- [Q\u0026A](#qa)\n    - [1. 在开发环境下运行，页面打开时会出现一瞬间的页面无样式](#1-在开发环境下运行页面打开时会出现一瞬间的页面无样式)\n    - [2. 报错 'window is not defined' 或 'document is not defined'](#2-报错-window-is-not-defined-或-document-is-not-defined)\n    - [3. 暂不支持文件修改后自动刷新页面](#3-暂不支持文件修改后自动刷新页面)\n\n\u003c!-- /TOC --\u003e\n\n\u003ca id=\"markdown-环境要求\" name=\"环境要求\"\u003e\u003c/a\u003e\n## 环境要求\n\n- Node.js \u003e= 7.9\n- PM2（用户生产环境）\n\n\u003ca id=\"markdown-安装\" name=\"安装\"\u003e\u003c/a\u003e\n## 安装\n\n你可以通过 [smarter](https://github.com/jd-smart-fe/smarter) 脚手架生成工具来安装该模板：\n\n```bash\n$ sudo npm i -g smarter                     # 全局安装 smarter\n$ smarter init rephic project               # 生成项目到 project 目录下\n$ cd project\n$ npm i                                     # 使用 npm 来安装项目依赖\n```\n\n或者直接 clone 该项目：\n\n```bash\n$ git clone https://github.com/pspgbhu/rephic.git\n$ cd rephic\n$ rm -rf .git \u0026\u0026 git init                   # 重新初始化 git 仓库\n$ npm i\n```\n\n\u003ca id=\"markdown-模板目录结构\" name=\"模板目录结构\"\u003e\u003c/a\u003e\n## 模板目录结构\n\n下面只列出了几个需要重点关注的目录文件\n\n```bash\n.\n├── bin                   # 项目脚本文件\n│   └── www               # 服务端启动脚本\n├── client                # 客户端专用代码\n│   ├── build             # Webpack 配置\n│   ├── entry             # 入口文件目录，包含客户端和服务端的入口\n│   ├── store             # Redux 相关文件\n│   └── App.jsx           # React 根组件\n└── server                # 服务端专用代码\n    ├── controller        # 控制器层\n    ├── service           # 服务层\n    ├── middlewares       # 中间件\n    ├── public            # 静态资源\n    ├── utils             # 工具函数\n    ├── views             # 渲染模板\n    ├── app.js            # Node 服务入口文件\n    └── router.js         # 路由\n```\n\n\n\u003ca id=\"markdown-运行\" name=\"运行\"\u003e\u003c/a\u003e\n## 运行\n\n\u003ca id=\"markdown-开发环境下运行\" name=\"开发环境下运行\"\u003e\u003c/a\u003e\n### 开发环境下运行\n\n```bash\n# 启动 Node 服务，支持 Node, jsx, less 的热更新\nnpm run dev\n\n# 开发环境下打开页面，页面会在最开始一瞬间没有加载样式。\n# 这个请不要担心，在生产环境下不存在这个问题。\n```\n\n开发阶段 webpack 会将静态资源打包至 `node_modules/.cache/rephic/public/` 文件夹下。且开发环境下该文件夹和 `/server/public` 均为静态资源文件夹，且该文件夹下的资源匹配的优先级更高。\n\n而生产环境下，`/server/public` 将是唯一的静态资源文件夹\n\n\u003ca id=\"markdown-预览生产环境\" name=\"预览生产环境\"\u003e\u003c/a\u003e\n### 预览生产环境\n\n上面我们提到，开发环境下打开页面，页面会在最开始一瞬间没有加载样式，在开发环境下不会出现。原因具体可以[参考这里](#1-在开发环境下运行页面打开时会出现一瞬间的页面无样式);\n\n如果你还是担心线上生产环境的运行效果，可以使用下列命名来快速的已生产环境来运行代码：\n```bash\nnpm start       # 生产环境预览。仅用于预览，请勿作为生产环境运行。\n```\n\n\u003ca id=\"markdown-生产环境下运行\" name=\"生产环境下运行\"\u003e\u003c/a\u003e\n### 生产环境下运行\n\n```bash\nnpm run build   # 构建生产环境静态资源，将会更新 /public 文件下的资源\nnpm run prd     # 启动 pm2\n```\n\n\u003ca id=\"markdown-开发注意事项\" name=\"开发注意事项\"\u003e\u003c/a\u003e\n## 开发注意事项\n\n\u003ca id=\"markdown-1-react-在服务端的生命周期和客户端的不同\" name=\"1-react-在服务端的生命周期和客户端的不同\"\u003e\u003c/a\u003e\n### 1. React 在服务端的生命周期和客户端的不同\n\n服务端中 React 的生命周期只走到了 `componentWillMount()`。但是在客户端 React 拥有着完整的生命周期。\n\n\u003ca id=\"markdown-2-node-环境中是不具备-dom-和-bom-相关api\" name=\"2-node-环境中是不具备-dom-和-bom-相关api\"\u003e\u003c/a\u003e\n### 2. Node 环境中是不具备 DOM 和 BOM 相关API\n\n`/common` 中的同构代码在 Node 环境和浏览器环境下都会执行一遍，因此一定要注意的是，Node 没有 `window` `document` 等对象以及相关 API，如果在 Node 环境下执行了便会报错。\n\n但是我们在很多场景下还是需要用到 DOM 和 BOM 的 API，这里还是有一些处理技巧的：\n\n- Node 中 React 生命周期只会走到 `componentWillMount`，因此我们可以将一些 DOM 操作放在该生命周期之后的一些钩子中，比如在 `componentDidMount` 中来执行 DOM 或 BOM 的 API。\n- 或者，我们可以使用一些安全判断来保证只在浏览器环境下才执行 DOM 操作。\n  ```js\n  // node 中没有 document 全局对象，因此便不会执行括号中的代码。\n  if (document) {\n    document.querySelector('#example').classList.add('hide');\n  }\n  ```\n\n\u003ca id=\"markdown-3-生产环境和开发环境下的静态文件来源的不同\" name=\"3-生产环境和开发环境下的静态文件来源的不同\"\u003e\u003c/a\u003e\n### 3. 生产环境和开发环境下的静态文件来源的不同\n\n生产环境静态资源目录\n\n- `/server/public`\n\n开发环境静态资源目录\n\n- `/node_modules/.cache/rephic/public`\n    开发环境下的临时资源都会被打包进这个目录。静态资源会优先匹配这个目录下的文件。\n\n- `/server/public`\n    开发环境下，仍会加载这个目录的资源，只不过优先级较低。\n\n\u003ca id=\"markdown-开发帮助\" name=\"开发帮助\"\u003e\u003c/a\u003e\n## 开发帮助\n\n\u003ca id=\"markdown-我该怎么在该脚手架的基础上继续开发页面\" name=\"我该怎么在该脚手架的基础上继续开发页面\"\u003e\u003c/a\u003e\n### 我该怎么在该脚手架的基础上继续开发页面？\n\n`/common` 是 React 的同构文件夹，全部的 React 逻辑都应该写在这个文件中，并将 `/common/App.jsx` 作为同构部分的入口文件。\n\n我们需要将将全部的组件都写在 `/common` 文件夹下，写组件时还是依照之前的纯前端开发方式，然后将 `/common/App.jsx` 作为根组件即可。\n\n\u003ca id=\"markdown-如何正确的引入样式文件\" name=\"如何正确的引入样式文件\"\u003e\u003c/a\u003e\n### 如何正确的引入样式文件?\n\n请使用 `require` 而不是 `import` 来引入样式文件。\n\n由于服务端无法处理也无须处理样式文件，我们便使用了 babel-register 的插件 babel-plugin-transform-require-ignore 来忽略掉 `['.css', '.less', '.sass', '.scss']` 这些后缀的文件。由于该插件的限制，我们必须要使用 `require` 命令来引入样式文件才能使这个插件正常工作。\n\n在打包前端静态资源的时候，webpack 的 loader 会去处理对应的样式文件，目前默认支持 Less 和 Sass 样式处理器。\n\n\u003ca id=\"markdown-我想新增几个页面\" name=\"我想新增几个页面\"\u003e\u003c/a\u003e\n### 我想新增几个页面\n\n如果不准备使用 Redux 的话，只需要在 `/common` 中写好 React Router 的逻辑即可。\n\n搭配 Redux 使用的话，请先参考 [Redux 服务端渲染](http://cn.redux.js.org/docs/recipes/ServerRendering.html)。\n\n`/client/index.jsx` 作为浏览器环境下的入口文件，初始化了客户端的 Redux 初始数据。\n\n服务端的 Redux Store 数据首先在 koa-router 中被创建，然后在 `/server/utils/render.jsx` 中被传递进 `/common/App.jsx` 组件中，然后 React 在服务端中便能像在前端中一样使用 Redux 中的数据了。\n\n```js\n// /routes/views/index.js\n\nrouter.get('*', filterPageRoute, async (ctx) =\u003e {\n  //..\n  // 在服务端创建 Redux Store\n  const store = createStore(reducer, ctx.reactState || {}, applyMiddleware(thunk));\n  // 通过 renderStaticHtml 方法来讲 store 注入到 React 组件中\n  const content = renderStaticHtml({ ctx, store, context });\n  //..\n});\n```\n\n\u003ca id=\"markdown-nodemon-使用技巧\" name=\"nodemon-使用技巧\"\u003e\u003c/a\u003e\n### Nodemon 使用技巧\n\nNodemon 是一款非常实用的 Node.js 开发工具，它能够用来监控 Node.js 源代码的任何变化和自动重启你的服务器。这里有几个技巧或许可以帮到你。\n\n1. **nodemon 启动后，在终端再次输入 rs 命令可以强制重启 Node.js 服务**\n\n\u003ca id=\"markdown-qa\" name=\"qa\"\u003e\u003c/a\u003e\n## Q\u0026A\n\n\u003ca id=\"markdown-1-在开发环境下运行页面打开时会出现一瞬间的页面无样式\" name=\"1-在开发环境下运行页面打开时会出现一瞬间的页面无样式\"\u003e\u003c/a\u003e\n### 1. 在开发环境下运行，页面打开时会出现一瞬间的页面无样式\n\n在本地开发时，CSS 样式是通过 webpack 的 style-loader 打包在 JS 静态资源中的。待到 JS 静态资源在浏览器端执行时才将 JS 中的样式作为样式表通过 style 标签插入页面中的。\n\n在浏览器请求回 HTML 文档，DOM 解析完毕后，一直到 JS 将样式表插入到页面中的这一段时间，页面会产生暂短的没有样式的情况。**这是开发环境下特有的一种情况。**\n\n在生产环境下，webpack 会将 CSS 作为单独的一个文件打包出来，因此**生产环境下不会有这个问题。**\n\n\u003ca id=\"markdown-2-报错-window-is-not-defined-或-document-is-not-defined\" name=\"2-报错-window-is-not-defined-或-document-is-not-defined\"\u003e\u003c/a\u003e\n### 2. 报错 'window is not defined' 或 'document is not defined'\n\n参考 [注意事项 - Node 环境中是不具备 DOM 和 BOM 相关API](#markdown-2-node-环境中是不具备-dom-和-bom-相关api)\n\n\u003ca id=\"markdown-3-暂不支持文件修改后自动刷新页面\" name=\"3-暂不支持文件修改后自动刷新页面\"\u003e\u003c/a\u003e\n### 3. 暂不支持文件修改后自动刷新页面\n\n目前是用 nodemon 来检测 js 变动来重启 node 服务。目前并没有计划加入浏览器自动刷新的功能。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpspgbhu%2Frephic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpspgbhu%2Frephic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpspgbhu%2Frephic/lists"}