教你用三天時間擼個論壇(react+egg.js包括上線)

我依舊已久發表於2019-02-27

引言

論壇系統也是一個很經典的系統了,很多人大學的時候估計也寫過,但是三天就能從開寫到部署上線這是以前怎麼也不敢想的,得益於現代前端工作流和一些優秀開源框架,讓這成為可能。能很快看到自己寫的東西部署在網上,相信帶來的成就感也是推動很多人持續學習的動力吧。

需要用到的

前端:react、react-redux、antd、axios、stylus

後端:egg.js

資料庫相關:mysql、sequelize

其他:postman、jwt、Nginx、七牛雲等...

目錄結構

client + service ,前端主要看src下,後端主要看app下

教你用三天時間擼個論壇(react+egg.js包括上線)

教你用三天時間擼個論壇(react+egg.js包括上線)

前端

樣式部分

我這裡前端部分沒有采用create-react-app腳手架搭建,是自己用webpack搭建的,對webpack不熟的同學建議直接用官方腳手架。因為這個專案只用了三天,所以樣式大部分使用antd,種類多,啥元件都有,又好看(強勢安利一波)。

資料管理

資料管理用的是redux,目前來說主要是使用者登入後的個人資訊管理。建立了store資料夾來放置actions和reducers。建立一個全域性的store樹,以後哪個元件需要使用者資訊只需要connect一下就可以直接從store裡面拿資料了。但是修改的話就需要dispatch一個action,這樣就保證了資料的統一性。

資料請求

請求資料用的是axios,先axios.create()建立一個例項,然後在例項上配置了interceptors攔截器,對返回的結果進行攔截處理。

  const instance = axios.create({
  xsrfCookieName: 'xsrf-name',
  baseURL: baseDomain
});

instance.interceptors.response.use(function(response) {
  if (response.data.success) {
    return Promise.resolve(response.data)
  } else {
    notification['error']({
      message: response.data.message
    });
    return Promise.reject({
      message: response.data.message
    })
  }
}, function(error) {
  try {
    notification['error']({
      message: error.response.data.message || '系統異常'
    })
    console.log(error.response.status)
    if (error.response.status === 401) {
      setTimeout(() => {
        window.location.href = '/login';
      }, 2000);
    }
  } catch(e) {
    notification['error']({
      message: '系統異常, 請稍後再試!'
    })
  }
  return Promise.reject({
    messageCode: 'sysError'
  })
})
複製程式碼

tips: 開發時跨域是通過devserver 轉發請求實現的。

後端

專案搭建直接用官方腳手架egg-init egg-example --type=simple。一般在實際應用中,Controller 一般不會自己產出資料,也不會包含複雜的邏輯,複雜的過程應抽象為業務邏輯層Service,所以我們主要的業務邏輯還是在service裡面完成,然後把結果返回給controller就可以了。詳細的CRUD就不具體說了,這裡說幾個關鍵點。

context的擴充

框架會把 app/extend/context.js中定義的物件與Context的prototype物件進行合併,在處理請求時會基於擴充套件後的 prototype 生成 ctx 物件。我們可以在這裡獲得一些資料,比如說在這裡獲取token裡 解析出的userId,這樣就只需獲取一次,之後可以用快取,提升了效能。或者還可已在這裡封裝一些函式,比如把原生的this.staus,this.body一起封裝成一個returnBody。

  returnBody (status, message, data = {}) {
    this.status = status;
    this.body = {
      data,
      message,
      success: true
    }
  }
複製程式碼

中介軟體

可以在middleware裡面寫一些自定義的中介軟體,比如我這個專案中用到的鑑權中介軟體。然後在app/config.default.js里加上一行config.middleware = [ 'authorization' ];就可以使用了,是不是十分方便呢?

資料庫

資料庫的話我們可以採用一些ORM工具來操作。比如sequelize,一款優秀的非同步ORM框架,讓我們可以用OOP的方式運算元據庫,優雅的生成安全、可維護的SQL程式碼。使用的話也是非常的簡單,值得注意的是我們最好在初始化之前配置一下,讓自動生成的檔案都在database目錄下,便於管理。

sequelize開發環境配置:

  "development": {
  "username": "root",// mysql賬戶
  "password": "yourpassword",// mysql密碼
  "database": "newbeeForum",// 資料庫名字
  "port": 3306,
  "host": "127.0.0.1",
  "dialect": "mysql"
}
複製程式碼

發帖

發帖的圖片是先上傳到七牛雲,然後返回連結,資料庫裡只儲存了連結。具體操作可以參見七牛雲開發者文件。

JavaScript SDK: developer.qiniu.com/kodo/sdk/12… Node.js SDK: developer.qiniu.com/kodo/sdk/12…

jwt

登入的話我們採用jwt來進行跨域身份驗證,登入成功後會簽發一個token,並把這個token種到cookie裡面,鑑權中介軟體就是通過這個token來鑑別使用者是否有許可權訪問頁面。

簽發token: const token = jwt.sign({ userId: existUser.userId }, this.app.config.jwtSecret, { expiresIn: '7d' });

密碼儲存

明文儲存使用者密碼是不道德的,所以我採用了crypto來加密儲存使用者密碼,登入的時候也是先將明文密碼加密再與資料庫中比對,相同才允許登入。

加密儲存使用者密碼:user.password = crypto.createHmac('sha256', this.app.config.password_secret) .update(user.password) .digest('hex');

部署上線

部署條件:伺服器安裝node 8.0以上版本,安裝mysql,安裝Nginx

我的是騰訊雲的伺服器,系統是centos7。前端npm run bulid,把打包後的專案放到伺服器上,比如/home/newbeeforum下,然後後端專案npm install --production,這樣就只安裝dependencies的依賴,然後tar -zcvf ../release.tgz,放到伺服器上解壓縮後npm start,就可以執行了。最後在配置一下Nginx的轉發請求就可以實現跨域了。

轉發請求:

``` 
    //如果只是host、埠轉換
    location /project {
    proxy_pass   http://127.0.0.1:8080/project;
}
    //如果路徑也變化了,則需要設定cookie的路徑轉換,否則cookie會丟失  
    location /proxy_path {
    proxy_pass   http://127.0.0.1:8080/project;
}
```
複製程式碼

tips: 如果react前端部署上去是一片白的話可能是路徑的問題,要注意是相對路徑還是絕對路徑。

最後

  • 原始碼點我
  • 因為只寫了三天,所以目前只實現了登陸註冊,發帖的基本功能,後續可以慢慢完善
  • 部署在我網站上,可以體驗一下 newbeeforum.newbeelity.cn(註冊驗證碼亂填就行)
  • 碼字不易,歡迎star
  • 有大佬招前端嗎,目前大四
  • over

相關文章