前端架构浅谈

前端架构浅谈

0、前注

鉴于作者本人的能力有限(非常有限),并且依然在学习中,因此本文的高度和深度必然有所欠缺。

欢迎(并且非常欢迎)大家来批评指正,如果能详细的说明问题在哪里,如何解决和改正,那么就太感谢了!!!

我最喜欢听有理有据的批评了!!

本人QQ:20004604,邮箱:[email protected],期待你的交流。


1、为什么要有一个好的架构

首先明确一点,架构是为需求服务的。

前端架构存在的目的,就我个人理解来说,有以下几点:

1、提高代码的可读性。
一个好的架构,代码的可读性一定是很强的。
简单来说,假如有一个新人加入团队,那么他接手这个项目,一定是容易上手的,能简单轻松的了解整个前端部分的相互关系,从而找到自己需要重点关注的点。而不是需要花很多时间去熟悉这个项目的很多细节,才能开始上手做东西。
就文件来说,可以从文件名上,分清哪些是页面、哪些是逻辑、哪些是样式、哪些是可以复用的组件、哪些是图标组、又有哪些是移动端或是PC端专享的样式/逻辑等。
就代码来说,包括统一的命名风格,封装在同一个文件里的代码的相关性足够强等。
2、提高代码的可维护性。
一个好的架构,一定是易于维护的,例如在新增需求、更改需求、修正bug,都不会造成意料之外的变化,比如说修改了一个页面组件的内容,却导致另外一个页面组件发生变化(这也太坑了)。
因此,要低耦合,高内聚,以及输入和输出是可预期的。
3、提高代码的可扩展性。
一个好的架构,一定扩展性要强,不能写死。
需求变更太TM正常了,新增需求也太TM正常了。因此好的架构,必须要考虑到这些情况的发生,因为他们是一定会发生的。
所以,一定要避免把代码写死。
比如页面组件A里需要有一个日历组件,而这个日历组件引用的是别人的(比如从github上找的)。
那么尽量不要直接在页面组件A里面直接引用这个日历组件,而是将写一个日历组件B,在这个日历组件B里封装你引用的日历组件C,然后通过这个日历组件B来进行操作。
原因很简单,假如某天产品经理说,这个日历组件太丑了,我们换一个吧。如果你直接在页面组件A里内嵌这个引用的日历组件C,你很可能就要改很多代码(因为不同日历组件的使用方法和暴露的接口可能不同)。假如你还在其他多个地方引用了这个日历组件,那就更糟糕了!每个地方都要改。
而若是将引用的日历组件C封装到自己写的日历组件B之中,那么你只需要改日历组件B里的相应代码即可,而因为日历组件B暴露的接口是不变的,那么自然不用修改页面中的代码了。

附图,以日历组件为例,是否考虑到扩展性的结果

未考虑到扩展性

考虑到扩展性:

4、便于协同。
包括前端和后端的协同,前端和前端之间的协同。
具体来说,前后端的协同通常是以ajax为交互,那么应至少有一个用于专门封装了所有ajax请求的文件,所有ajax请求都封装在这里。在开发时,这里封装的方法应该可以模拟发送和接收约定好的交互内容,方便开发联调。
而前端和前端的协同,主要体现在同时在更改代码时,不会影响对方代码的正常运行。因此要求封装、解耦以及低干扰度是必须的。
5、自动化
自动打包,压缩,混淆,如果有必要,再加上自动单元测试。

总结:

总结来说,一个好的架构的目的是,让前端写代码写的舒服,让后端联调的舒服,让产品经理改需求改的舒服。


2、我如何设计架构

我不敢说自己的架构是好的架构(显然不是啦),只能分享自己最近做的一个项目,它的架构的如何做的。

首先,确定需求:

1、一个中小型网站,同时面向移动端和PC端(单端大概15个页面,算上弹窗大约20个)。

2、预算有限(给的钱少),开发时间有限(一个月)。

3、可能存在一定程度上的需求变更(比如增加页面或修改某些页面内容)。

4、客户可能不太在乎优化(但是我自己在乎啊!)

5、要求兼容IE9以上。

其次开始决定:

1、兼容IE9以上说明可以使用主流框架,而无需必须使用jquery。因此我采用了vue,版本是2.0;

2、预算有限,时间有限,因此PC端和移动端共html和js,独立css。

3、页面有限,因此无需将架构层级划分的比较细,只需要按其类型划分即可;

4、根据原型图来看,页面复杂程度有限,复用部分不是很多,因此可以确定哪些东西需要封装复用,哪些比较复杂需要独立封装,哪些比较简单为了简化开发难度可以直接耦合。

5、自己比较熟练单页面网站,因此采用以单页面为主,异步加载其他页面的形式。

于是使用相关配套的东西,比如webpack,vue-router等,另外为了开发和生产的方便性,采用以下模式进行开发。


第三,划分功能。

首先有一个根html,用户需要通过访问它来加载我们的js逻辑,因此js逻辑的代码被写在main.js之中。

在main.js之下,我们的前端代码可以被划分为三部分:

  1. 组件树;
  2. 功能模块;
  3. 各种资源;

如下图:

功能划分好之后,相同功能的放在同一个文件夹下,命名风格应该类似。

具体来说,组件树相关的东西,通常是以.vue结尾,放置在components文件夹下;

资源,有图片或者国际化资源等,以.png或者.js或.json结尾,放置在resources文件夹下;

而功能插件、服务等,因为可能被多处引用,因此为了方便引用,放在src文件夹下,并且该文件夹是components文件夹和resources文件夹的上级文件夹;


第四、细化功能模块

功能、组件树以及资源,我们已经明确了有哪些东西,那么接下来,我们要明确这些东西该如何以文件的形式来划分。

如下图:

1、项目构建相关

因为要使用vue.js,也要使用es6语法,因此babel是必须的;

又因为要自动化混淆打包,因此webpack也是必须的;

最后因为要方便多人协同,因此npm的package.json的配置,方便不同人可以快速自动化通过npm install来安装依赖,也是必须的;

2、CDN相关

而又因为我们要采用外部字体(需求要求引入非常见字体),因此CDN加速是必须的,该字体文件放在html中来配置引用即可;

3、配置和插件

我们需要直接引入一些插件和配置文件;

为了使用vue,我们需要一个根组件,那么就是App.vue

使用vue-router,我们需要配置路由文件,因此router-config.js这个路由配置也是必须的;

然后我们还需要以插件形式引入一些功能和服务,因此有了Plugin-开头的若干个vue插件,这些都是根据需要封装好的低耦合高内聚方法;

4、需要的npm依赖

当然,要使用vue肯定要引入vue.js

类似的还有vue-router.js和各种兼容性polyfill和全局插件;

5、抽离出的功能模块

除了直接引用的这些插件,我们还有一些和项目高度耦合的功能服务,我认为不能作为插件,但依然需要抽离出来封装好,方便使用和修改;

如封装ajax请求的ajax.js,所有的ajax请求都放置其中,只对外暴露接口,方便管理和使用;

又如实时国际化功能的组件LanguageManager.js,他需要引入国际化资源和管理国际化资源的加载;

又例如实现跨组件通信的event-bus.js

又比如管理用户信息的user.js

6、总结

而这些划分,都体现在上图之中。这就是src目录下的功能模块文件,我们需要的绝大多数功能都可以包括在其中,我们只需要按照实际开发中的需要,将对应的功能写入在这些文件中并引用即可;

第五、组件树

之前谈了功能模块的划分,接下来是组件树;

因此是中小型页面,因此组件树的层级无需太深,但该抽离出来的依然还是要抽离,尽量保证抽离出来的组件解耦以及一个页面组件的逻辑不要太多;

如下图:

0、根组件

所有组件最终往上找,都会找到共同的根组件App.vue,根组件只负责管理他的直接子组件;

每个组件都只负责管理自己的直接子组件,不跨级管理,并且不依赖于自己的子组件(否则可能因为子组件的未加载或错误而导致父组件错误),做到解耦和内聚;

1、弹窗dialog和弹窗tips

因为弹窗dialog和弹窗提示tips可能同时存在,因此将其划分为2个组件,方便管理;

2、未登录页面和登录页面

因为页面存在登录和未登录状态,而为了加载速度考虑,当未登录时,不加载已登录页面,因此需要划分出来,并进行异步加载处理;

3、未登录页面

未登录页面又分为三种情况:

1、初始页面:毫无疑问要直接加载

2、登录弹窗:点击登录时加载(异步)

3、注册弹窗:点击注册时加载(异步)

之所以分拆开,是因为根据需求,已登录用户刷新页面,可以直接进入登录后页面,因此无需登录和注册,这种处理可以减少流量消耗,提升加载页面加载速度(特别是注册弹窗需要加载的内容还比较多);

4、已登录页面

已登录页面有较多页面,采用默认加载初始页,然后异步加载其他页面(访问时);

5、弹窗dialog

由于逻辑较少,代码量不多,因此为了方便管理,统一将其合并在一个vue文件中,共同相同的打开逻辑,根据传递的key决定打开哪一个。

这样在新增弹窗时,无需再去写弹窗的打开、关闭逻辑。

假如有较复杂的弹窗,可以以子组件的形式引入到当前vue文件中,如此也方便管理;

6、国际化管理

和页面高耦合,负责加载对应的国际化资源,并进行切换管理;

7、页面组件

可能有子页面和复用的组件,按照正常方式引用即可。

8、样式文件

可以独立写为.css文件,但因为我的公共样式文件比较少,因此我还是将其放在一个.vue文件中,并在App.vue里来引用

8、页面组件起名

通常以.vue为结尾,除了国际化LanguageManager.js因为高耦合度,因此以.js结尾并是一个单独的vue实例,表示他更像是一个功能模块,而不是一个vue的页面组件;

基础页面,如登录和未登录页面,公共组件(并且是header和footer这种),以base-开头;

弹窗统一以box-为开头;

可复用的组件以extend-开头;

引入的外部组件以import-开头;

普通页面组件以page-开头(这些页面往往是一个独立的页面,并且挂靠在登录或未登录页面下);

注册弹窗因为逻辑比较复杂,并且同类较多,因此以register-为开头;

通过以文件名来划分,不同的页面组件之间的区分可以说是一目了然,同时也方便管理;


3、还没有谈到的内容

想了想,目前还没有谈到的内容有以下几点:

1、路由:
以路由为驱动来写页面,似乎是一种不错的选择;
好处是只需要通过查看路由的配置文件router-config.js,就可以了解页面组件的架构;
不过我自己关于vue-router的实践经验比较少,因此就略过不谈了;
2、单元测试:
按道理说,单元测试是非常有必要的,因此在进行架构设计时,必须考虑到这一点;
不过作者我目前在的公司关于前端方面都不太正规,实在没这方面的经验,
又因为作者我本人转行做前端的时间也比较短,虽然周周9.12.7,但也没来得及学习这方面的知识(没有需求驱动,这方面动力不足哈哈),
所以只能望有这方面经验的同学,愿意和我交流一下这方面的知识,先谢谢啦。我的QQ是:20004604,邮箱是:20004604@qq.com
3、自动化配置:
关于webpack的自动化,是前端架构的重要组成部分,因此配置也是蛮重要的;
不过一是这方面需要很多笔墨的,二是网上也有一些别人分享的文章(肯定比我的好),所以我这里就不细说了;
4、一些自动化工具:
依然尴尬,没有大厂经验,路子比较野,所以大厂专有的一些工具是木有的,
而自己找的话又嫌麻烦,所以没有优化到极致,只做到了基本满足目前项目需求的程度,见谅见谅;
等以后有这方面经验的话我再写博客来分享吧~

其他:

听说写原创内容可以获得打赏,我想试试~

觉得我文章不错的,欢迎支付宝打赏一发~

谢谢~~

时间: 2024-10-13 12:50:11

前端架构浅谈的相关文章

C++插件架构浅谈与初步实现

一.插件架构初步介绍 想到写本博客,也没想到更好的名字,目前就先命这个名吧.说到插件架构,或许大部分IT从业者都听过或者某些牛人也自己实现过稳定高效的插件框架.目前有很多软件以及库都是基于插件架构,例如PS.我所在行业的GIS软件如Arcgis.QGIS.还比如开源图形引擎OGRE以及OSG,这些都是插件架构,通过插件架构来进行功能的扩展.那到底什么是插件架构呢?我的理解是系统运行时在需要某个功能的时候动态加载的模块,插件通常用动态链接库实现,当然也可以用静态库,例如一些嵌入式系统中,比如IOS

React | 高效前端之浅谈

React | 高效前端之浅谈 React在国外已被各个公司的各种产品大量使用,大众熟知的INS.Airbnb.Yahoo.ThoughtWorks等,都是使用React来实现UI开发的.很多人认为,虽然React在国外已经被广泛应用,但在国内,仍处新兴萌芽阶段.到底React在国内境遇如何?据海说科技了解,阿里内部系统.支付宝新一代框架.美团内部系统.知乎.滴滴.卖座电影.豆瓣等大型网站及平台正在运用React,或在进行系统重构.毫无疑问,React作为近两年前端三大流行框架之一,正成为程序员

超融合架构浅谈

为什么叫浅谈呢,因为就是自己的观点,受知识所限难免偏颇.数据中心里面真正的东西总结起来就是三大部件:计算.存储和网络.这三大部件的演变过程是:硬件-虚拟化-融合. 在传统独立硬件时代,计算资源就是服务器,存储也是独立的硬件设备,因为服务器和存储之间的相互连接就构成了网络.不管是TCP/IP还是FC,这些构成服务器和存储之间连接的网络部分,随着服务器硬件的升级和存储的硬件的升级而成为瓶颈.为什么不把碍事的连接网络去掉,将最强的直接融合在一起,即服务器和存储硬件融合在一起,并且实现扁平化.在超融合时

iOS应用架构浅谈

缘由 从事iOS工作一年多了,主要从事QQ钱包SDK开发和财付通app维护,随着对业务的慢慢熟悉,最近在思考这两款应用架构设计的思想,刚好昨天在微信里看了一篇iOS大牛对终端应用架构的分享,乘热打铁,下面浅谈下我对ios应用架构设计的理解,写的不好或不对的地方,欢迎大家拍砖,我们一起来探讨. 假如问你一个iOS or Android app的架构,你会从哪些方面来说呢? 不要急着给出你的答案,可以先在你的脑子里思考3分钟,再看下面我要讲的内容. 其实对于iOS客户端应用的架构来说,复杂度不亚于服

iOS 应用架构浅谈

当我们讨论客户端应用架构的时候,我们在讨论什么? 其实市面上大部分应用不外乎就是颠过来倒过去地做以下这些事情: 简单来说就是调API,展示页面,然后跳转到别的地方再调API,再展示页面. App确实就是主要做这些事情,但是支撑这些事情的基础,就是做架构要考虑的事情. 调用网络API 页面展示 数据的本地持久化 动态部署方案 上面这四大点,稍微细说一下就是: 如何让业务开发工程师方便安全地调用网络API?然后尽可能保证用户在各种网络环境下都能有良好的体验? 页面如何组织,才能尽可能降低业务方代码的

iOS开发项目架构浅谈:MVC与MVVM

MVC MVC,Model-View-Controller,我们从这个古老而经典的设计模式入手.采用 MVC 这个架构的最大的优点在于其概念简单,易于理解,几乎任何一个程序员都会有所了解,几乎每一所计算机院校都教过相关的知识.而在 iOS 客户端开发中,MVC 作为官方推荐的主流架构,不但 SDK 已经为我们实现好了 UIView.UIViewController 等相关的组件,更是有大量的文档和范例供我们参考学习,可以说是一种非常通用而成熟的架构设计.但 MVC 也有他的坏处.由于 MVC 的

Angular2的模块架构浅谈

一.根模块.子模块与惰性加载 先说根模块.一个ng2应用至少要有一个根模块,包含ng2自带的BrowserModule,并声明为引导模块,在应用启动时将从此模块展开.随着应用的扩大,所有的事情都在一个模块中完成难免会变乱(某种程度上看ng1应用就是这么做的,并且细分了控制器来拆分应用,这其实浪费了最顶层模块的意义),所以自然而然能想到,可以将系统分为多个模块,每个模块都只做各自的事情而互不干扰,所以进一步的思路就是,用来根模块来引导程序并管理所有子模块(通过路由定向以及为它们提供全局配置与服务实

前端知识 | 浅谈在React中使用echarts

方法一: echarts-for-react 是一个非常简单的针对于 React 的 Echarts 封装插件. 和使用所有其他插件一样,首先,我们需要 install 它: 第一步: npminstall --save echarts(依赖) npminstall --save echarts-for-react 第二步: 在我们的项目中导入: importReactEcharts from 'echarts-for-react' 第三步: 在 render 函数中使用: option={th

前端知识 |浅谈React setState

setState的连锁反应 这是一个React组件实现组件可交互所需的流程,render()输出虚拟DOM,虚拟DOM转为DOM,再在DOM上注册事件,事件触发setState()修改数据,在每次调用setState方法时,React会自动执行render方法来更新虚拟DOM,如果组件已经被渲染,那么还会更新DOM中去.这个过程,setState就像一个点燃引擎的火源,发动了React核心的调度层,然后直至渲染层的改变.异步的setState刚接触React的同学,对React的setState