当前位置: 首页 > 科技观察

前端工程是什么意思?

时间:2023-03-16 16:27:28 科技观察

大家好,我是前端西瓜哥。今天我们就来看看什么是前端工程。什么是前端工程?工程可以理解为用一些方法来改进和改进行业中已有的步骤、设计和应用方法。前端工程是指在前端对一些流程进行标准化,让开发更高效,更好地交付产品。一开始,网页并不复杂,只是提供一些简单的静态页面展示和交互,甚至不需要后台。后面我们需要根据不同的用户返回不同的页面信息。这时候我们会使用后端读取数据,配合一些模板引擎,在后端拼接内容返回,也就是所谓的服务端渲染(SSR)。后来页面变得很复杂,于是前后端分离,把前端拿出来分别写html、css、js,就成了单页应用(SPA)。但是复杂也带来了很多问题,比如多个脚本的执行时机不对,css名称冲突,文件过于臃肿,错误的缓存导致无法下载最新的资源,以及前端复杂后出现的一系列问题。随着Nodejs的诞生,我们可以使用JS来编写前端工具了。为了解决以上问题,前端界出现了很多工具和框架:Gulp、Angular、babel、Sass、React、Vue、Webpack、Yarn、TypeScript、ESLint、Docker、k8s等等。一切都是为了让前端开发更工程化,也就是不断完善前端项目的开发流程,让开发者更高效的开发,更好的协作,规范代码风格,压缩资源和懒加载,更好的交付deployments等等(当然因为工具太多,前端直接喊“学不会了”)下面通过四个维度来谈谈前端工程化的一些具体细节,即:模块化,标准化、自动化、模块化、模块化。最重要的是将代码功能拆分成独立且相互依赖的片段。首先是JS的模块化。JS最初的职责是为网页提供一些简单的交互,所以语法比较简单,不支持模块化。随着网页的复杂化,发现原来的组织方式带来了很多问题,变得难以维护。于是出现了CommonJS、AMD、ESModule等模块系统。正统的标准是ESModule,通过import关键字导入模块,通过export导出模块。JS模块化拆分代码,解决全局变量污染、依赖不明确、多人协作不便、脚本引入顺序、单元测试等问题。CSS模块化。CSS的第一个问题就是难写,比如不支持选择器的嵌套。为此,我们可以使用CSS预编译器(如Less、Sass、Stylus)编写一些更高级的语法,然后将其编译成CSS。然后就是命名冲突的问题。一个老的解决方案是BEM,就是在一个组件化的框架中命名CSS。我们有很多解决方案,比如CSSinJS,CSSModule,或者Vue-specificCSSScoped。HTML模块化。HTML通常是动态的。在服务端,我们会使用一个模板引擎(template)将获取到的数据注入到占位符中。后端Nodejs,我们可以使用pug、handlebars、ejs等,前后端分离后,我们通常使用Vue的template(类似handlebars的语法)和React的JSX。资源整合和模块化不同类型的资源无法组织在一起。比如JS引擎可以识别导入的js文件,但是不能识别css文件。如果我们希望将所有资源统一组织管理,那么将不同类型的资源分开管理会方便很多。为了解决这个问题,webpack诞生了。webpack是一个模块打包器,可以将任何资源转换成js代码导入。比如图片可以先转成静态资源服务的资源,然后在js文件导入的时候转成url字符串,或者直接转成base64字符串。这些都需要用到一些加载器(loader)。webpack是一个框架。用户需要根据自己的需要添加一些loader来识别不同的文件并转换成JS代码导入。另外还有插件,在整个过程中做一些处理,比如将导出的JS文件插入到HTML模板中,或者压缩代码等。自定义元素”类似于div等原生元素。组件有自己的HTML、CSS和JS,也有自己的状态,支持嵌入到其他组件和接受外部数据进行复用。组件化可以看作是UI层组织方式的模块化。目前主流的React和Vue前端框架都是基于组件的。原来的组织管理是按资源类型组织的(所有的JS文件都放在一个文件夹里,CSS也一样)。事实上,它很难维护,也不容易复用。组件化的思想是在视觉上进行拆分。将结构、风格、剧本组合起来,抽象出一个“新元素”。组件已经是前端开发的基石,是一种合理的抽象。规范化就是前端代码的规范。规范对于使代码更容易和更正确以避免不必要的错误非常重要。可以想到的规范有:目录结构规定。代码风格(包括JS、HTML、CSS)。注释规范。提交消息规范。git工作流规范。代码审查。请求接口规范。一些规范受工具的限制较少,例如目录结构。但是一些规范可以使用工具。下面说一下与规范相关的工具。首先是重量级的TypeScript。TS是TypedJS,是JS的超集。通过类型,我们可以预测变量的行为。例如,布尔值类型不能作为函数调用,可能未定义的值需要缩小并丢弃未定义的可能性,然后才能使用。TS越来越受欢迎,因为在大型项目中,类型系统非常重要,可以避免大量的类型错误。TS让代码成为文档,降低程序员理解代码的成本。如果工具层可以制定规范,则不应在文档中进行说明。人不是绝对正确的机器,但工具可以。然后是ESLint。ESLint可以检测JS代码中的错误,主要体现在两个方面:代码质量,比如你不能声明一个没有使用的变量。代码风格,如字符串引号必须使用单引号。ESLint有助于统一团队的风格,让代码看起来像一个人写的,避免字符串使用单引号,一会儿使用双引号,一会儿使用下划线样式的变量命名,一会儿使用驼峰样式,这种把强迫症逼疯的情况。然后是提交消息。Commitmessage我们不想看到像“Fixedsomebugs”这样不够具体,但是有一定结构的东西,比如“fix(workbench):Fixedtheproblemthatcardscannotbescrolled”。对此,我们可以使用commitlint命令行工具来判断是否符合特定的风格。当然,也要保证团队成员使用这些工具,我们可以在保存后自动格式化(需要配合编辑器和相应的插件)。然后最重要的就是githook,它可以在本地commit的时候先检查并格式化staged中文件的风格,然后再检查commitmessge的风格。否则,本地提交将失败。对应的工具是husky。将可以自动化的重复流程工作自动化,并且应该尽可能自动化。做起来对人来说是一种折磨,质量也得不到保证,因为工艺通常很复杂,即使很简单,做多了也很容易出错。一个小概率事件只要做的次数足够多,就会变成大概率事件。这就是容错机制在分布式系统中非常重要的原因。首先想到的自然是CI/CD(持续集成和持续交付/部署)。当我们将代码提交到远程仓库,或者打上分支后,我们可以触发一些脚本,将我们的项目代码打包编译,发布成产品,然后发布到生产环境。这些都是自动化和简化的。CI/CD工具有很多:Jenkins(比较老)、GitLabCI/CD、GitHubAction、Docker(发布工件)和k8s(容器编排)等,前面提到的githook可以看作是一个简单的自动化来执行本地提交时的一些操作。打包工具前端工程的核心是打包工具。打包工具需要支持几个重要的功能:代码拆分:是指将代码分成多个包或组件的能力,这些包或组件可以按需/同时加载。例如动态导入、提取公共依赖模块代码、多入口文件无重复代码、支持ESM的值引用模拟等。Hash:资源更新时的Hash,防止资源缓存。哈希有很多种,例如文件路径名哈希、内容哈希等。包导入:支持ESModule、CommonJS和从node_modules目录导入包。非JS资源:支持导入非JS资源,比如webpack需要各种loader支持,内置一些打包工具。输出模块格式:支持输出到ESModule、CommonJS等模块。转换处理:比如图片压缩、代码压缩、JS版本缩减等,都是在webpack中使用插件实现的。还有其他分散的工具可以提高效率。babel:开发时使用高版本ES语言特性,然后在生产环境使用babel转换为兼容性好的低版本ES5。打包工具内部其实使用了babel。tsc:tsc(TS编译工具)在支持TS的前提下,支持编译到低版本的JS。Polyfill:在ES5的低版本中,如果要使用一些新的API,可以自己写函数模拟。这是polyfill。通常我们使用core.js库,但是一些语言层面的新特性不能使用polyfill。monorepo:将多个项目放在一个git仓库下,方便包依赖共享和维护。异常监控:当前端报错时,将相关信息提交给异常监控服务,比如sentry,通常配合sourcemap在源码中准确定位错误位置。产品库:使用Nexus部署自己的私有产品库,支持各种产品库。比如发布docker包,npm包等,配合release部署;VSCodeSnippet:自定义VSCode编辑器的代码片段,可以快速生成一些预设的代码模板,减少一些模板代码的编写。可以归类为自动化。Mock:前端在完成接口之前,在后端确认返回的数据结构后,可以通过模拟虚假数据进行调试开发。比如yapi平台不仅支持接口文档,还提供了mock函数。单元测试:以模块(如组件)为单位进行测试,确保代码逻辑符合预期。单元测试通常比较耗时,会在提交到远端或者合并到主分支时进行。一个流行的单元测试库是Jest。Hotreload:因为每次更改代码,都必须编译。如果需要重新编译整个项目,开发体验很差。您可以使用热重载来仅编译修改后的模块。组件库文档:stroybook可用。如果是vue组件,可以考虑使用VuePress。Treeshaking:扔掉一些导入但未使用的模块。简单来说,前端工程就是对前端开发流程的改进,是一种效率工具。