一、相关工具链简介

  • HAML

    HAML是专门面向Ruby on Rails模版语法设计的一门标记语言,其结合RoR的views部分模版语法的特点,对原来的*.html.erb(嵌入Ruby代码的HTML页面)进行了简化和封装,使得在编写前端页面时能够更加简洁方便。

    例如,下面是一份嵌入式Ruby的HTML页面的代码:

    <div id='content'>
    <div class='left column'>
    <h2>Welcome to our site!</h2>
    <p><%= print_information %></p>
    </div>
    <div class="right column">
    <%= render :partial => "sidebar" %>
    </div>
    </div>

    使用HAML改写后,可以写成:

    #content
    .left.column
    %h2 Welcome to our site!
    %p= print_information
    .right.column
    = render :partial => "sidebar"

    可以看到HAML使用缩紧代替了HTML的成对标签,同时更加友好地支持了Ruby代码的嵌入。可以看到HAML方便了前端的编写,因此也很受欢迎,我们所熟知的GitLab的前端代码均是使用HAML进行编写的。

    HAML官方文档:传送门

  • Webpacker

    • Webpack 是一个 JavaScript 应用程序的静态模块打包器。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
    • Webpacker基于Webpack,是一个专门为使用Ruby on Rails项目搭建的打包器。
    • 由于我们前端需要使用Vue.js前端框架以及ElementUI这一UI框架,因此前端部分使用了很多js以及vue的组件,需要使用webpacker进行编译和打包。

二、相关工具链配置方法

  • HAML

    使用Ruby on Rails的项目很方便配置HAML,只要在Gemfile中添加:

    gem 'haml'

    然后执行bundle install即可。

    这时,只要在views中创建*.haml,在渲染时就会根据HAML语法进行渲染。

  • Webpacker

    Gemfile中添加:

    # Gemfile
    gem 'webpacker', '~> 5.x'

    然后执行bundle install,之后执行:

    bundle exec rails webpacker:install

    这时webpacker完成了初始化,可以在app/下看到javascript目录,在里面添加js文件以及修改其中的js文件后,在刷新浏览器重新请求前端页面时会自动触发编译。

    这里我们的小组成员曾遇到过编译时间过长的情况(数分钟),正常情况下应该能在20-30秒左右完成编译,后来经小组中的wjx同学探究后发现,如果系统(或虚拟机)运行在了机械硬盘上就会导致此问题,将系统(或虚拟机)安装到固态硬盘即可解决此问题。

  • 另外,我们使用了Vue.js以及Element UI,在完成上述配置后使用npm进行安装:

    npm i vue
    npm i element-ui -S

关于上述工具链的使用

HAML确实让前端的代码编写变得简洁很多,但是同时我认为也带来了一些不便。在我们Alpha阶段开发时对此很有体会。在使用HAML时,对于原有的HTML标签中的属性以及Vue.js的一些语法均是使用Ruby的hash进行传入的,例如:

%el-card{shadow: 'never', 'v-for': "(blog, index) in blogs", ':key': 'index', class: 'blog-card', ':body-style': "{ padding: '10px' }"}

其中直接使用Ruby的symbol作为key的是HTML标签的标准属性,涉及到Vue.js模版语法的key使用string,而其值如果不是Ruby的变量,则需要写为字符串,这样就导致对于很多语法提示不能使用,比如上述的(blog, index) in blogs,是Vue.js的列表渲染,如果使用传统的HTML格式,在IDE中安装Vu e.js官方提供的插件则可以实现语法提示与高亮,类似的情况还有很多。这样就导致我们在写前端代码是经常需要在没有任何提示的情况下手写,尤其是在我们还不太熟悉相关技术的阶段时很容易出现一些错误,在开发时花费了很多时间。

对于这一问题,我们在Beta阶段进行了改进,我们进一步研究了Vue的单文件组件以及Webpacker所提供的组织结构,我们选择了只在views中的HAML中保持整体的结构逻辑,而将更多的具体实现封装为Vue组件。以下面一个比较简单的小模块为例:

- content_for :scripts do
= javascript_pack_tag 'new_organization'
- content_for :styles do
= stylesheet_pack_tag 'new_organization' #new-organization-app.small-container
.page-title-holder
.page-title 创建组织
%org_form{:action => organizations_path}

我们在前端的HAML中只保留了一些架构,而对于表单(org_form)的具体实现放到了Vue组件中,然后使用app/javascript/packs中的js文件注册该组件,如下所示:

import Vue from 'vue/dist/vue.esm'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import org_form from '../src/organizations/components/new_organizations_form.vue' Vue.use(ElementUI); document.addEventListener('DOMContentLoaded', () => {
new Vue({
el: '#new-organization-app',
components: {
org_form,
}
})
})

此时该js相当于为前端提供一个封装好的接口,我们在app/javascript/src/organization/components中添加对应的组件,如下所示

<template>
<el-form :model="orgForm" :rules="rules" ref="orgForm" :action="action" method="post">
<csrf></csrf>
<el-form-item label="组织名称" prop="name">
<el-input v-model="orgForm.name" name='org[name]'></el-input>
</el-form-item>
... ...
</el-form>
</template> <script>
export default {
props: ['action'],
data() {
... ...
},
components: {
csrf,
},
methods: {
... ...
}
}
</script> <style scoped>
... ...
</style>

这样不仅能够实现使用语法高亮与提示减少出错,提高开发效率,同时也对前端界面及其内部包含的模块进行了解耦。

对Web应用结构设计的一点思考

我们现在使用的Ruby on Rails没有进行前后端的分离,我们前端和后端共用了同一套路由,但是这样在进行小组合作时回有些不方便,而且要想实现很好地配合,需要每一位组员都掌握前端和后端的相关技术,然后实行任务导向型分组。但是我认为对于一个小组合作的项目而言,更好的方法或许是进行前后端分离。我参考了这篇文章

前后端分离即前后端各使用一套路由,然后后端通过提供API、前端通过调用API进行服务,这样在小组进行合作时,可以让一部分的同学专功前端,另一部分专攻后端,然后后端通过撰写API文档的形式提供服务,API文档的撰写可以参考GitLab的API文档,例如:

Remove project

This endpoint either:

  • Removes a project including all associated resources (issues, merge requests etc).
  • From GitLab 12.6 on Premium or Silver or higher tiers, marks a project for deletion. Actual deletion happens after number of days specified in instance settings.
DELETE /projects/:id
Attribute Type Required Description
id integer/string yes The ID or URL-encoded path of the project

然后后端的路由使用Web框架提供的路由,例如(Django):

from django.urls import path
from rango import views urlpatterns = [
path('', views.index, name='index'),
path('about/', views.about, name='about'),
path('add_category/', views.add_category, name='add_category'),
path('category/<slug:category_name_slug>/', views.show_category, name='show_category'),
]

然后前端使用前端框架的路由,例如使用Vue.js提供的Vue Router,大致如下:

... ...
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Index',
component: Index
},
{
path: '/rango',
name: 'Rango',
component: Rango,
children: [
{
path: 'index',
name: 'RangoIndex',
component: RangoIndex,
},
... ...

在前端需要调用后端的API时,可以使用axios等方式:

methods: {
getIndexContent: function () {
return axios.get('http://127.0.0.1:8000/');
}
}

然后在组件挂载时调用该方法,解析后端传来的数据(使用JSON格式),并将其赋值给对应的data即可:

this.getIndexContent().then((result) => {
this.msg = result.data["bold_message"];
this.tableData = result.data["category_list"];
// console.log(this.tableData);
})

[技术博客] 软工-Ruby on Rails前端工具链的配置以及对Web应用结构设计的一点思考的更多相关文章

  1. [技术博客] 软工-Ruby on Rails 后端开发总结分享

    [技术博客] 软工-Ruby on Rails 后端开发总结分享 在这次软件编写中,我们的后端使用了Ruby on Rails (RoR)框架. Rails框架是用Ruby编写的.这意味着当我们为Ru ...

  2. 【技术博客】忘记密码界面的Vue前端实现

    一.基本流程 [登录界面] --> [点击忘记密码] --> [输入个人邮箱和验证码] --> [系统发送邮箱验证] --> [用户在限定时间内登录邮箱,查收验证码] --&g ...

  3. [技术博客] win10下vagrant+centos7 rails虚拟开发机配置流程

    由于少昂早年已经在此踩过坑了,因此在这里,我们现在直接贴上他早年的博客链接:https://www.cnblogs.com/HansBug/p/7403306.html

  4. the Agiles Scrum Meeting 博客汇总

    the Agiles 团队博客目录 一.Scrum Meeting 1. Alpha the Agiles Scrum Meeting 1 the Agiles Scrum Meeting 2 the ...

  5. [技术博客] 敏捷软工——JavaScript踩坑记

    [技术博客] 敏捷软工--JavaScript踩坑记 一.一个令人影响深刻的坑 1.脚本语言的面向对象 面向对象特性是现代编程语言的基本特性,JavaScript中当然集成了面向对象特性.但是Java ...

  6. [福大软工] Z班——个人技术博客评分

    个人技术博客 作业地址 https://edu.cnblogs.com/campus/fzu/SoftwareEngineering2015/homework/1070 作业要求 个人技术博客单次作业 ...

  7. 【软工】[技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE

    [技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE 官方文档与重要参考资料 官方demo 官方API调用样例 Playground 官方API Doc,但其搜索框不支持模 ...

  8. 个人作业——软件工程实践总结&个人技术博客

    一. 回望 (1)对比开篇博客你对课程目标和期待,"希望通过实践锻炼,增强软件工程专业的能力和就业竞争力",对比目前的所学所练所得,在哪些方面达到了你的期待和目标,哪些方面还存在哪 ...

  9. [技术博客]大闸蟹的技术博客,通过gitlab api进行用户批量创建

    技术博客--通过gitlab api批量注册用户 gitlab登录界面本身提供了register功能,但需要手工一个个添加,对于一次性会添加整个班级的学生的软工平台来说并不科学合理.使用gitlab ...

随机推荐

  1. 转:C#读取PDF、TXT内容

    //读取PDF内容 private void button2_Click(object sender, EventArgs e) { label3.Text = OnCreated("D:\ ...

  2. JS010. 三元运算符扩展运用(多层判断语句 / 多条表达式)

    MDN - 三元运算符 语法 Condition ? exprIfTrue : exprIfFalse 用例: function getFee(isMember) { return(isMember ...

  3. Filter案例之登录验证

    一.登录验证,权限控制 1.需求分析 其中,登录有关的资源被访问时要直接放行,不然会死循环: 2.代码实现

  4. Redis-数据类型-应用场景

    目录 一些小问题 String Hash List Set ZSet BitMaps Hyperloglog Geo Streams 应用场景小结 一些小问题 Redis一共有几种数据类型?(注意是数 ...

  5. MySQL实战45讲(16--20)-笔记

    目录 16 | "order by"是怎么工作的? 全字段排序 rowid 排序 17 | 如何正确地显示随机消息? 内存临时表 磁盘临时表 随机排序方法 18 | 为什么这些SQ ...

  6. go新建一个工程

    使用go mod 可以在任何地方新建工程 工程目录 main.go   //引用子包必须格式"工程目录/子包" go.mod 子包 编译工程: go build

  7. 255 day03_List、Set、数据结构、Collections

    day03 [List.Set.数据结构.Collections] 主要内容 数据结构 List集合 Set集合 Collections 教学目标 [ ] 能够说出List集合特点 [ ] 能够说出常 ...

  8. LINUX服务器带宽跑满、负载过高问题排查

    1.centos 安装流量监控iftop apt-get  install iftop -y 2.查看网卡名称 ifconfig 3.查看端口占用情况 iftop -i 网卡名称 -P 执行 nets ...

  9. Docker系列(2)- Docker中的名词概念

    Docker工作流程 名词概念 镜像(image): docker镜像就好比一个模板,可以通过这个模板来创建容器服务,tomcat镜像===>run===>tomcat01(提供服务器) ...

  10. windows2012安装django

    第一步:下载python3.6.8或者到(https://www.python.org/downloads/release/python-368/)官网下载(Windows x86-64 execut ...