当前位置: 首页 > Web前端 > HTML

浅谈前端工程化发展及相关工具介绍

时间:2023-03-28 16:22:16 HTML

什么是工程化?什么是前端工程?需要面对越来越复杂的系统性问题,比如模块化文件的组织、ES6JS文件的编译、所有JS代码的打包压缩、图片静态资源的优化合并等等。我们的项目需要进行合理的组合,以应对项目在团队协作和需求迭代中的稳定发展。这种方式是设计系统来运行我们的项目。比如下图,就是前端工程中的一个打包过程。左侧是出现在我们项目中的源文件。比如我们会使用sass作为预处理风格来更好的组织我们的风格代码,使用其他各种语言比如typescript、coffescript等来编写我们的逻辑脚本。当我们终于上线的时候,需要把我们的文件转换成在线浏览器可以直接识别的css和js。这种用工程化的思维,以工具的形式来进行上述过程,就是前端的工程化。总而言之,前端工程就是用工具来处理与实际业务无关的内容,比如处理JS编译、打包、压缩、图片合并优化等各个方面的工程代码。前端工程特定类包管理工具对于一个成熟的语言,在有语言规范的同时,制定语言规范的社区或组织也会有模块化的规范和模块存储在平台上,大家可以自己编写的模块化代码自己发布在平台上,任何人也可以在公共平台上下载别人的模块化代码。我们一般将这种模块化的代码称为包,平台我们称为包管理平台,这种行为我们称为包管理器。对于JS,现阶段大家比较熟悉的就是node.js环境自带的npm工具。npm的全称是nodepackagemanager,是node.js的包管理工具。对于符合规范的包,我们可以通过npmpublish发布包。同样,npminstall也可以用来下载别人发布的包,实现模块复用。社区常用的包管理工具有bower、npm、yarn。仍然经常使用的是npm和yarn。bowerbower最早出现在浏览器项目中。安装bower命令后,可以通过bowerinstalljquery下载jquery到bower_components目录下,我们可以在html文件中添加。省去了我们直接从官网下载然后移动到项目中的麻烦。Bower也支持一些配置,我们只需要在项目根目录添加.bowerrc配置即可:{"directory":"app/components/","timeout":120000,"registry":{"search":["http://localhost:8000","https://registry.bower.io"]}}上面的配置主要是配置我们下载后的模块存放目录,下载超时时间和下载地址等,如果要发布一个bower模块,需要在我们项目下配置bower.json,然后通过bowerregister命令发布。bower内容介绍比较简单,现在在新项目中用的不多。本节关于包管理工具的重点是npm。npmnpm是随node.js下载一起安装的命令。它的功能和bower一样,都是下载或者发布一些JS模块。我们可以使用npm--version查看安装的npm版本,不同的版本有不同的功能。同时,我们可以通过npminstall安装一个模块。比如上面的例子,我们可以通过npminstalljquery来安装jquery,npm会把模块安装到node_modules目录下。一个合格的npm包必须有一个package.json文件,该文件包含以下公共字段:name:包或模块的名称version:版本main(重要):默认加载的入口文件scripts:定义一些脚本依赖项:Modulesrequired运行时devDependencies:本地开发需要运行的模块optionalDependencies:可选模块,即使安装失败,安装过程也会正常退出以“version.Minorversion”格式规范。我们通过npminstall安装的模块最终会被记录下来同时,我们通过npminstall的时候,也会安装这里记录的模块,而node_modules中没有,如果前面有波浪号(~),则主版本号和次版本号占优,如“~1.3.2”版本,最后安装时会安装最新版本的1.3.x。如果前面有脱字符(^),则表示主版本号为主,如“^1.3.2",最终安装将安装最新版本的1.x.x。高版本的npm会把所有的依赖“扁平化”,从而保证尽可能少的安装相同的模块。所有下载的模块最终都会被记录在package-lock.json中,实现对版本的全面锁定。下次我们执行npminstall时,我们将首先下载package-lock中的版本。yarnhttps://yarnpkg.com/Yarn是一个新兴的包管理工具。它和npm有类似的功能,最大的优势就是并发和速度。我们可以通过yarnadd安装一个模块,通过yarnxxx在scripts中运行脚本。包管理工具常见面试题devDependencies、dependencies、optionalDependencies、peerDependencies的区别DevDependencies指的是在使用本地开发时需要用到,但在实际业务操作中用不到的模块。依赖是指业务运行所需要的模块。optionalDependencies是一个可选模块,可以安装也可以不安装。即使安装失败,包安装过程也不会报错。peerDependencies一般用于大型框架和库的插件。比如我们写webpack--xx-plugin,对于用户来说,他必须先有webpack,然后再安装我们的模块。这里的peerDependencies约束了这个例子中webpack的版本。对于大型项目,npm中的--save-dev和--save之间的区别并不是很清楚。真正不同的地方在于我们安装所有依赖项的方式。save-dev和save都会将模块安装到node_modules目录下,但是save-dev会将依赖名称和版本写入devDependencies,save会将依赖名称和版本写入dependencies。如果我们使用npm--productioninstall这样的命令安装模块,则只会安装save安装的包。源代码静态检查和格式化工具静态检查是指我们在本地编写源代码时,通过我们使用的编辑器对我们编写的代码进行提示、检查和格式化。在大型项目中,这一步因人而异,大多不做共同需求。检查和格式化一般会限制团队使用的内容,以确保每个人都能写出“正确”的代码和统一的代码风格。对于代码检查和格式化,前端开发中比较经典的有jslint、jshint、eslint和prettier。它们基本上是一种工具。再细分的话,jslint、jshint和eslint是一类。他们专注于JS格式化和静态语法检查。Prettier是另一种类型。它可以处理多语言格式。eslinteslint官网:https://eslint.org/我们以eslint为例,我们只需要在项目中通过npminstall--save-deveslint安装,配置.eslintrc(运行时配置)。有了eslinteditor插件,我们在编辑代码的时候就可以使用eslint来提示和修复我们的代码了。通过配置像eslintindex.js这样的脚本,可以对脚本文件进行静态检查。注意这里使用--save-dev是因为我们只需要在项目开发时使用它,而不是在运行时使用这个模块。Prettierprettier官网:https://prettier.io/,同样我们可以配置prettier的配置,.prettierrc也可以配置,最后配合prettier的编辑器插件,我们也可以在代码中实现提示和修复编辑状态。源代码静态检查和格式化工具静态检查是指我们在本地编写源代码时,通过我们使用的编辑器对我们编写的代码进行提示、检查和格式化。在大型项目中,这一步因人而异,大多不做共同需求。检查和格式化一般会限制团队使用的内容,以确保每个人都能写出“正确”的代码和统一的代码风格。对于代码检查和格式化,前端开发中比较经典的有jslint、jshint、eslint和prettier。它们基本上是一种工具。再细分的话,jslint、jshint和eslint是一类。他们专注于JS格式化和静态语法检查。Prettier是另一种类型。它可以处理多语言格式。eslinteslint官网:https://eslint.org/我们以eslint为例,我们只需要在项目中通过npminstall--save-deveslint安装,配置.eslintrc(运行时配置)。有了eslinteditor插件,我们在编辑代码的时候就可以使用eslint来提示和修复我们的代码了。通过配置像eslintindex.js这样的脚本,可以对脚本文件进行静态检查。注意这里使用--save-dev是因为我们只需要在项目开发时使用它,而不是在运行时使用这个模块。Prettierprettier官网:https://prettier.io/,同样我们可以配置prettier的配置,.prettierrc也可以配置,最后配合prettier的编辑器插件,我们也可以在代码中实现提示和修复编辑状态。ES6等泛JS语言的编译很多时候,我们无法在网上直接使用ES6语法规范的JS代码,需要通过工具来编译JS。同时,对于一些项目,我们可能会使用coffeescript、typescript、flow、elm、ocaml等可以编译成JS语言的泛JS语言来编写代码,这就需要借助编译工具来编译调试或发布时将相应代码转化为JS代码。直接运行。在编译过程中,JS常用的工具是babel,其他语言都有自己的编译器。比如coffeescript使用coffeescript编译器编译成js,typescript使用typescript编译器编译成js。babelbabel的官网是https://babeljs.io/。对于一个项目,我们可以使用npminstall--save-dev@babel/core@babel/cli来安装babel需要的工具。@babel/core是babel内部的核心编译和代码生成方式@babel/cli(commandlinetool)是babel命令行工具内部的解析方式安装好这两个包之后,我们就可以使用babel相关的方式来编译code进行操作,接下来我们需要进行配置,告诉babel我们需要将代码改成什么。添加一个babelpreset,代表我们要编译的结果的预设值。在最新的babel工具链中,统一使用@babel/preset-env作为环境默认值。我们安装npminstall--save-dev@babel/preset-env后,新建一个.babelrc,在scripts中定义一个脚本,通过配置{"presets":["@babel/preset-env"]来执行babelindex}.js-ooutput.js,我们在index.js中编写的es6语法将被编译。这一步只是在语法层面编译内容。如果我们使用一些新方法,我们需要添加一个polyfill。使用npminstall@babel/polyfill安装完所有符合规范的polyfill后,我们需要在入口文件中引入这个模块,就可以正常使用规范中定义的方法了。对于JS语言不同环境下的JS打包工具,常见的模块化规范有CommonJS、AMD、ESModule等几种,它们各有不足。CommonJS只能在node.js上运行,无需处理。AMD不经过处理是不能在各种平台上使用的。它需要与其他符合AMD规范的库一起使用,例如require.js。ESModule虽然从语言层面解决了规范问题,但即使是通过babel编译,import、export等关键字也会被编译到CommonJS的require、exports中,我们还是不能直接在浏览器中使用。为了让任何模块可以自由切换使用环境,比如在浏览器中使用CommonJS打包的模块,我们需要经过打包这一步。browserify、rollup等工具都处理这样的事情。Browserify地址:http://browserify.org/我们通过npminstall--save-devbrowserify来安装browserify,我们写了一个简单的commonJS模块,我们可以通过browserifyindex.js-ooutput.js命令对CommonJS进行模块化包改造成通用的、模块化的规范,可以被任何环境加载。rollurollup是一个新兴的打包工具。它首先提出了一个概念,叫做treeshaking,可以去掉我们代码中其他无用的代码。通过ESModule编写的模块会在rollup处理后标记未使用的导出内容,这些未使用的内容将在压缩过程中被删除。经过JS压缩工具编译打包后的JS代码,经过在线压缩后,最终可以在网站上展示给用户。目前有很多JS压缩工具,但使用最多的是uglify系列。uglify最新的版本是3版,不同的uglify的实现原理和性能差别很大。UglifyUglify3地址https://github.com/mishoo/Ugl...安装成功后,很简单,只需要通过uglifyjsindex.js-ooutput.js即可输出压缩后的结果。同时我们可以通过添加--source-map在运行时生成站点地图文件,方便我们调试。其他类工具任务处理工具(gulp/grunt)我们上面提到的所有工具都是针对某个垂直领域的,比如编译、打包、压缩等,我们需要通过不同的命令来运行和操作我们的JS文件。所谓任务处理工具就是这类脚本工具,它们可以将不同的工具以脚本的形式组合输出。最常提到的两个流处理工具是grunt和gulp。下面介绍这两个工具。gruntgrunt官网https://gruntjs.com/。首先通过npminstall--save-devgrunt安装grunt工具,新建一个gruntfile.js,通过gruntfile.js中的配置让grunt做不同的操作。这里我们安装npm--save-dev@babel/core@babel/preset-envgrunt-babelgrunt-contrib-uglify来完成一个项目的搭建。通过配置gruntfile脚本,我们分别执行编译和压缩的过程生成最终的js脚本。Gulpgulp官网https://gulpjs.com/同样,我们使用npminstall--save-devgulp安装gulp工具,并新建一个gulpfile.js配置。我们还实现了相同的功能来重新配置gulp任务。相比grunt,gulp的配置更清晰,写成链式调用。Generalprocessingtools(fis3/webpack)Generalprocessingtools在这里,我们的分类是从功能上来说,是上面列出的类别的多个功能的集合。我们在这里列出的一些工具是fis3和webpack。fis是国内百度早期发布的一款前端通用处理工具(早于webpack)。fis3是它的第三代,使用node.js重写。fis3和webpack最大的特点就是不再是普通的工具,而是一个插件系统,拥有丰富完善的社区环境。它们属于前端解决方案领域。从理论上讲,它们可以做很多事情,不像上面介绍的大多数工具只能处理某个垂直类别的内容。其实webpack有点类似于gulpgrunt等任务处理工具,只不过它本身具有打包的功能,同时也支持通过中间件和插件实现其他领域的功能,最终所有的操作都可以通过一个命令。webpack通过webpack.config.js配置配置loader中间件对不同的文件进行操作,通过插件配置支持压缩等操作。使用fis3和webpack,他们更多的集成了我们前面提到的所有其他工具,并以插件的形式加载,从而达到通用的目的。