Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2018/09/07 -【React 实战教程】从0到1 构建 github star管理工具 #14

Open
Baifann opened this issue Sep 7, 2018 · 0 comments

Comments

@Baifann
Copy link
Contributor

Baifann commented Sep 7, 2018

前言

在日常使用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文件的配置

需要注意的是loadersuse代替,随后在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;
}

注意

  • 图片中自带的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 ★,转载请注明出处。

欢迎讨论,点个赞再走吧 。◕‿◕。 ~

@wusb wusb changed the title 2018/09/07 - 从0到1使用React构建一个 github star管理工具 系列一(前期准备篇) 2018/09/07 -【React 实战教程:第一节】从0到1 构建 github star管理工具 :前期准备 Sep 13, 2018
@wusb wusb changed the title 2018/09/07 -【React 实战教程:第一节】从0到1 构建 github star管理工具 :前期准备 2018/09/07 -【React 实战教程】基础架构搭建 Nov 9, 2018
@wusb wusb changed the title 2018/09/07 -【React 实战教程】基础架构搭建 2018/09/07 -【React 实战教程】从0到1 构建 github star管理工具 Nov 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant