一、相关工具链简介

  • 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. Appium问题解决方案(6)- Java堆栈错误:java.lag.ClassNotFoundException:org.eclipse.swt.widets.Control

    背景 运行脚本出现 SWT folder '..\lib\location of your Java installation.' does not exist. Please set ANDROID ...

  2. junit4 套件测试

    junit4 中的套件可以用来测试一个需要依赖的业务流程,如购买必须依赖与登录成功 代码实现: 测试数据存放 public class BaseTest { protected static Hash ...

  3. 将两个byte型拼接成16位二进制,再转化为十进制

    short s = 0; //一个16位整形变量,初值为 0000 0000 0000 0000 byte b1 = 1; //一个byte的变量,作为转换后的高8位,假设初值为 0000 0001 ...

  4. this关键字的理解

    this理解为:当前对象 或 当前正在创建的对象 this代表所在类的当前对象的引用(地址值),即对象对自己的引用. 备注:意思方法被那个对象调用,方法中的this就代表那个对象.即谁调用,this就 ...

  5. Wpf UserControl使用 KeyBinding,失效问题

    我的问题根源是UserControl未获取相应焦点,在UserControl后台添加如下 public AccountDetailView()         {             Initia ...

  6. SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xF0\x9F\x90\xA3\xF0\x9F...' for column

    在做微信公众号保存用户数据时出现这种错误,一直不知道是哪里的原因,后来发现那个用户昵称带着一只兔子表情,由于数据库编码限制不能保存数据,所有需要先编码, 用PHP的函数就是base64_encode, ...

  7. Nginx系列(6)- nginx: [error] CreateFile() "D:\nginx-1.20.1/logs/nginx.pid" failed (2: The system cannot find the file specified)

    背景 修改nginx配置文件nginx.conf后,想要重启nginx使配置生效.cmd进入nginx安装目录,输入命令: nginx -s reload 报错:nginx: [error] Crea ...

  8. Jmeter系列(10)- Linux环境安装之Jmeter下载配置

    step-1下载 我是之前windows有,就直接copy到Linux系统了 step-2Jmter放到local目录 mv apache-jmeter-5.2.1 /usr/local/ step- ...

  9. django 模版-标签-视图-csrf-token-模版继承-HTML过滤器

    """ ******模版****** --定义模版-- **变量** 视图传递给模版的数据 注意1:要遵守标识符规则 语法:{{var(即变量)}} 如果使用的变量不存在 ...

  10. YbtOJ#752-最优分组【笛卡尔树,线段树】

    正题 题目链接:http://www.ybtoj.com.cn/problem/752 题目大意 \(n\)个人,每个人有\(c_i\)和\(d_i\)分别表示这个人所在的队伍的最少/最多人数. 然后 ...