基于React的PC网站前端架构分析

news/2024/5/20 14:17:07/文章来源:https://blog.csdn.net/findhappy117/article/details/79724027

代码地址如下:
http://www.demodashi.com/demo/12252.html

本文适合对象

  1. 有过一定开发经验的初级前端工程师;
  2. 有过完整项目的开发经验,不论大小;
  3. 对node有所了解,关注前端发展,了解所谓“大前端”的概念;
  4. 了解React;
  5. 了解ES6;
  6. 想要初步了解一下大型网站的前端结构的人。

关于demo

本demo是我平时开发React项目时候自己配置的一套开发环境,由于每次写react的demo的时候都需要配置webpack,十分繁琐,因此前段时间我按照自己的开发习惯配置了一套基础的配置开发环境,以后每次写demo的时候直接使用本环境即可。

该环境由于只是用于本地开发使用,因此没有配置SSR和PRODUCTION_ENV。

最开始接触前端的时候,是从简单的html、css、js开始的,当时盛行的WEB理念是结构样式行为相分离,即html、css、js分离,独立开发,互相之间通过link和script来互相调用。

最开始我说接触到的小项目,都是直接将html、css、js等静态资源直接部署到服务器上,然后根据请求路由响应不同的html文件即可。

即使学习了webpack之后,我依然认为webpack的作用只是压缩js和css文件,提高服务器响应速度,优化用户体验,而部署到服务器上的依然是压缩后的min.css和min.js文件。

后来进入A公司实习之后,确实也是这种开发模式,当时我们开发h5页面,都是直接书写html、css、js文件,然后部署到服务器上,直接访问html即可。

后来进入B公司工作之后,才慢慢接触到真正的前端工程是什么样子的。

前后端分离

部分传统大型PC网站的业务前端部分都是采用的MVC架构方式,也就是每次立项之后,前后端约定好接口,分别开发,开发完毕之后,前端将开发好的页面交给后端(一般是Java或者PHP),然后由后端响应客户端请求,返回具体的html页面。

这种开发模式的缺点在于费时费力,沟通成本和联调正本非常高,前端有一点小的改动都需要前后端一起联调改动上线,大大增加了总工作量。

因此,现代大型PC网站一般都采用了前后端分离的架构方式,前端和后端的业务功能各自收敛,可以分别开发上线,互不影响,可以极大提高工作效率。

前后端分离一般分为两种:
1. 没有中间层的前后端分离;
2. 有中间层的前后端分离。

这里以目前最火的三大框架之一的react为主进行介绍。

无中间层

没有web中间层的前后端分离属于比较简单的类型,我们将一个统一的html/pug模板和其他的css、js等静态资源放置到cdn上,每次访问页面的时候,直接将模板返回给用户,然后里面所有的dom节点和其他数据都是由js来执行生成的。

(无中间层的前后端分离)

然而这种没有中间层的前后端分离的又有很多劣势:
1. 首屏渲染时间过长;
2. 对seo不友好。

有中间层

有中间层的前后端分离是一般大型项目采用的前后端分离方式。

自从2009年node横空出世之后,前端也逐渐承担了一些后端的业务,但是node由于自身健壮性的限制,又不适合作为大型项目的后端服务器,所以node热过一阵之后,逐渐成为了连接传统前端和后端的中间层,我们也称这种前端+node的架构为“大前端”。

返回模板

在node层中,我们可以做的事情就有很多了,其中最基础的就是返回不同的前端模板。

使用过几款前端模板,其中给我感觉最好的就是pug模板了(以前叫做jade)。

pug中的语法都是js语法,对前端工程师十分友好,而且pug功能很强大,可以作为html-middleware,被node完美支持,这里建议学习使用 Get Started。

数据拼接

其次,当网站发展地越来越大,数据量越来越多,对服务层进行分割的时候,会产生很多的服务模块,或者我们的数据分散在不同的数据库服务器上的时候,或者我们的前端页面中要嵌入第三方广告的一些api的时候,node就可以帮我们完成数据拼接的工作。

因为服务器访问接口的速度要比浏览器快很多个数量级,因此在node中访问多个接口并且拼接起来是非常高效的,拼接后的数据我们就可以直接传入模板中,供js使用了。

但是通常意义上来说,访问基础服务或者从数据服务器访问数据放在后端来做比较合适,但凡事总有例外,在万不得已的情况下,我们可以在node中间层中进行数据拼接。

这种模式一般不提倡使用,因为可维护性太差,而且安全性也很低,一般情况下都是后端有一个专门的数据模块去访问数据库和服务,然后将数据拼接起来,我们只需要在node中调用后端的一个API,就可以拿到我们想要的数据了。

监控服务

node层可以捕捉一些异常请求或者事件,上报到我们的第三方监控平台上,同时node还可以承担一部分的数据统计的工作,将一些用户应为打到第三方数据统计平台,供pm和数据分析师查看。

node还可以承担对整个实例进行监控的职责,当出现异常导致cpu使用率或者内存使用率超过阈值之后就饿可以及时触发报警机制。

服务器端渲染

SSR(server-side-render)可以说是非常重要的功能之一了,它可以帮助我们解决之前提到的首屏渲染时间过长和对seo支持较低的问题。

现代seo爬虫一般分为两种:
1. 支持解析js的爬虫,这类数量较少,以Google为代表;
2. 不支持解析js的爬虫,大部分都是这类,基本上都是非Google的搜索引擎的爬虫了。

对于Google的爬虫来说,是否使用SSR在seo方面无关紧要,因为最终都可以爬取到正常的页面。

而对于非Google的搜索引擎来说,我们就需要利用SSR,先将具体的dom节点渲染出来,供爬虫爬取。

而且这样同时还有一个优点:用户在网页loading的过程就中可以看到页面内容了,而不是一个空白页面。如果不使用SSR的话,在网页loading资源的过程中,一直呈现给用户一片空白,这就有可能造成用户的流失。

这张图是我在50kb/s的网速下,访问b站第一秒钟看到的内容,若是b站不使用SSR技术的话,可能等到用户能够看到首屏内容之后,时间都过去了五六秒。

这里是一个简单的使用SSR的Node层代码:

// 代码中使用了es6语法,不懂的可以先学习一下阮一峰老师的《ES6入门》
// 这个地方node如果没有使用babel的话,import会报错,可以直接使用require方法替换
import { renderToString } from 'react-dom/server';
import DemoContainer from 'containers/demo';
// 以koa2框架为例
module.exports = (ctx) => {const props = {...};// 这里的html就存放着我们组件render完之后的dom节点。const html = renderToString(<Demo >);// 这里以返回pug模板为例,第二个参数是要传入pug模板中的数据ctx.render('demo.pug', {__props: JSON.stringify(props),html});
};

这里是pug的代码片段:

// pug代码片段
body#root!{ html }script.window.__props = '!{ __props }'

使用SSR的时候要切记保证前端和服务器端的组件props保持一致,因此这里我的习惯是在node层将props直接传入window对象上,然后前端的组件直接从window对象获取props即可。

SSR的时候,React组件只会执行componentWillMount和render两个生命周期用来生成dom结构,其他的生命周期以及方法挂载都是在前端完成的。

node层的功能不止以上这些,这里就不过多展开介绍了。

虽然SSR的有点很多,但是还是有自身的弊端的。使用SSR就意味着你用自己服务器代替了一部分原本属于用户客户端的功能,因此会造成服务器性能降低,成本增高的可能,相对于小团队或者资金不算充裕的团队,要谨慎选择是否使用SSR。

选择框架

了解了前后端分离之后,我们就要对node层进行框架选择了。

目前比较主流的框架有三款:Express、koa1.0、koa2.0。

对于初学者来说,建议直接使用koa2.0进行中间层的学习和开发。

express的缺点在于:
- 太重,有很多模块我们可能都不会用到;
- 回调地狱,即使使用Promise也只能缓解。

koa1.0的缺点在于:
- 必须配合co库和generator来使用,配置繁琐。

而自从node升级到7.6版本以上,增加了async/await语法糖之后,我们就可以不需要任何三方库,直接在原生node中使用koa2的语法。

koa2是express的升级版框架,里面很多模块是直接从express中迁移过来的,但是又将以前不经常用到的模块删除,只有开发者在需要使用的时候采取引入那么模块。

并且koa2使用async/await语法糖之后,代码看似变成了同步执行,非常适合前端工程师的逻辑思维。

这里是express、promise、koa2的样例代码:

// express版本
module.exports = (req, res) => {const data1 = request.get('/api/demo1', (err, res) => {const data2 = request.get('/api/demo2', (err, res) => {const data3 = request.get('/api/demo3', (err, res) => {res.send(data1 + data2 + data3);})})})
}
// promise版本
module.exports = (req, res) => {new Promise((resolve, reject) => {request.get('/api/demo1', (err, res) => {resolve(res);}).then(res => {request.get('/api/demo2', (err, res2) => res + res2 );}).then(res2 => {request.get('/api/demo3', (err, res3) => res2 + res3)}).then((data) => {res.send(data);});})
}

看起来虽然整齐了一些,但是依然十分繁琐。

// koa1和koa2在写法上基本相同,区别在于koa1在使用之前要对co库和generator进行繁琐的配置。// 每一个await的时候最好加上try-catch,防止因为一个异步请求失败而导致node进程崩溃,这里简化了写法。
module.exports = async (ctx) => {const data1 = await request.get('/api/demo1');const data2 = await request.get('/api/demo2');const data3 = await request.get('api/demo3');ctx.body = {data: data1 + data2 + data3};
}

koa2用起来非常的舒服,很适合前端工程师的思维逻辑。

虽然koa2的代码看起来像同步执行,但其实在编译之后只是变成了promise函数,await后面所有的代码都放到了promise的回调中执行了。

开发结构

选择好了框架之后,剩下的就只有开发了,一般的node层都遵循一下的目录结构:
- node
- lib // 存放第三方插件
- util // 存放自己编写的工具函数
- middleware // 存放中间件
- routes // 存放路由
- controller // 存放路由处理函数
- app.js // node层入口文件

基本的node层架构这里就介绍差不多了,剩下的前端部分也一般是大家熟悉的东西。
前端目录结构:
- public
- static
- src
- js
- components
- containers
- routes
- stores
- actions
- reducers
- pages
- css/scss/less
- img

这里按照正常的React开发逻辑去走即可。

最后还有一些其他的文件夹可以自由发挥,比如template存放模板,scripts存放平时写的脚本等。

配置

一个线上项目要拥有两套模式——生产模式和开发模式。

生产模式即我们线上运行环境。

开发模式即我们平时本地开发环境。

如果有需要的话甚至可以配置更多的环境。

这两种环境的要求不一样,因此我们会有两套配置文件,将不同的配置文件传入node和webpack中,就可以根据配置的不同启动不同环境了。

自动化测试

自动化测试在一个成熟的大型网站中必不可少。

虽然目前因为前端领域的快速增长,业务层的自动化测试也因为业务的快速迭代而变得不稳定,但是一些基础的测试还是很有必要做的。

平时开发的时候要做好类库单元测试的自动化以及UI组件的单元测试的自动化。

这些测试文件最好存放在单独的test目录下,或者在每一个基础UI组件目录下加上component.test.js文件,这样启动测试的时候会自动找到.test文件进行测试。

每次项目上线之前都要进行一次集成测试,测试路由是否正常,webpack打包和node模块安装是否正常,模拟用户登录访问等操作是否正常。

偶尔我们还需要做压力测试和容灾测试等。

对于初学者来说,测试是一个很重要的概念和习惯,平时要多写一写单元测试。

项目源码截图

结语

本文只是初步介绍了一下大型PC网站的前端架构,希望对大家有所帮助,我会继续研究关于技术架构方面的知识的~

我的博客中记录了一些我从零学习前端的笔记(因为最近实习工作忙,很久没有更新了),如果有需要的同学可以去看看~基于React的PC网站前端架构分析

代码地址如下:
http://www.demodashi.com/demo/12252.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_710657.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Python-Flask实现的网站例子

概述 使用Flask写的体育网站 包括&#xff08;注册 论坛 文章评论 组建战队 后台管理&#xff09;等功能 示例地址文中有写 萌新 请多指教 详细 项目示例地址: 网站演示 源码下载地址&#xff1a; http://www.demodashi.com/demo/12380.html 一、环境搭建 1. 安装配置py…

Python-Flask实现基金自选网站

代码地址如下&#xff1a;http://www.demodashi.com/demo/14734.html 项目介绍 本项目的基金数据来自天天基金网&#xff0c;但该网站用户体验较差&#xff0c;内容冗余&#xff0c;故自己实现一个轻量级网站&#xff0c;从8个指标维度对股票基金和债券基金进行挑选&#xff0…

任晶磊:如何看待程序员在 GitHub 发起抗议互联网公司实行 996 工作制网站?

作者&#xff1a;任晶磊 有人说&#xff0c;此行为艺术仍然停留在抱怨的阶段。那么我们来看看出路在何方&#xff0c;所幸已有人在路上。注意&#xff0c;这里都是正在落地的干货。 Disclaimer&#xff1a;我在表达观点时会引用自己的研究工作。如果认为此有夹带私货之嫌&…

大型网站架构系列:分布式消息队列

以下是消息队列以下的大纲&#xff0c;本文主要介绍消息队列概述&#xff0c;消息队列应用场景和消息中间件示例&#xff08;电商&#xff0c;日志系统&#xff09;。 本次分享大纲 消息队列概述消息队列应用场景消息中间件示例JMS消息服务常用消息队列参考&#xff08;推荐&am…

Python网页分析,分析网站的日志数据

前言 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。 以下文章来源于大话数据分析&#xff0c;作者&#xff1a;尚天强 网站的日志数据记录了所有Web对服务器的访问活动&#xff0c;本节通过Python第…

基于django快速开发一个网站(一)

* 创建虚拟环境、基于虚拟环境创建django2.0.0和图片加载库和mysql数据库驱动 1. 创建目录并创建虚拟环境 ╰$ mkdir Cornucopiavirtualenv ╰$ cd Cornucopiavirtualenv ╰$ virtualenv env1 2. 进入bin目录&#xff0c;并激活虚拟环境 ╰$ cd bin ╰$ source activate …

发现一个好看的手机壁纸网站,撸代码的手已经饥渴难耐了

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。 最近有同学的爬虫代码出了bug&#xff0c;给问我怎么改 于是就发现了这个好看的手机壁纸网站。 看到那么多好看的壁纸&#xff0c;我的爬虫已经饥渴难耐…

浅谈web网站架构演变过程

前言我们以javaweb为例&#xff0c;来搭建一个简单的电商系统&#xff0c;看看这个系统可以如何一步步演变。该系统具备的功能&#xff1a;用户模块&#xff1a;用户注册和管理商品模块&#xff1a;商品展示和管理交易模块&#xff1a;创建交易和管理阶段一、单机构建网站网站的…

php域名墙检测,php 网站域名被墙判断请求方法

可以使用exec去进行查询判断&#xff0c;判断traceroute to 出的ip和最后追踪到的IP是否匹配&#xff0c;如果不匹配可能就被墙了。也可以有个保险的方法&#xff0c;去请求下看是否有返回数据没有基本就是墙了。查询命令方法&#xff1a;traceroute --tcp youtubemy.com[rootl…

思科模拟器企业网站服务器配置,思科模拟器服务器配置

思科模拟器服务器配置 内容精选换一换虚拟IP(Virtual IP Address&#xff0c;简称VIP)是一个未分配给真实弹性云服务器网卡的IP地址。弹性云服务器除了拥有私有IP地址外&#xff0c;还可以拥有虚拟IP地址&#xff0c;用户可以通过其中任意一个IP(私有IP/虚拟IP)访问此弹性云服务…

推荐95个极富创意的单页网站设计实例欣赏

随着网络带宽的快速提升&#xff0c;越来越多的Web视觉设计师开始将自己的网页设计推向单页面的表现形式&#xff0c;他们在不断的尝试各种令人耳目一新的设计方案&#xff0c;像下面的这些例子有很多都是出自个人网站&#xff0c;使用JavaScript来实现单页面内的内容切换&…

30 个用于杂志网站的 WordPress 主题

WordPress 已经形成了一个非常完善的生态链&#xff0c;为 WordPress 开发的各种插件、主题越来越丰富。本文介绍 30 个适用于杂志网站使用的 WordPress 主题&#xff0c;其中也包含一些收费的主题&#xff0c;制作非常精美。 免费的 WordPress 杂志主题 Snips DotNews Render …

网站安全检测 Web 安全测试工具

随着 Web 应用越来越广泛&#xff0c;Web 安全威胁日益凸显。黑客利用网站操作系统的漏洞和 Web 服务程序的 SQL 注入漏洞等得到Web服务器的控制权限&#xff0c;轻则篡改网页内容&#xff0c;重则窃取重要内部数据&#xff0c;更为严重的则是在网页中植入恶意代码&#xff0c;…

SharePoint 2010设计(Design)权限能操作的网站操作菜单项

在SharePoint平台中有经典的5大权限&#xff1a;完全控制、设计、参与讨论、只读、仅查看。其中设计权限与完全控制权限有些相似&#xff0c;而只读和仅查看基本上差不多&#xff0c;参与讨论权限主要是针对内容管理的。设计权限在SharePoint 2010里是不能设置权限的&#xff0…

ubuntu服务器网站备份,用 Ubuntu 建立 Time Machine 备份服务器

用 Ubuntu 建立 Time Machine 备份服务器&#xff1a;1、安装 Netatalksudo apt-get install netatalk2、设置 Time Machine 备份文件存放位置, 假设位置在 /backup/TimeMachinesudo vi /etc/netatak/AppleVolumes.default#~/ "Home Directory"/backup/TimeMachine &…

arcgis制作瓦片地图_挖掘Dark Sky Maps(热的要死后,疯传的一个气温地图网站)...

最近&#xff0c;各种朋友圈&#xff0c;社会媒体&#xff0c;都在疯传一张图&#xff0c;这张图显示的全球的气温图&#xff0c;本没有什么特别的&#xff0c;但是这张图的网站来源所展示的数据与气象局或者各种天气预报的温度值相差倒是不少&#xff0c;引来一片网友的吐槽。…

django 跳转其他网站_Django 实战 | 搭一个 GitHub 用户展示网站 04

一、搜索页面跳转在 urls.py 中添加一个 user 路径&#xff1a;from django.urls import path from . import viewsurlpatterns [path(, views.home, name"home"),path(user/, views.user, name"user"), ]在 views.py 中添加一个 user 方法&#xff1a;de…

使用LogParser分析IIS网站日志

LogParser是个强大的&#xff0c;多功能的分析工具&#xff0c;它统一的查询方式适用于各种文本类型文件&#xff08;例如日志文件&#xff0c;XML文件&#xff0c;CSV文件&#xff09;和操作系统层面数据文件&#xff08;例如事件日志&#xff0c;注册表&#xff0c;文件系统&…

Webydo:一款在线自由创建网站的 Web 应用

Webydo 是一款专业的在线建站应用&#xff0c;使平面设计师可以创建和管理 HTML 网站&#xff0c;而无需编写代码。设计人员可以设计任何类型网站&#xff0c;只需要点击按钮&#xff0c;就能够发布先进的 HTML 网站。 你可以控制所有的设计组件&#xff0c;如&#xff1a;元素…

元素“Button”不是已知元素。原因可能是网站中存在编译错误,或者缺少web.config文件...

最近开发的时候ASP控件都有波浪下划线&#xff0c;提示不是已知元素&#xff0c;搞得挺郁闷的。虽然不影响变异&#xff0c;不过就是不爽。 折腾N久...... 解决了&#xff0c;把FramWork平台换成3.5&#xff0c;问题解决&#xff0c;不知道为啥&#xff0c;求大神指点。 问题描…