react-rack-cli搭建前端项目和node+express搭建后端项目实例

整个项目的最终目的是诞生一个类似csdn的技术博客。

一、react-rack-cli搭建前端项目

0. 首先要安装好node、git、和npm环境。

1. 先全局安装react-rack-cli脚手架

npm install -g react-rack-cli

然后执行以下命令可查看react-rack的版本号

react-rack --version

2. 安装完之后便可用react-rack命令,如果使用不了react-rack命令则说明该脚手架的路径没有添加到环境变量中的path中。具体路径(win7系统)为:右击我的电脑(或计算机)——属性——高级系统设置——环境变量——选择系统变量中的path并双击——将react-ract的安装路径添加进去。

3. 然后创建一个文件夹。

mkdir tech-blog-front   
// mkdir是make direction的缩写,tech-blog-front是前端项目名
cd tech-blog-front
// 进入tech-blog-front文件夹

随后要初始化创建的文件夹,输入命令:

react-rack init

4. 安装依赖。

npm install
// 或者 npm i (因为 i 是 install的缩写)

然后再安装需要用到的依赖,如react-dom、webpack、babel、ejs、router、redux等。如果安装过程中报错,错误信息为缺少某某时,继续安装这个提出的工具名即可。最后安装完之后的项目文件如下:

react-rack-cli搭建前端项目和node+express搭建后端项目实例_第1张图片

其中src文件夹是整个项目的核心,内部的文件构造如下图:

react-rack-cli搭建前端项目和node+express搭建后端项目实例_第2张图片

在打包命令之前,在根目录下创建一个logs文件夹

mkdir logs

5. 项目运行前,一般会用webpack将代码打包,打包之后会生成一个dist文件,浏览器渲染的就是dist里的文件,注意打包这个过程很吃内存,电脑配置高点最好,不然卡的你怀疑人生。打包命令为:

npm run build-dev

6. 打包之后,再输入命令启动项目。

node server.js

7. 命令窗口会显示项目启动在xxxx端口号,然后在浏览器里输入localhost:xxxx即可看到项目显示,如下图所示。

react-rack-cli搭建前端项目和node+express搭建后端项目实例_第3张图片

8. 目前react项目可使用ant design辅助开发工具,如果该开发工具中提供的组件没有你所需要的,那么可使用ant design pro,如果依旧没有,可参照ant design pro中的开发文档自己写组件。

ant design的功能比较强大,它不仅能适应于react,还可适用于vue;而博主以前介绍的iview只适用于vue,ant design与iview都是功能比较强大的插件,可以更好帮助开发人员工作,实用性较强。

9. 下面主要介绍一下主要项目文件的作用。

9.1 src文件夹里面主要放置的是项目代码,也就是需要你开发的地方,它里面又有多个子文件夹,如上上图所示。

其中actions里的index.js文件作用是定义并导出数据请求函数;

api文件夹下的api.js文件的作用是封装请求方法;home.js文件作用是定义异步请求函数,并返回相应的数据;index.js文件主要是封装请求的头部和处理一些其他必要的参数;

components文件夹下放置的是各个组件;

entries文件夹下的index.js文件主要是放置定义一些路由,即页面的跳转;

reducers文件夹下的index.js文件用于导出后台返回的数据(数据类型必须先初始化后再赋值);

store文件夹下的types.js文件的作用是让请求函数编译起来更方便,差不多给函数赋上一个镜像变量,这个变量的值可表示函数本身或返回的值;

static主要放置静态文件;

util文件夹放置的是一些方法的封装;

views文件夹下放置的是路由页面。

9.2 根目录下的views文件夹放置的是根页面;其他的文件顾名思义,就不做介绍了。

10. 开发项目的时候可根据实际所需,引用相应的插件,比如专用于图表制作的bizcharts

-------------------------------------------------------------------------------------------------------------------------------------

9102.05.05更新

为了更清晰的认知react前端项目数据请求怎么走的,下面以首页加载文章fetchNewArticles(params)为例。
在页面内发出该请求后,由于该项目是用redux来管理状态的,所以要对redux有一个基本的认识才好理解。

在发出fetchNewArticles(params)请求后,该函数会返回一个函数,且返回的函数中包含两个参数dispatch和getState,这是redux封装好了的,它们的作用分别是什么呢?

dispatch的作用是发送一个新的action,它是根据请求的结果来分发不同的action。如果请求失败,则走请求失败的action;成功则走成功的action;请求错误则走错误的action。
getState()返回的是一个对象,这个对象就厉害了,它掌控着整个项目所有数据的状态,算是redux的核心。比如,文章的id数组、热门文章的id数组等都是其下可枚举属性articles下的属性。如果用户的某个操作并未引起数据发生变化,则不会走请求函数;反之,走请求函数。

state:

​const initialState = {
    hotArticleIds: [],
    mainArticleIds:[]
}

// 获取热门文章 Id
export const getHotArticleIds = state => state.articles.hotArticleIds;

// 获取首页文章列表 Id
export const getMainArticleIds = state => state.articles.mainArticleIds;

dispatch:

import { actions as appActions } from "./app";

export const types = {
  FETCH_HOT_ARTICLES: 'ARTICLES/FETCH_HOT_ARTICLES',
  FETCH_ARTICLES: 'ARTICLES/FETCH_ARTICLES',
  FETCH_MORE_ARTICLES: 'ARTICLES/FETCH_MORE_ARTICLES',
}

// 加载首页文章列表
fetchNewArticles: (params, shouldFetch = true, isLoadMore = false) => {
  return (dispatch, getState) => {
    if (shouldFetch || shouldFetchMainArticles(getState())) {
      return getArticles(params).then(data => {
        if (data.status === 1) {
          dispatch(fetchArticlesSuccess(data , isLoadMore));
        } else {
          dispatch(appActions.setError(data.msg));
        }
      }).catch(err => {
        dispatch(appActions.setError(err));
      })
    }
  }
},

const shouldFetchMainArticles = (state) => {
  return state.articles.mainArticleTotal === 0 ||
    state.articles.mainArticleTotal > state.articles.mainArticleIds.length
}

const fetchArticlesSuccess = (data, isLoadMore) => ({
  type: isLoadMore ? types.FETCH_MORE_ARTICLES : types.FETCH_ARTICLES,
  articles,
  mainArticleIds,
});

这其中主要的请求函数是getArticles(),它会走api内的Ajax请求,即把请求正式发出给服务器。
另外,如果要想对redux有进一步认识,可查看阮神的Redux入门教程

------------------------------------------------------------------------------------------------------------

 

二、node+express搭建后台项目

1. 全局安装express-generator,执行以下命令:

npm install express-generator -g

2. 创建一个根目录并进入,执行以下命令:

express demo
cd demo

3. 安装依赖,执行以下命令:

npm i

会出现以下信息:

react-rack-cli搭建前端项目和node+express搭建后端项目实例_第4张图片

 继续执行命令:

npm audit fix

4. 查看生成的子目录与文件,如下图:

react-rack-cli搭建前端项目和node+express搭建后端项目实例_第5张图片

5. 运行后台环境,执行如下命令:

npm start

6. 虽然有了基础的后台开发环境,但是依旧缺少一些主要配置,比如数据库连接,api的设计,路由设计等等。那么接下来首先解决数据库连接的问题,而数据库的连接有两种形式。

6.1 数据库连接

6.1.1 本地连接
连接本地数据库可使用SQLyog Ultimate 64,百度下载破解版即可,然后打开新建连接,输入以下图示信息并点击连接

react-rack-cli搭建前端项目和node+express搭建后端项目实例_第6张图片

但是你会发现会出现提示框,提示框提示的错误为如下图示:

react-rack-cli搭建前端项目和node+express搭建后端项目实例_第7张图片

 这是因为SQLyog是数据库管理工具,所以要先开启本地数据库服务,即要下载mySQL并安装,然后开启。这里博主建议下载phpstudy,该程序包集成最新的Apache+PHP+MySQL+phpMyAdmin+ZendOptimizer,一次性安装,无须配置即可使用,是非常方便、好用的PHP调试环境。当然你也可以就选择下载MySQL并安装,只要你最后开启了本地MySQL服务就好。开启本地数据库之后,再点击SQLyog的连接,即可连接成功,再在里面创建表和填充少部分数据即可。

6.1.2 远程连接

远程连接数据库很简单,只需要把你的SQL主机地址、用户名、密码、端口和数据库填充进去,然后点击连接即可。

6.1.3 数据库配置config/config.js

const env = process.env.NODE_ENV;
let config = {};
//开发环境数据库配置
config = {
  db_host: 'xxxxxxxxxxxxxxxxx.mysql.rds.aliyuncs.com', //主机
  username: 'db_xxxxxxxx', //mysql数据库管理员
  password: 'xxxxxxxxxxxxx', //密码
  db_port: 3306, //端口
  db_name: 'xxxxxxxx', //数据库名
  dialect: 'mysql', // 数据库类型
  pool: {
    max: 5,
    min: 0,
    idle: 10000
  }, // 连接池配置
  salt:'smart',
  frontSalt: 'perfect'
};
module.exports = config;

6.2 管理数据库
一般来说我们需要一个ORM框架来管理数据层的代码,所以需要Sequelize插件来管理。dataBase/db.js

const config = require('../config/config.js');
const option = {
  host: config.db_host,
  pool: config.pool,
  port: config.db_port,
  dialect: config.dialect,
  operatorsAliases: false,
  define: {
    timestamps: false
  },
  timezone: '+08:00'
};
// 引入模块
const Sequelize = require('sequelize');
// 根据配置实例化sequelize
const sequelize = new Sequelize(config.db_name, config.username, config.password, option);
module.exports = {
  sequelize
};

 6.3 操作数据库
比如用户在注册的时候,这个时候数据表中需要插入一行新的数据,所以后台项目中还需要有一个文件夹用于放置操作数据库的js文件。sql/article.js

7. 若想查看后端代码详细的文件分布情况,可查阅:https://blog.csdn.net/Charles_Tian/article/details/89248855

 

三、前后端项目数据互通过程。

1. 前端的静态页面写好之后,就需要与后台进行数据对接,确保数据能正确显示在前端页面相应的位置上,而这个过程具体是通过哪些文件呢?

2. 一般情况下,前端发出的请求是在指定的页面内指定的可点击标签触发的,比如:我在登录界面触发的“登录”按钮,“登录”按钮上会绑定一个点击事件,用于触发登录请求,一般在前端目录src/views/Login/index.js内

3. 一旦触发了请求函数,而这个函数真正被执行是在src/actions/login.js内。若是新手刚进入项目中,你不知道执行文件在哪,那么以编辑器vs code为例,你选中登录函数名(以login为例),然后在这个文件里查询login,找到出现的第一个login,而这个login一般是以import { login } from '../../actions/login'的形式出现,如果不是,那你找到import { login } from '../../actions/login'这句即可,然后按住Ctrl健,再把鼠标移到 import 里的login上面,login会变蓝,且带下划线,然后点击左键,vs code自然会跳到actions/login.js文件,并显示login函数,非常方便。其实这也表示着,vs code工具是以代码运行的顺序(请求函数的逻辑走向)来帮助开发者寻找对应的“下家”,提高开发效率。

4. 按照同样的方法(复制函数名+crtl+左键),若是没有跳转到另一文件,那说明原先的开发者在未使用同样的函数名,这时,你需要回到文件(该文件是actions内的)的顶部,找到与login相关的import语句,以import { login_in } from '../api/login'为例,此时import里的是login_in,而不是login,所以跳转不了,这时应复制login_in,然后按照同样的方法,会发现文件跳转到了src/api/login.js内。

5. 在最新跳转的文件内,你会发现,真正发起Ajax请求的函数原来是在这里,下面给出代码示例:

import { AjaxServer } from './index';
/**
 * 登录
 * @param {*} params
 */
export async function login_in(params) {
  return AjaxServer('post', '/admin/user/login', {}, params);
}

请注意:下面的AjaxServer()内的路径是根据实际项目来的,而不是固定的,以我演示为例,这个是后台管理系统项目,登录的权限只有管理员才具备,所以放在了admin文件夹下,而admin的上一级目录是controllers。

6. 这个时候不能按照先前的方法去跳转了,因为这个时候已经不再是前端项目的事情了,而是要转到后端项目,后端项目的目录本文有链接https://blog.csdn.net/Charles_Tian/article/details/89248855查看,这里不再赘述。怎么找?打开后端项目代码,找到路由文件夹routers,然后在routers/adminRouter.js文件内找到login函数,按照同样的方法可跳转到cotrollers/admin/login.js。controllers文件夹内主要是保存后端接口即api,以我上述演示代码为例,再找到admin文件夹,再找到login.js文件,在该文件内找到与登录相关的函数,完整路径:cotrollers/admin/login.js

7. 第六步中找到了login函数,按照同样的方法(这里不再是函数名,而是函数内await 后面的函数名,以我的代码示例:函数名为getUser,这个才是发出了请求数据的函数),这时vs code不会跳转,但它会显示如下信息:

react-rack-cli搭建前端项目和node+express搭建后端项目实例_第8张图片

它会显示一个独立的窗口,窗口的最上方会显示接下来的文件在哪,你可根据这个路径去找,会发现在models文件夹下。即models/user.js内。

8. 然后在 user.js文件内查询“getUser”这个名字,会找到对应的函数,函数中return出来的结果就是要返回给后台的数据,示例:

/**
 * 获取用户  登录
 * @param {} poarams
 */
const getUser = async (params) => {
  const data = await Account.findAll({
    attributes: ['uuid', 'username', 'password', 'is_del'],
    where:params
  });
  return data;
};

9. 当然了,数据要从数据库里取出才有,因此对于数据库的操作封装在哪呢?很明显在sql文件夹下了,sql下会有一个user.js的文件,它里面就定义了众多的数据库操作,以我的代码为例:

const userSqlMap = {
  list: 'select * from account',
  getById: 'select * from account where uuid = ?',
  getInfoById:
    `SELECT
      ai.uuid,
      ai.name name,
      ai.avatar,
      ai.sex,
      ai.auth_name,
    FROM
      account_info AS ai
    JOIN
      article AS a
    ON
      ai.uuid = a.user_id
    WHERE
      ai.uuid = ?;`   // 获取个人中心用户信息
};

module.exports = userSqlMap;

跟数据库的操作很类似,只是写法有一点不同而已。

注意:上述代码均只演示了函数而已!并没有演示函数的导出或者一些必要的插件和文件的导入!一定要切记,你在定义函数的时候,函数内用到的一些变量如果不是函数内部定义的,那么必须要从其他路径通过import导入进来!

10. 后台管理系统流程总结:

前端部分开始--login界面发起请求(src/views/Login/index.js)--触发请求(src/actions/login.js)--发出请求(src/api/login.js)--前端部分结束--后端部分开始--发出的请求经过后端路由(routers/adminRouter.js)--对请求进行处理(controllers/admin/login.js)--对数据库进行操作(操作数据库的这个隐形过程在(sql/user.js))获取数据并返回(models/user.js)

你可能感兴趣的:(react,express,node)