饥人谷技术栈介绍:Rails + Vue

最近我们又招了一名初级前端开发者,以后我们的队伍也会逐渐壮大,为了让以后的人知道我们的技术栈,遂有此文。


我们的应用架构为前后端分离,但是人员不分离(一个人既写后端又写前端)。

用到的技术:

  • 后端:Rails + gon + jwt + cancancan(权限管理)+ redis + psql
  • 前端:Vue + axios + vue-router + vue-i18n + 小程序
  • 构建部署:webpacker + capistrano
  • 测试:circleci + rspec + mocha + GitHub 强制检查
  • 第三方服务:七牛CDN + SendCloud邮件服务 + 七牛直播服务 + LeanCloud 短信服务


在前端使用 Vue 做多页面应用

假设我们有三个页面 /users/ , /users/1 和 /users/new 。

那么每个页面就都会有一个入口 JS 文件,分别叫做 users/index.js, users/show.js 和 users/new.js

每个入口 JS 都引用了 Vue,大概长这样:


import 'initializers' // 各种初始化
import Vue from 'vue'
import axios from 'axios'
import ComponentA from 'components/a'

let app = new Vue({
  el: '#vue-app',
  components: {ComponentA}
})

如果这个页面较复杂,可以引入 Vuex 和 VueRouter(hash模式)。


在局部使用 Vue 做单页面应用

我们的 /admin/ 页面由于不需要 SEO,所以做成了完全的单页面。

后端路由会把 /admin/*path 全部渲染成 /admin/show 页面,VueRouter 接管所有 /admin/*path 路由。

get 'admin/*path', to: 'admin#show', constraints: ->(request) do
  !request.xhr? and request.format.html?
end


我们使用 Webpacker 打包所有前端资源。


后端使用 RESTful API 与前端通信

所有后端接口都是 /api/v1/xxx 的形式,如

  • GET /api/v1/users
  • GET /api/v1/users/1
  • POST /api/v1/users
  • DELETE /api/v1/users

原则上不允许出现不符合 RESTful 风格的 API,如 /api/v1/createUser。

API 输出格式默认为 JSON。

后端 model 使用 as_json 做 JSON schema,例如 user.rb


def as_json(options = {})
  attributes.merge(
    admin: admin?,
    display_name: display_name
  )
end


后端可以直接将变量传给前端的 window 以减少异步数据请求,如:

class ApplicationController < ActionController::Base
  before_action :set_gon
  def set_gon
    gon.qiniu = QiniuClient.settings
  end
end

这样做了之后,页面的 head 里就会出现

<script>
  window.qiniu = {uptoken:...}
</script>


所有无 SEO 需求的模块完全组件化

以课程页面为例,课程标题、主讲人等 SEO 信息直接用 Ruby 渲染,评价、问答等信息则使用 Vue 组件来渲染。如

<h1><%= @course.name %></h1>
<router-view></router-view> // 将会载入 <Comments> 组件



移动端使用小程序

由于目前没有做 App 的打算,所以先用小程序顶着。


待续……

编辑于 2018-11-19 14:20