【React 實戰教程】從0到1 構建 github star管理工具
在日常使用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,因此選擇構建一個 ofollow,noindex">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 複製程式碼
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
檔案的配置

loaders
用
use
代替,隨後在file-loader增加scss檔案格式的匹配

跨域問題
跨域問題可以使用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; } 複製程式碼
注意
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.js
和 webpack.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
中的 history
和 hash
模式,需要注意的是,在我們這個專案當中必須使用 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了=.=。