前端为什么要用框架?是为了解决问题还是复杂化问题?

二叶草 2020年3月9日22:26:43前端框架评论阅读模式

前端为什么要用框架?是为了解决问题还是复杂化问题?

当代前端框架规定您下载一个开发工具,进行依靠项,并在电脑浏览器上查询编码以前编译编码。它是件好事儿吗?难题是人们已经搭建更繁杂的网站,還是架构自身就很繁杂,导入了多余的多元性。今日的Web开发设计自90时代以来已经发展了很多,我们能够创建非常接近任何应用程序的完整体验;而且开发过程也发生了变化,作为前端web开发人员,打开记事本、键入几行代码、在浏览器上检查并将其上传到FTP文件夹的日子已经一去不复返了。

 
过去的前端Web开发

首先,我必须说明一个显而易见的事实: 

这个世界已经不像10年前那样了,唯一不变的是变化。以前,我们只有很少的浏览器,但是有很多兼容性问题。今天,你不会经常看到像“在Chrome 43.4.1上浏览效果最好”这样的广告,但在那个时候,这是很常见的。我们现在有更多的浏览器,但兼容性问题更少了。为什么?由于jQuery。jQuery满足了拥有一个标准的公共库的需要,允许您编写操作DOM的JavaScript代码,而不必担心DOM如何在每个浏览器和每个浏览器的每个版本上运行。

现代浏览器可以将DOM作为一种标准来操作,因此对这样一个库的需求在最近几年大大减少了。不再需要jQuery了,但我们仍然可以找到许多非常有用的插件,它们都依赖于它。换句话说,web框架可能不是必需的,但是它们仍然足够有用,可以流行和广泛使用。这是大多数流行web框架的共同特征,从React、Angular、Vue和Ember或者Bootstrap这样的样式模型。

 
人们为什么使用框架

在web开发中,就像在生活中一样,有一个快速的解决方案总是很方便的。你以前用JavaScript做过路由器吗?既然可以安装一个前端框架来克服这个问题,为什么还要经历痛苦的学习过程呢?当客户希望昨天就完成任务,或者您从为特定框架设计的另一个开发人员那里继承代码,或者您正在与已经使用给定框架的团队进行集成时,时间就变得很奢侈了。我们必须面对这个客观存在的事实,框架有它必须存在的客观原因,如果框架没有好处,就不会有人会使用它们了。

那么,使用web开发框架有哪些好处和独特的特性呢?

时间就是金钱。 当您在开发一个项目时,客户并不关心您使用的是哪个框架—实际上,甚至可能不知道您使用的是什么—他们只关心得到结果,而且越快越好。已建立的框架可以让您从一开始就创建一种即时的进展感,这是客户从第一天就渴望的。此外,开发得越快,赚的钱就越多,因为框架释放出来的时间可以被重新分配到更多的项目上。

社区的存在是非常有用的。 在选择框架时,这是非常重要的一点:当您遇到问题时,谁将帮助您?你和我都知道它一定会在某个时刻发生。您将需要做一些框架不打算做的事情,或者框架从来没有为您提供访问权限,所以有一个支持您的社区是非常重要的。开发——尤其是自由开发——可能是困难的,因为您沉浸在一个虚拟世界中,如果您是团队中惟一的前端web开发人员,这意味着您是惟一具有找到解决方案的经验和专业知识的人。但是,如果您使用的前端框架有可靠的支持,那么在世界的另一端就会有人遇到相同的问题,并且可能能够帮助您。

标准是优美的。 您是否注意到,当您查看自己的旧代码段时,您可以很容易地浏览它?或者至少比别人写的代码更容易?你以一种特定的方式思考,你有自己的命名和组织代码的方式。这是一个标准。我们都追随他们,即使他们只是为了我们自己。我们倾向于早餐吃同样的东西,在特定的时间醒来,每天把钥匙放在相同的地方。事实上,如果我们每天都改变我们的日常生活,生活将会变得更加困难,仅仅是搞清楚如何做事情。你曾经因为把钥匙放在不同寻常的地方而丢了钥匙吗?标准使生活更容易。当作为开发人员团队或社区的一部分工作时,他们变得绝对不可或缺。

框架从您安装它们的那一刻起就提供了一个标准,指导您以特定的方式思考和编码。你不需要花时间和你的团队建立一个标准;您只需了解在框架中如何完成工作即可。这使他们更容易在一起工作。当您知道函数必须在某个文件中,因为它是为在SPA中添加路由而构建的,并且在您的框架中,所有路由都被放置在具有该名称的文件中,所以查找函数会更容易。如果你有这样的标准,不同技能水平的人可以一起工作,因为高级程序员知道为什么事情是这样做的,即使初级开发人员也可以遵循标准本身。

 
当框架失效时

几年前,说一些诸如“我不使用框架——我看不出它们有什么实际的好处”之类的话会让某些开发者想要拿着火把和干草叉来烧了你。但是今天,越来越多的人在问自己,“我为什么要使用框架呢?”我真的需要它们吗?没有它们,编码有那么难吗?”

我当然是其中之一——我从不喜欢任何特定的框架,我的整个职业生涯都是在没有框架的情况下编写代码。如果我可以选择,我的选择总是:“不,谢谢。”“在那之前,我已经用JavaScript和ActionScript开发了很多年。当大多数人都认为Flash已经死了的时候,我却在用Flash编程。(我知道,我知道……但我做了很多动画,用纯HTML制作动画很难。)因此,如果您是许多从未考虑过编写不使用框架的代码的人之一,那么让我向您展示一些您可能会遇到困难的原因。

“万全之策” 是一个谎言。你能想象编写一个软件来完成你职业生涯中完成的所有事情吗?这是web开发框架的主要问题之一。您的项目有非常具体的需求,我们倾向于通过添加库、插件或附加组件来扩展框架的范围来解决这些需求。没有一个框架能100%满足你的需要,也没有一个框架是100%由你会发现有用的东西组成的。

拥有太多您不使用的代码可能会导致站点的加载时间延迟,随着用户的增加,这一点变得越来越重要。另一个问题是“完全之策”的心态导致了低效的代码。举个例子,$(‘sku-product').html('SKU 909090');, 最后,我们都知道jQuery代码会被翻译成类似这样的东西 
document.getElementById('sku-product').innerHTML = 'SKU 909090';

这种单行上的差异似乎并不重要,但是更改页面特定元素的内容恰恰是React的优点。现在,React将完成创建DOM表示的过程,并分析要呈现的内容的差异。如果从一开始就只针对您想要更改的内容不是更容易吗?

前端框架版本的混乱 您是否曾经遇到过这样的情况:您正在使用您的框架,并试图向其中添加一个库,但却发现您需要的库版本与您正在使用的框架版本不兼容?有时候,让两段代码协同工作甚至比自己编写代码要花费更多的精力。由于所使用的框架和库通常是依赖于其他隐藏的不兼容的框架和库,这个问题可以生长指数成长而变得更加复杂,最终达到一定程度,他们不可能被按照你希望的方式被成功管理和迭代。

更新不总是向下兼容的. 你是否曾经用AngularJS开发过一个项目,结果却发现你需要的东西在Angular 4发布之前是不会出现的?你知道Angular 5已经发布了吗?这是另一个大问题;即使您坚持使用单一的前端框架,当一个新的主要版本出现时,情况也会发生很大的变化,以至于您辛辛苦苦编写的代码甚至无法在新版本上运行。这可能导致从需要对大量文件进行的烦人的小更改到对代码的完全重写。

跟上最新的框架构建是一项挑战,但同样需要注意的是,当更新完全停止并且无法跟上其他技术时,其他框架也会受到影响。2010年,AngularJS和Backbone都首次发布。今天,Angular已经发布了它的第五个主要版本,Backbone已经完全不在聚光灯下了。七年似乎是一段很长的时间。如果你建立网站,它们可能已经完全改变了美学和功能。如果你正在开发一款应用程序,押注于错误的框架可能会让公司在以后需要重写程序时陷入艰难而昂贵的境地。

如果你手里是锤子,那你看啥都是钉子, 如果您经常使用web开发框架,这种情况很可能会发生在您身上,其中某个单个代码库定义了您将来使用的代码的状态,即使它只是外围相关的。假设你要建立一个像YouTube这样的平台,你想要使用Framework X,在某种程度上,即使这在今天听起来很荒谬,你还是决定使用Flash来制作视频,因为这是框架内置的。

框架是有着自己的想法的,而且很强大;例如,React强制您以特定的方式使用JSX。您可以看到到处都以这种方式使用代码。还有其他选择吗?是的。但是谁在使用它呢?这并不总是一件坏事,但是如果你需要执行复杂的动画,你可能只需要一个动画框架,而不是全部的React。我见过有些人做一些疯狂的事情,比如向页面添加jQuery只是为了向元素添加一个节点,其实这在普通的JS中是可以很简单的实现的.
document.getElementById('id_of_node').appendChild(node);

 
Eval 通向地狱, 但是 .innerHTML 貌似可控?

我想单独花点时间来探讨这一点,因为我认为这是很多人不使用框架来编写代码的原因之一。当您看到向DOM添加内容时大多数代码是如何工作的,您会发现 .innerHTML 属性注入了大量HTML。我们似乎都同意 eval 不适合运行JavaScript代码。但我想在这里强调一下 .innerHTML ,当您将HTML代码作为纯字符串注入时,您可能会丢失对所创建的任何节点的任何引用。确实,您可以通过使用 getElementsByClassName 或为它们分配一个id, 但这并不实际,当尝试更改其中一个节点的值时,您会发现自己要重新呈现整个HTML。

这在您开始编写代码时非常有用,并不需要太多的经验,你可以很容易地做很多简单的事情,问题出现在现代网站的复杂性上,它们更像是应用程序——这意味着我们需要不断地改变我们节点的值,如果你是通过重新连接整个结构来做的话,如果仅仅使用 .innerHTML , 这是一个高成本的操作。React通过一个虚拟DOM有效地解决了这个问题,Angular通过使用绑定作为修改页面上显示的值的简单方法来解决这个问题。但是,通过跟踪创建的节点并保存将在变量中重用或更新的节点,也可以相当容易地解决这个问题。通常也有一些 其他原因 让我们远离使用 .innerHTML 。

 
关于不使用框架进行编码的最大误解

时间就是金钱, 是的,我把这个概念带回来了。很多人觉得,如果他们停止使用流行的web框架,我们就会立即回到90年代的互联网,在当年人们最爱的标签还是 <marquee> 的时候, 在一个网站上旋转gif图片既时髦又前卫,Alta Vista是网络搜索的首选(no google),而且点击计数器无处不在。

使用web框架,您的第一行代码似乎可以节省很多时间,但是在某些情况下,收益会变成损失。你花很多时间阅读关于如何使框架,如何集成库,让框架工作的很好。之后,您可能会发现您构建的代码框架的标准不会工作,现在你需要重写它。而当你做一些没有框架的事情时,你开始会慢一些,但是你会取得稳定的进展。最后,最简单的部分就是你想要去的地方。总的时间不会有太大的区别。

我的代码将比长城还长。没有框架的写作就像单独购买电影而不是订阅流媒体服务。你不能立即看到你想看的几百部电影,但你也不必花钱去看成千上万部你根本不会考虑从商店下载的电影,你可以只写你需要的那部分。

中间件有用吗?确定有用,但通常没有必要。您编写的每一行代码都有更多的含义,因为您不需要适应框架的需求。感觉上像是在用纯JavaScript编写更多的代码,因为创建DOM元素的方法需要使用几行代码来创建一个元素,将其附加到DOM,可能还需要添加一个用于样式化的类,而不是在JSX中调用一行代码。但是如果你使用jQuery或React这样的库来比较代码,你会发现普通的JS在长度上非常相似。有时长一些,有时也短一些。

不必造重复造轮子。 到处都是“计算机科学教授”的口头禅。这是真的,它只是不需要特定的框架。例如,几乎每个web应用程序都要求发送Ajax请求来加载或保存数据,但是没有框架并不意味着每次都需要重新编写代码。您可以创建自己的库或代码库,也可以从其他库中提取代码。它越小,就越容易根据需要进行修改或调整,因此当您需要某个项目的特定内容时,它就派上了用场。修改100-200行代码比浏览第三方库或框架可能包含的堆积如山的文件要容易得多。

它只适用于小项目. 这是一个很常见的神话,但根本不是真的;目前,我正在开发一个完整的系统,可以在一个地方在线管理公司的所有方面,包括一个类似于谷歌Drive的模块。无论使用框架还是不使用框架,我都会经历非常相似的步骤,并遇到非常相似的问题。差别可以忽略不计。但是,如果没有框架,我的整个代码会更小,更容易管理。

我想要证明

好吧。让我们停止讨论理论,跳到一个现实世界的例子。几天前,我需要显示一个带有商店标识的品牌列表。最初的代码使用了jQuery,但是在火狐浏览器加载时出现了一个问题,它显示了一个损坏的图像图标,而这个图标是为那些还没有上传标识的品牌设计的。我们不能仅仅因为X公司还没有完成他们的工作,就让商店看起来没有完成,但是功能需要上线。

下面的代码使用jQuery等效于 .innerHTML:
var list_brand_names = ['amazon', 'apple', 'nokia'];
var img_out = '';
for (i=0;i<list_brand_names.length;i++) {
var brandName = list_brand_names[i].toLowerCase();
img_out += "<a href='/pages/" + brandName + "'><img src='images/" + brandName + "' /></a>";
}
jQuery("#brand-images").html(img_out);

在不深入了解jQuery的优缺点的情况下,这里的问题是我们没有任何对所创建的图像的引用。虽然有些解决方案不涉及更改代码,但让我们利用这个机会看看如何在不使用任何库的情况下完成:

var brands = ['amazon', 'apple', 'nokia'];
var brand_images = document.getElementById("brand-images");
for (var iBrand = 0; iBrand < brands.length; iBrand++) {
var link = document.createElement('a');
link.setAttribute('href', '/pages/' + brands[iBrand]);
link.style.display = 'none';
brand_images.appendChild(link);

var image = new Image();
image.src = "images/" + brands[iBrand] + "png";
image.onload = function(){
this.parentNode.style.display = '';
}
link.appendChild(image);
}

最初的jQuery代码有6行,而普通的JS解决方案需要12行。要解决这个问题,在加载每个图像之前隐藏它,需要两倍的编码时间。我们来看看另一种选择。它能用jQuery解决吗?来看这个例子:

img_out += "<a href='/pages/" + brandName + "' style="display:none"><img src='images/" + brandName + "' onload="showImage(this)"/></a>";
function showImage(image){
image.parentNode.style.display = "";
}

用一些额外的代码,现在在jQuery和vanilla js之间只有三行区别,但是在jQuery,您可以看到img_out线迅速增长非常复杂,,你需要停下来仔细思考你在做什么。通过使用节点函数添加属性、函数等来直接编码DOM可能会更冗长,但是每一行都有更清晰、更精确的含义,这使得将来更容易阅读和维护。

让我们来看看React:
function BrandLink(props) {
var url = "images/" + props.brand + ".png";
return (<a href="{props.brand}"><img src={url}/></a>);
}
class Brands extends React.Component {
constructor() {
super();
this.state = {brands: ['amazon', 'apple', 'nokia']};
}
render() {
const links = this.state.brands.map((step, move) => {
return (<BrandLink brand={step} key={step}/>);
});
return (<div className="brands">{links}</div>);
}
}
ReactDOM.render(<Brands />, document.getElementById("root"));

这个版本显然不是最优的。这段代码并不比普通的代码短,我们甚至还没有解决这个问题并隐藏链接,直到加载了其中的图像。
对于每个示例,结果都是不同的。有时,jQuery会更短。有时候,React会赢。有时vanilla JS可能比它们都短。在任何情况下,这里的目标都不是要证明其中一个在本质上优于另一个,而是要证明使用vanilla JS和使用框架在代码长度方面没有显著的区别。
 
结论

就像任何现实生活中的问题一样,没有什么是非黑白的。对于您的一些项目来说,不使用web开发框架进行编码可能是最好的解决方案,而对于其他项目来说则是一场噩梦。就像每个工具一样,关键不只是学习如何使用它,而是何时使用它,以及使用它的优点和缺点是什么。用纯JavaScript编写代码就像使用任何框架一样——要掌握它需要一定的时间,然后才能熟练地使用它。

但是,至少对我来说,最关键的区别是框架来来去去,即使一个框架流行了很长一段时间,它也会从一个版本到另一个版本发生巨大的变化。纯JavaScript将是一个选择,直到它不再完全相关和其他一些语言出现。即使这样,也会有更多的概念和策略可以直接从一种语言迁移到另一种语言,而不是使用给定的框架迁移到另一种语言。就单个项目而言,时间和精力大致相当,知识贬值的减少以及您可以为下一个挑战带来的经验教训都是需要考虑的非常重要的因素

  

本文来源于:前端为什么要用框架?是为了解决问题还是复杂化问题?-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
二叶草
Go语言接口规则 前端框架

Go语言接口规则

Go语言接口规则 接口是一个或多个方法签名的集合。任何类型的方法集中只要拥有该接口对应的全部方法签名。就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。对应方法,是指有相同名称、参数...
Go语言中处理 HTTP 服务器 前端框架

Go语言中处理 HTTP 服务器

1 概述 包 net/http 提供了HTTP服务器端和客户端的实现。本文说明关于服务器端的部分。 快速开始: package main import (   "log"   "net/http" )...

发表评论