【React 實戰教程】從0到1 構建 github star管理工具

薄荷前端發表於2018-11-09

前言

在日常使用github中,除了利用git進行專案版本控制之外,最多的用處就是遊覽各式的專案,在看到一些有趣或者有用的專案之後,我們通常就會順手star,目的是日後再看。但是當我們star了許多專案之後,回過頭想找一個的專案就會發現,很難在短時間內找到它,官方也並沒有提供很好的管理我們的star專案的功能,因此在市面上也出現了一些對star進行管理的工具,比如說 astralapp,Star Order等等,其實github的介面api都是開放的,我們完全可以自己構建一個屬於自己的專案管理工具。公司的前端技術棧是React,而筆者之前使用的是Vue,因此正好想利用github的open api 自己構建個react的github star管理專案來加深react的使用。而大體功能我們就模仿astralapp。

github open api

官方文件有v3和v4,2個版本,v3是Restful,v4是GraphQL,在這裡我們使用的是v3版

v3

使用的是restful 協議

伺服器地址

https://api.github.com
複製程式碼

在無token情況下使用github的api,每分鐘限制是60次請求,考慮到想完整的使用github的api,因此選擇構建一個web application,授權OAuth應用程式的流程可以參照官方文件。在這裡,就簡單的說一下這個流程。

授權OAuth2.0 的流程

github OAuth的授權模式為授權碼模式,對OAuth不瞭解的同學可以具體看阮一峰老師的理解OAuth 2.0

要做的流程主要分為3步

  • 獲取code
  • 通過code獲取token
  • 在請求時攜帶token

獲取code

首先需要跳轉到這個地址

https://github.com/login/oauth/authorize
複製程式碼

需要有以下引數

引數名 型別 描述
client_id string 必選 client_id是在註冊github application後可以看到
redirect_uri string 可選 授權成功後跳轉的地址,這裡的這個跳轉地址也可以在後臺進行設定
scope string 可選 許可權範圍,具體的許可權可以參照,具體傳值格式以及需要哪些範圍可以參照官方文件
allow_signup string 可選 是否允許為註冊的使用者註冊,預設為true

跳轉至目標地址後,會有個授權介面,當使用者點選授權之後會重新跳轉到我們自己設定的redirect_uri並攜帶一個code,就像這樣

<redirect_url>?code=1928596028123
複製程式碼

通過code獲取token

在獲取code之後,請求用於獲取token

POST https://github.com/login/oauth/access_token
複製程式碼
引數名 型別 描述
client_id string 必填 client_id是在註冊github application後可以看到 必填
client_secret string 必填 該引數是在同client_id一樣,也是在註冊application後可以看到
code string 必填 通過第一步獲取
redirect_uri string 可選
state string 可選 隨機數

token的預設返回格式為字串

access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&token_type=bearer
複製程式碼

可以通過更改頭部接受格式進行返回格式變更

Accept: application/json
{"access_token":"e72e16c7e42f292c6912e7710c838347ae178b4a", "scope":"repo,gist", "token_type":"bearer"}

Accept: application/xml
<OAuth>
  <token_type>bearer</token_type>
  <scope>repo,gist</scope>
  <access_token>e72e16c7e42f292c6912e7710c838347ae178b4a</access_token>
</OAuth>
複製程式碼

在請求時攜帶token

攜帶token有2種方式 一種是永遠跟在url的後面作為params

GET https://api.github.com/user?access_token=...
複製程式碼

另外一種是放在請求頭中

Authorization: token 獲取到的token
複製程式碼

介面請求

在專案裡運用到的github 介面 目前有三個

  • 使用者資訊介面
  • 當前使用者star的專案
  • 獲取專案Readme介面

需要注意的是這些介面由於服務端實現了CORS,因此是不存在跨域問題,但是,考慮到本身這個專案的功能情況,之後我們會自己建立服務端進行請求。

使用者資訊介面

GET https://api.github.com/user
複製程式碼

當前使用者star的專案

GET https://api.github.com/user/starred
複製程式碼

可選的請求引數

引數名 型別 描述
page string
sort string 排序條件 有2種created updated,預設為created
direction string 升序還是倒序 asc desc,預設為``desc

獲取倉庫Readme介面

GET https://api.github.com/repos/:username/:repo/readme
複製程式碼

針對一些檔案介面,github提供了頭部型別的選擇,可以返回不同的檔案型別,比如raw等,具體可以參考官方文件中的Custom media types

在這裡我們需要的是html格式,因此 我們在頭部當中設定

"Accept": "application/vnd.github.v3.html"
複製程式碼

這樣ReadMe返回的是html程式碼,我們根據html程式碼直接顯示即可。

目錄結構

├── config  // webpack相關檔案
├── public  // 公用檔案
├── scripts // 指令碼檔案 build,start,test檔案都在裡面
├── src
    ├── assets  // 自己放置的資原始檔
    ├── components  // 公用元件
    ├── pages   // 頁面檔案
    ├── utils   // 公用方法文
    App.css
    App.scss
    App.jsx
    index.css
    index.js
    logo.svg    
    reset.css   // 重置樣式
    variable.css
    variable.scss   // 公用變數檔案
├── package.json
├── .editorconfig   // 編輯器配置
├── .gitignore // git 忽略檔案
複製程式碼

構建

create-react-app

構建React專案首先第一個想到的是用腳手架工具,Vue當中有Vue-cli,自帶webpack,vue-router,vuex,而React對應的是create-react-app

當我們初始化完成專案之後,我們會發現webpack的配置檔案找不到,我們需要執行以下命令將wepack配置顯示出來

npm run eject
複製程式碼

scss

這個方法參照的是create-react-app中的說明adding-a-css-preprocessor-sass-less-etc

npm install --save node-sass-chokidar
複製程式碼

還需要裝 webpack watch

   "scripts": {
+    "build-css": "node-sass-chokidar src/ -o src/",
+    "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
     "start": "react-scripts start",
     "build": "react-scripts build",
     "test": "react-scripts test --env=jsdom",
複製程式碼
npm install --save npm-run-all
複製程式碼
 "scripts": {
     "build-css": "node-sass-chokidar src/ -o src/",
     "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
-    "start": "react-scripts start",
-    "build": "react-scripts build",
+    "start-js": "react-scripts start",
+    "start": "npm-run-all -p watch-css start-js",
+    "build-js": "react-scripts build",
+    "build": "npm-run-all build-css build-js",
     "test": "react-scripts test --env=jsdom",
     "eject": "react-scripts eject"
   }
複製程式碼

安裝好這些包之後,新建一個scss檔案會自動生成css檔案,我們在引用時直接引用css檔案即可。

另外一種方法是參照medium的一篇文章CSS Modules & Sass in Create React App

npm i sass-loader node-sass --save or yarn add sass-loader node-sass
複製程式碼

隨後更改webpack.config.dev.js檔案的配置

【React 實戰教程】從0到1 構建 github star管理工具
需要注意的是loadersuse代替,隨後在file-loader增加scss檔案格式的匹配
【React 實戰教程】從0到1 構建 github star管理工具

跨域問題

跨域問題可以使用webpack自帶的proxy進行配置,或者通過ngix進行代理

如果是webpack配置需要在package.json當中進行配置

"proxy": {
    "/user": {
      "target": "https://api.github.com",
      "changeOrigin": true
    },
    "/user/star": {
      "target": "https://api.github.com",
      "changeOrigin": true
    },
    "/login": {
      "target": "https://github.com",
      "changeOrigin": true
    }
}
複製程式碼

svg

目前使用了svg-react-loader

 /* eslint-disable */
 // 主要是這裡 eslint會報錯
import Refresh from '-!svg-react-loader!../../assets/img/refresh.svg';
/* eslint-enable */

class StarFilter extends Component {
  constructor(props) {
    super(props);
require.resolve('svg-react-loader');
    this.state = {
    };
  }

  componentDidMount() {
  }

  render() {
    return (
      <div className="star-filter">
        <div className="title-container">
          <h3 class="title-gray-dark">STARS</h3>
          <!--這樣就可以使用了-->
          <Refresh className="icon-refresh text-grey" />
        </div>
      </div>
    );
  }
}

export default StarFilter;

複製程式碼

顏色

改變顏色要使用fill屬性

.icon-refresh {
  width: 20px;
  height: 20px;
  fill: #606f7b;
}
複製程式碼

注意

  • 圖片中自帶的p-id元素在react中會自動變成pId,隨後會被react輸出警告日誌,建議把pid 屬性刪除,這個屬性不影響顯示
  • 我們經常在iconfont上下載svg圖片,但是有些svg圖片內部預設設定了顏色,如果要讓我們樣式當中的顏色起作用,建議在下載完svg後,檢查下預設的fill屬性是否存在,如果有請先刪除

引用本地圖片

import NoSelectedImg from '../../assets/img/not-selected.svg';

class ResInfo extends Component {
 // ..此處省略
  render() {
    <img
      alt="no-selected"
      src={NoSelectedImg}
      className="img-no-selected"
    />

  }
}

export default ResInfo;
複製程式碼

第二種方法是用require

<img src={require('../../assets/img/status-spinner.svg')} alt="fetch" width="16" height="16"/>
複製程式碼

需要注意的是如果是要在img標籤中使用svg圖片,還需要在webpack當中進行配置,在webpack.config.dev.jswebpack.config.prod.js當中大致在133行左右的urlLoader增加svg檔案的匹配

{
    test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/, /\.svg$/],
    loader: require.resolve('url-loader'),
    options: {
    limit: 10000,
    name: 'static/media/[name].[hash:8].[ext]',
}
複製程式碼

路由

使用react-router-dom進行路由的管理,和Vue-router一樣,需要對要用到的路由級別元件進行註冊。直接將元件寫在router內部即可。

render() {
    return (
      <div className="App">
        <BrowserRouter basename="/">
          <div>
            <Route exact path="/" component={Auth} />
            <Route path="/auth" component={Auth} />
            <Route path="/star" component={Star} />
          </div>
        </BrowserRouter>
      </div>
    )
  }
複製程式碼

Router中有BrowserRouter,HashRouter等,而這2種類似於Vue-router中的historyhash模式,需要注意的是,在我們這個專案當中必須使用BrowserRouter,如果使用HashRouter在github 授權重定向回我們頁面時會出現問題。會出現code不在尾部的問題。

import { Redirect } from 'react-router-dom'

class Auth extends Component {

 //省略...

  render() {
    // 如果isTokenError為true直接跳轉至首頁
    if (this.state.isTokenError) {
      return (
        <Redirect to="/"/>
      )
    }
    // 如果hasCode有值則跳轉至star
    if (this.state.hasCode) {
      return (
        <Redirect to="/star" />
      )
    }
    return (
      <div className="Auth">
        <Button className="btn-auth" onClick={this.onClickAuth}>
          點選授權
        </Button>
      </div>
    )
  }
}

export default Auth

複製程式碼

同時它也支援api的跳轉,當元件放置在router中,元件props內建會有一個histroy屬性,即this.props.history,使用它就可以實現push,replace等跳轉了功能了。

  /**
   * 返回首頁
   */
  go2home() {
    this.props.history.replace('/auth');
  }

  /**
   * 前往star介面
   */
  go2star() {
    this.props.history.push('/star');
  } 
複製程式碼

總結

我們大致瞭解了專案的概況,在開發專案的過程當中,官方文件是十分重要的,包括githubApi的使用,SCSS的使用,跨域問題等等,都能從官方文件當中得到解答。同時github提供的api也是十分豐富的,基本囊括了所有github的基礎功能,在上述文章當中只是展示了它極少的功能,更多的功能大家可以自己來發掘。在接下來的文章當中,會為大家帶來服務端開發篇,使用node進行服務端,資料庫的一些操作。專案地址可以點我,專案還在初期開發中,就不要來star了=.=。

參考

廣而告之

本文釋出於薄荷前端週刊,歡迎Watch & Star ★,轉載請註明出處。

歡迎討論,點個贊再走吧 。◕‿◕。 ~

相關文章