现在的前端领域, 随着JS框架, UI框架和各种库的丰富, 前端架构也变得十分的重要. 如果一个大型项目没有合理的前端架构设计, 那么前端代码可能因为不同的开发人员随意的引入各种库和UI框架, 导致代码量变得异常臃肿, 最终结果可能是代码变得无法维护, 页面性能低下,不得已只能推翻重构. 所以我们需要在项目开始前, 同样的需要对前端代码进行架构, 一旦前端架构师设计出所有前端开发人员都要遵循的检验机制, 建立起系统设计的规范, 那么项目就拥有了可以衡量代码质量的标准, 前端开发人员也能享受到更高效的工作流. 所以, 前端架构的定义可以用以下一句话来总结:

前端架构是一系列工具和流程的集合, 旨在提升前端代码的质量, 并实现高效, 可持续的工作流.

本系列的前端架构文章, 将分别围绕前端架构的四个核心展开, 分别是代码, 流程, 测试, 文档.

前端架构的四个核心

(一) 代码

归根到底, 所有的网站都是由一堆文本文件和资源文件组成的. 当我们面对制作网站所产生的大量代码时, 就会发现为代码和资源设定一个期望是多么重要. 在代码部分, 我们会专注于如果实现系统架构中的HTML, CSS, JavaScript.

(二) 流程

现在早已过了FTP上传文件的时代, 那么现在重要的是思考怎么用工具和流程构建一个高效且避免出错的工作流. 工作流变得越来越复杂, 那些用于它们的工具也同样如此. 这些工具在提高生产力, 加快效率和保持代码一致性上带来了惊人的效果, 但也伴随着过度工程化和抽象化的风险. 所以, 现有的工作流是需要改变的.

(三) 测试

要构建一个可扩展和可持续优化的系统, 必须保证新代码和老代码能够很好的兼容. 我们的代码不会独立存在, 它们都是大型系统中的一部分. 创建覆盖面广泛的测试方案, 能确保老代码还能正常运作.

(四) 文档

一般而言, 如果不是团队中的重要成员要离开, 我们几乎都不会意识到文档的重要性. 等到那个时候, 大家将不得不停下手头的工作, 优先编写所有的文档. 作为前端机构师, 你要善于在项目开发的同时编写良好的文档.

代码核心

(一) HTML

在前端的架构中, HTML作为页面的基础是十分重要的. 如果初始的HTML写得很烂, 将要写出很多不必要的CSS和JavaScript来弥补. 反之, 如果如果初始的HTML写得足够好, 就能写出根据可扩展性和可维护的CSS和JavsScript.

首先我们来看一些初级的前端工程师可能写出的HTML代码:

<div id="header" class="clearfix"> <div id="header-screen" class="clearfix"> <div id="header-inner" class="container-12 clearfix"> <div id="nav-header" role="navigation"> <div class="region" region-navigation> <div class="block block-system block-menu"> <div class="block-inner"> <div class="content"> <ul class="menu"> <li class="first leaf"> <a href="#">菜单1</a> </li> <li class="second leaf"> <a href="#">菜单2</a> </li> </ul> </div> </div> </div> </div> </div> </div> </div> 

这类"div乱炖"的代码, 是很多初级的前端为应付切页面的工作写出来的. 只是单纯为了还原psd图, 而完全你不考虑HTML的可读性和可维护性.

随后, 在HTML5之后, 标签的语义化受到了大家的重视, 采用语义化的标签, 不仅增加了代码的可读性, 也有利于SEO. HTML语义化标签的使用,这也是在前端架构中需要考虑到的,下面我们来看一下使用语言化标签写的这段代码:

 <header><section><nav> <ul> <li> <a href="#"> 菜单1 </a> </li> <li> <a href="#"> 菜单2 </a> </li> </ul> </nav> </section> </header> 

但是如果我们的页面的菜单有数10项的时候, 就会额外添加<li><a href="#">菜单N</a></li>, 这类重复的工作量完全可以交给Mustache这类模板引擎来解决, 已Vue中的模板引擎语法来写HTML, 会减少很多的工作量 :

<template><header><section> <nav> <ul> <li v-for="(item, index) in navList" :key="index"> <a href="#"> {item} </a> </li> </ul> </nav> </section> </header> </template> <script> export default { data() { navList:['菜单1','菜单2','菜单3','菜单4','菜单5','菜单6','菜单7','菜单8','菜单9','菜单10'] } } </script> 

你也可以使用Handlebars, Jade, artTemplate各种模板引擎到你的项目中, 当然这些都是需要取决于前端架构师前期的所选择的技术选型. 做为前端架构师, 需要评估HTML产生的过程, 你对内容的顺序, 使用的元素和CSS类名有多大的控制权? 这些元素在将来改动起来会有多大难度? 模板的易用性? 你可以通过系统做出更改, 还是需要手动处理? 通过回答这些问题, 可能会颠覆你自己构建HTML和CSS的方法.

(二) CSS

构建CSS现在有很多成熟的方法, 例如使用新的命名空间, 扩充数据属性或在JavaScript里面定义CSS. 这些方法你可以从BootStrap, ElementUI这类UI框架中找到影子. 下面, 介绍3种比较常用的方法.

1.OOCSS方法(Object-Oriented CSS 面向对象的CSS)

  <div class="toggle simple"><div class="toggle-control open"> <h1 class="toggle-title">标题</h1> </div> <div class="toggle-details open"> 详细内容 </div> </div> 

上面这段代码就展示了如何使用OOCSS方法创建一个可切换的HTML代码, OOCSS有两个主要的原则:

  • 分离结构和外观
  • 分离容器和内容

分离结构和外观
这里的toggle用来控制结构, simple用来控制外观,这就是分离结构和外观的表现. 这样可以实现外观的复用, 例如当前的simple皮肤使用直角, 而complex皮肤可能使用圆角, 还加了阴影.

分离容器和内容
这里使用toggle-title就是分离容器和内容的表现, 无论toggle-title的容器是用的<h1>还是<h2>或者是<div>, 一旦加上了toggle-title这个类名, 那么该容器均已该类名所定义的样式呈现内容.

2.SMACSS方法(Scalable and Modular Architecture for CSS 模块化架构的可扩展的CSS)

<div class="toggle toggle-simple"><div class="toggle-control is-active"> <h2 class="toggle-title">标题2</h2> </div> <div class="toggle-detail is-active"> 详细内容 </div> </div> 

上面的这段代码基本展示了如何使用SMACSS方法,在我个人的理解中, OOCSS更多的其实是提供了一种CSS构建思想, 该思想要求将结构和外观分离, 将容器和内容分离. 但是并没有提供一套完整的CSS构建规范, 而SMACSS是提供了一套样式系统, 该样式系统有5个具体类别:

  • 基础: 如果不添加CSS类名, 标记会以什么外观呈现
  • 布局: 把页面分成一些区域
  • 模块: 设计中的模块化, 可复用的单元
  • 状态: 描述在特定的状态或情况下, 模块或布局的的显示方法
  • 主题: 一个可选的视觉外观层, 可以让你更换不同主题

基础

//base.css
body, form { margin: 0; padding: 0; } a { color: #039; } a:hover { color: #03F; } 

在基础代码中, 应该规定的是页面中的一些通用样式,例如将bodymarginpadding设置为0 , 设置a标签的颜色等. 类似于某些人常用的initial.css文件.

布局

//layout.css
#header, #article, #footer { width: 960px; margin: auto; } #article { border: solid #CCC; border-width: 1px 0 0; } 

这里的布局指的是页面中一些通用的布局组件, 例如头部, 侧边栏, 主体和底部这些. 这些布局组件会在多个页面通用, 所以最好把其放入到一个css文件中. 方便复用. 在SMACSS中, 推荐将布局容器的顶级标签设置为id, 这样确保了每个页面中拥有唯一持有该样式的布局容器, 也方便其css和js选择器的使用. 当然, 你也可以使用一个唯一的类名替代id.

模块

//module.css//module1
.module1 > h2 { padding: 5px; } .module1 span { padding: 5px; } //module2 .module2 > h2 { padding: 10px; } .module2 span { padding: 10px; } 

模块是指页面中可以单独分离并提取出来复用的部分, 例如导航条, 侧边栏, 对话框或一些widget等. 所以, 模块禁止使用id, 而应该采用类名的方式.

状态

<div id="header" class="is-collapsed"> <form> <div class="msg is-error"> There is an error! </div> <label for="searchbox" class="is-hidden">Search</label> <input type="search" id="searchbox"> </form> </div> 

State 负责定义元素不同的状态下,所呈现的样式. 上面的一段代码中,已is-开头的就是表示状态的类名, is-collapsedis-error等类名不会单独使用, 而是和前面的布局模块一起使用. 下面的代码, 就是在tab栏模块和状态一起使用:

//state.css
.tab {background-color: purple; color: white; } .is-tab-active { background-color: white; color: black; } 

主题

// module-name.css
.mod {border: 1px solid; } //theme.css .mod { border-color: blue; } 

这里的主题理解为皮肤更加合适, 已上面的代码为例, 在module-name.css中定义了边框除颜色之外的样式, 在theme.css文件中定义了该边框的颜色, 这样的好处就是, 如果定义其他颜色的类名去覆盖这些有颜色的样式, 那么就可以通过类名去切换皮肤的颜色. 达到更换主题的效果.

更多关于SMACSS的方法, 请参考: https://smacss.com/book

3.BEM方法(Block Element Modifier 块元素修饰符)

<div class="toggle toggle--simple"><div class="toggle__control toggle__control--active"> <h2 class="toggle__title">标题3</h2> </div> <div class="toggle__details toggle__details--active"> ... </div> ... </div> 

BEM是由Yandex提出的给一个CSS命名方法, 该方法要求使用一个CSS类名, 尽可能使用以下三者组成:

  • 块名: 所属组件的名称
  • 元素: 元素在块里面的名称
  • 修饰符: 任何与块或元素相关联的的修饰符

块名
这里的块名很多初学者会以为是inline-block中的块, 其实这里的块名指的是一个独立的模块或组件. 例如一个<header>可以用做一个模块, <header>中的<nav>可以用作一个模块. 模块之间是可以相互嵌套的. 上面的示例代码中 ,toggle就是一个独立的模块

元素
元素是指无法用在其他块名中的部分, 在BEM方法中, 元素跟在块名后面使用__连接, 之所以约定使用双下划线是因为方便在块名中使用单下划线命名. 上面示例代码中的toggle__controltoggle__title就是块名+元素的命名方式.

修饰符
修饰符与SMACSS中的状态类似, 在BEM方法中, 修饰符需要跟在元素后面使用--连接. 有的人会觉得这种写法会使得代码冗余, SMACSS使用is-active同样可以表示同样的作用, 为什么上面的代码要使用toggle__details--active呢? 其实, 如果单独看openis-active这两个名字, 我们并不知道它们的含义是什么, 但是当看到一个toggle__details--active的类名, 我们就知道它是表示: 这个元素的名称是details, 位置在toggle组件里, 状态为active.

(三) JavaScript

1.框架的选择
这里我不想陷入Angular, React, Vue三大框架之争. 我是一个Vue的开发者, 我深知MVVM框架给我们开发者带了极大的便利, 不用再以jQuery不停的操作DOM的形式去开发, 而是只关注数据的改变, 以数据去驱动DOM的改变. 这能够把更多的时间放入到业务逻辑的处理上.

就目前三大框架的生态系统来看, 大部分业务三大框架实现起来其实并没有什么大的差别,框架的选择更多的取决于项目中团队人员的偏好和学习成本. 比如Vue的学习成本就相比于Angular要小太多. 虽然我是一个Vue的开发者, 但我不得不说在React中使用JSX的语法让写代码变得很愉快.

这里我还想说的是: 其实你很可能不需要任何的框架!

有很多成功的网站只不过是采用了一些模板语法, 加上少量手动创建的Sass文件和几十个Javascript函数创建而成. 当项目的规模足够庞大, 需要牺牲代码文件体积大小去换取框架所带来的开发效率的提高时, 再考虑评估引入哪类JS框架和UI框架, 否则不要轻易放弃精简方案.

2.选择一套JavaScript代码规范

每个人写代码的方式是不同的, 有些人可能喜欢用==, 但有的喜欢用===; 有的人可能习惯给每个变量使用var去声明, 但有的喜欢使用一个var加逗号运算符去同时声明多个变量. 这些代码习惯可能并不会对程序运行造成影响. 但是在大型业务中, 面临多个开发者共同开发时, 如果没有一套代码规范, 那么就会出现代码难以维护, 难以阅读的情况. 为了让新加入的团队成员也能够快速熟悉相关的代码, 并且让代码可以维护, 一套Javascript代码规范不论是开发大型项目和小型项目, 都是必须的.

如果公司没有代码定制自己的代码规范, 可以使用大公司所制定的代码规范, 这里向大家推荐以下三个代码规范:

  • Airbnb JavaScript Style Guide

    Airbnb JavaScript Style Guide

    Airbnb的Javascript号称是"最合理的编写JavaScript代码的方式", 也是互联网中最流行的JavaScript代码规范, 它在Github上足有6万star, 几乎覆盖了JavaScript的每一项语言特性.

  • Google JavaScript Style Guide

    oogle JavaScript Style Guide

    Google的JavaScript代码规范相比于Airbnb代码规范更加全面, 它不仅从代码美感,性能角度和代码特性对编写Js代码进行了规范, 同时也对Js的命名, 导入方式, Js代码文档进行了规范. 在Introduction中, Google团队表明, 在项目中全部使用了Google的Js规范, 才能被叫做Google Style的代码!

  • JavaScript Standard Style Guide

    JavaScript Standard Style Guide

    standard JS是一个功能强大的 JavaScript 代码规范, 自带 linter 和自动代码纠正, 无需配置, 自动格式化代码. 可以在编码早期就发现代码中的低级错误. 这个代码规范被很多知名公司所采用, 比如 NPM、GitHub、mongoDB 等.

下面截取部分airbnb的ES5规范, 来对比一下使用了规范和未使用规范的区别:

数组
  • 使用直接量创建数组
//bad
var items = new Array() //good var items = []; 
  • 拷贝数组时, 使用slice
var len = items.length;
var itemsCopy = [];
var i;// bad for (i = 0; i < len; i++) { itemsCopy[i] = items[i]; } // good itemsCopy = items.slice(); 
  • 使用slice将类数组对象转换成数组
function trigger() { var args = Array.prototype.slice.call(arguments); } 
字符串
  • 使用单引号''包裹字符串
//bad
var name = "LITANGHUI"//good var name = 'LITANGHUI' 
  • 程序化生成的字符串使用join连接而不是使用连接符。尤其是 IE 下
var items;
var messages;
var length;
var i; messages = [{ state: 'success', message: 'This one worked.' }, { state: 'success', message: 'This one worked as well.' }, { state: 'error', message: 'This one did not work.' }]; length = messages.length; // bad function inbox(messages) { items = '<ul>'; for (i = 0; i < length; i++) { items += '<li>' + messages[i].message + '</li>'; } return items + '</ul>'; } // good function inbox(messages) { items = []; for (i = 0; i < length; i++) { // use direct assignment in this case because we're micro-optimizing. items[i] = '<li>' + messages[i].message + '</li>'; } return '<ul>' + items.join('') + '</ul>'; } 
比较运算符 & 等号
  • 优先使用 ===和 !==而不是 ==和 !=
  • 使用快捷方式
// bad
if (name !== '') {// ...stuff... } // good if (name) { // ...stuff... } // bad if (collection.length > 0) { // ...stuff... } // good if (collection.length) { // ...stuff... } 
空白
  • 使用 2 个空格作为缩进
// bad
function () { ∙∙∙∙var name; } // bad function () { ∙var name; } // good function () { ∙∙var name; } 
  • 大括号前放一个空格
// bad
function test(){ console.log('test'); } // good function test() { console.log('test'); } // bad dog.set('attr',{ age: '1 year', breed: 'Bernese Mountain Dog' }); // good dog.set('attr', { age: '1 year', breed: 'Bernese Mountain Dog' }); 
  • 使用空格把运算符隔开
// bad
var x=y+5;// good var x = y + 5; 

前端架构设计1:代码核心相关推荐

  1. 前端进阶之路: 前端架构设计(2)-流程核心

    可能很多人和我一样, 首次听到"前端架构"这个词, 第一反应是: "前端还有架构这一说呢?" 在后端开发领域, 系统规划和可扩展性非常关键, 因此架构师备受重视 ...

  2. 前端架构设计应该包含哪些东西?

    前端架构设计 后台架构设计概念适用于前端,前端没有数据库设计,所以可以不考虑并发. vuejs的优点,一样适用于前端项目.高内聚,低耦合,可复用,单元测试. 从项目的生命周期,开发.上线.维护三个阶段 ...

  3. 前端架构设计第十课 前端数据结构和算法

    21 如何利用 JavaScript 实现经典数据结构? 前面几讲我们从编程思维的角度分析了软件设计哲学.从这一讲开始,我们将深入数据结构这个话题. 数据结构是计算机中组织和存储数据的特定方式,它的目 ...

  4. 前端架构设计第一课 CI环境npm/Yarn

    开篇词 像架构师一样思考,突破技术成长瓶颈 透过工程基建,架构有迹可循.你好,我是侯策(LucasHC),目前任职于某互联网独角兽公司,带领 6 条业务线前端团队,负责架构设计和核心开发.工程方案调研 ...

  5. 浅谈京东静态html原理,京东首页前端架构设计.ppt

    京东首页前端架构设计 工程化 Windows可视化工具 * 工程化 前端模块构建平台 * 总结 * QA * * JD.com JD.com JD.com JD.com JD.com JD.com J ...

  6. 架构方面学习笔记(3)-前端架构设计

    2022.02.08 今天读了一篇关于前端整洁架构的设计,因此对其中的内容进行了一些整理以及我自己的思考,后续阅读<领域驱动设计>后可以加入更多的内容. References: 前端领域的 ...

  7. 【成为架构师课程系列】架构设计中的核心思维方法

    架构设计中的核心思维方法 目录 前言 #一.抽象思维 #二.分层思维 #三.分治思维 #四.演化思维 #五.如何培养架构设计思维

  8. 前端架构设计第六课工程化构建、编译、运行

    12 如何理解 AST 实现和编译原理? 经常留意前端开发技术的同学一定对 AST 技术不陌生.AST 技术是现代化前端基建和工程化建设的基石:Babel.Webpack.ESLint.代码压缩工具等 ...

  9. 阿里浅谈大型项目前端架构设计

    1.综合 我在2年之前,写过一篇中小型项目的前端架构浅谈. 随着能力的上升,以及在阿里巴巴工作的经验,是时候写一篇大型项目的前端架构分析了. 本篇文章不会更多侧重于具体技术实现,而是尝试从更高角度出发 ...

最新文章

  1. python词频作图_基于Python的词频分析与云图生成
  2. 96.不同的二叉搜索树
  3. 异步fifo的设计(FPGA)
  4. 如何理解Excel数组公式{=sum(1/countif(B8:K9,B8:K9))}
  5. 标签页如何用php静态显示,php使用标签替换的方式生成静态页面
  6. 云服务器php版本修改,云服务器 更改php版本
  7. 积分图像 Integral
  8. 华中科技大学计算机网络实验_第四届江苏省计算机网络与云计算新技术研讨会在南京召开...
  9. 荣耀V30外观细节曝光:后置相机模组排布类似坚果Pro3
  10. vue 设置每个页面的title
  11. 从0开始学习 GitHub 系列之「04.向GitHub 提交代码」
  12. def __init__(self)是什么意思_Python入门一篇搞懂什么是类
  13. Python运维开发工程师养成记
  14. C语言——知识点汇总
  15. k8s修改集群IP--不重置集群
  16. 发邮件+实习+简历+
  17. UINO优锘:数据中心可视化管理面向运营的IT运维配置管理
  18. android强行打开软键盘,隐藏Android软键盘(如果已打开)
  19. 易语言 mysql lost connection during query
  20. 梅森数形如2 ​n ​​ −1的素数称为梅森数(Mersenne Number)。例如2 ​2 ​​ −1=3、2 ​3 ​​ −1=7都是梅森数。1722年,双目失明的瑞士数学大师欧拉证明了2 ​3

热门文章

  1. 获取php.ini配置信息,获得php所对应的配置文件(php.ini)信息
  2. 计算机二级vb2003年4月考试题,2003年4月全国计算机等级考试二级vb笔试真题附答案...
  3. 模拟灰度传感器循迹的程序_PLC编程,实例讲解西门子PLC模拟量编程
  4. layerconfirm 自动关闭问题 没有阻塞问题_微信新版本自动更新?赶紧关闭这个功能...
  5. verilog时钟翻转怎么写_verilog实时可调时钟代码
  6. 计算机程序大赛编程,【小学组】海淀区第三届“智慧杯”中小学生计算机程序设计大赛编程思维类初赛...
  7. 事业单位综合应用能力计算机,最新事业单位统考-综合应用能力C类梳理精华.pdf...
  8. jquery ajax html编码,jQuery AJAX字符编码
  9. 排球制作html,MAYA打造排球建模教程
  10. 十二、Python第十二课——函数