最近想跟着教程,尝试用React做一个SPA项目。记录一下大致的流程。

1. 搭建react开发环境

使用 react-create-app 脚手架,搭建react开发环境。默认已装好 npm 和 nodejs,终端输入:

> npm install -g react-create-app
> create-react-app folder-name

这时就已经搭建好了react开发环境。

编码测试
在项目文件夹中运行:

> npm start

访问 http://localhost:3000/ 查看。

打包发布
在项目文件夹中运行:

> npm run build
> npm install -g serve
> serve build

访问 http://localhost:5000/ 查看。

2. 设计前端源码目录

根据项目的具体需求,在 src 文件夹中创建相关文件夹,以及入口文件index.js。
如 src 文件夹中包括 components、containers、redux、assets、api 等。

3. 下载相关的库

根据项目的具体需求,下载项目所需组件库包。
如:

  • antd-mobile
  • react-app-rewired 用于扩展 webpack 配置
    react 方便之处在于把webpack等配置封装起来,这方便了使用,但不方便修改webpack配置。react-app-rewired 是一个开源的工具,下载后可以通过创建一个 config-overrides.js 文件来对 webpack 配置进行扩展。
    使用方法可以参考 https://github.com/timarney/react-app-rewired#3-flip-the-existing-calls-to-react-scripts-in-npm-scripts
  • babel-plugin-import
    按需加载,详细可以参考 https://mobile.ant.design/docs/react/use-with-create-react-app-cn

自定义主题
antd-mobile 设计规范上支持一定程度的样式定制,以满足业务和品牌上多样化的视觉需求,包括但不限于主色、圆角、边框和部分组件的视觉定制。 

> npm install --save-dev less@2.7.3 less-loader

 

  1. 引入路由
  • 下载 react-router-dom
  • 创建路由组件
    在 containers 文件夹下创建各组件,如注册界面组件(Register.jsx),登陆界面组件(Login.jsx),主页面组件等。
  • 映射路由
    如,入口 js 文件:
<HashRouter>
    <Switch>
        <Route path='/register' component={Register}></Route>
        <Route path='/login' component={Login}></Route>
        <Route component={Main}></Route>
    </Switch>
</HashRouter>
  • 路由链接 & 非路由链接
    区别:是否发了请求,发了请求则是非路由链接(如a标签);没有发请求,则是路由链接(如NavLink标签)。

5. 引入React-Redux

随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状态)。 这些 state 可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等。管理不断变化的 state 非常困难,Redux 试图让 state 的变化变得可预测。

Redux中文文档React-Redux中文文档

  • 下载相关依赖包
> npm install --save redux@3.7.2 react-redux redux-thunk
> npm install --save-dev redux-devtools-extension

Action 发出以后,Reducer 立即算出 State,这叫做同步;Action 发出以后,过一段时间再执行 Reducer,这就是异步。

  • React-Redux 的用法 React 项目开发中使用到 React-Redux 这个库,也就是我们上面下载的依赖包。这篇博客介绍了 UI组件容器组件connect方法<Provider> 组件。

6. 搭建后台应用

(1)Node + express 应用

用 vscode 创建 Node + express 应用

  • 下载 express
> npm install express -g
  • 创建项目
> express folder-name
> cd folder-name
> npm install
  • ejs 模板引擎
    下载依赖包
> npm install ejs --save

app.js 中修改:

+ app.engine('.html', require('ejs').__express);
- app.set('view engine', 'jade');
+ app.set('view engine', 'ejs');

再将 view 文件夹中 index.jade 更改为 index.ejs,内容修改为:

<!DOCTYPE html>
<html>
  <head>    
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>

    <%= title %>
    
  </body>
</html>
  • 运行
    /bin 文件夹中 www 文件,指定了端口号:
var port = normalizePort(process.env.PORT || '4000');
app.set('port', port);

运行 npm start 后可在对应端口打开。

(2)Postman工具

Postman 提供功能强大的 Web API 和 HTTP 请求的调试,它能够发送任何类型的HTTP 请求 (GET, POST, PUT, DELETE…),并且能附带任何数量的参数和 Headers。不仅如此,它还提供测试数据和环境配置数据的导入导出,付费的 Post Cloud 用户还能够创建自己的 Team Library 用来团队协作式的测试,并能够将自己的测试收藏夹和用例数据分享给团队。

简而言之,我们可以用postman模拟数据请求和后台响应的过程。

react 打包为docker镜像 react打包流程_react 打包为docker镜像


下载及安装可以参考 https://www.jianshu.com/p/451e0d009304

使用教程可以参考

(3)后台应用自动重运行

使用 nodemon 包,使得修改后台任何代码, 会自动重新运行最新的代码。

  • 下载依赖包
> npm install --save-dev nodemon
  • 配置
    修改 package.json 文件:
- "start": "node ./bin/www"
+ "start": "nodemon ./bin/www"
(4)操作数据库

数据库使用的是MongoDB,所以使用 mongoose 操作数据库。

  • 下载安装 mongodb
    MongoDB的下载、安装和配置可以参考:
    可以勾选下载 MongoDB Compass Community,可以通过该软件很方便地查看数据库的内容。
  • 下载 mongoose 依赖包和加密依赖包
> npm install --save mongoose blueimp-md5

对数据库的操作一般分三步:

  1. 连接数据库
  2. 得到对应特定集合的 Model
  3. 通过 Model 或其实例对集合数据进行操作(如保存、删除、替换、查找等)

其中对集合数据进行操作,一般写在后台的路由组件(router)里,所以需要将特定集合的Model暴露出去,可以使用 module.exportsexports 导出模块。

8. 前台处理

(1)封装ajax
  • 下载相关依赖包
> npm install --save axios

可以调用 axios 的 get 和 post 方法,返回 promise对象。

  • api/ajax.js
    使用 axios 封装的 ajax 请求函数(下载 axios 依赖包)。传入的参数:url参数数据请求方式,函数返回:promise 对象认识和使用promise)。
  • api/index.js
    接口的入口文件,包含n个接口请求函数(向外暴露该模块),通过调用ajax.js文件,每个请求函数返回的都是promise对象。
  • 配置 ajax 请求的代理
    由于前后台端口不同,所以前台向后台的请求是跨域请求,需要配置代理服务器,实现跨域请求。
    package.json
"proxy": "http://localhost:4000"
(2)使用 redux 管理用户信息
  • action-types.js
    action类型,如:请求成功(AUTH_SUCCESS)和错误(ERROR_MSG)。
  • action.js
    通过封装的ajax,向服务器发送请求(跨域请求的处理);
    通过服务器返回的response,判断请求是否成功。
    注意:await 的使用,可以参考:
  • reducers.js
    包含用于生成新的 state 的 reducer 函数。定义defaultState,根据不同 action,返回相对应新的 state。
  • connect 方法
    在路由组件中调用 connect方法,从 UI 组件生成容器组件。

至此,可以基本实现浏览器页面提交表单给后台服务器,后台服务器操作数据库(存储、查找),再返回响应数据给前端页面的功能。

踩坑记录

1. “The “injectBabelPlugin” helper has been deprecated as of v2.0.” 报错

react 打包为docker镜像 react打包流程_React_02

解决方法1
react-app-rewired 降级到2.x以下。终端输入:

> npm install react-app-rewired@2.0.2-next.0

解决方法2
安装 customize-cra

> npm install react-app-rewired customize-cra

然后需要配置 config-overrides.js 文件,详见 链接 再运行 npm start 就不会出现报错了。

2. Uncaught (in promise) Error: Request failed with status code 500

react 打包为docker镜像 react打包流程_react 打包为docker镜像_03


解决方法

把 await 命令放在 try…catch 代码块中。

3. Error: Request failed with status code 500

react 打包为docker镜像 react打包流程_react 打包为docker镜像_04


response的内容是:

Proxy error: Could not proxy request /register from localhost:3000 to http://localhost:4000/.

See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (HPE_INVALID_VERSION).

这个真的坑了我快两天(摔!)从代理、服务端接收程序、前台发送请求,挨个排查,各种谷歌百度bing。。。首先排除了后台接收程序代码方面的问题,因为用postman传值可以成功返回响应;其次排除前台发送请求代码方面的问题,因为向同一端口发送请求,则可以成功返回响应;最后,很久之后,我突发奇想,把端口号给改了,4000改成5000,重启了一下数据库,然后就好了。。。我要晕掉了。。。不过在调试过程中,我不得不先补习了一下axios、nodejs、express、正反向代理,复习了一下创建React项目的流程,还顺便清理了浏览器cookie、更改了win10下localhost的解析(不要问我为什么。。贴一下教程。。 )要枯了,好在最后解决了。

4. Module not found: Can’t resolve ‘./images/${text}.png’ in xxx

在react中动态导入,使用require时报了上述错误,百思不得其解。报错的代码如下:

react 打包为docker镜像 react打包流程_react 打包为docker镜像_05


解决方法

emm基础知识欠缺,这里用了ES6的模板字符串,应该是反引号``。