近几年来,前端的发展速度非常夸张,除了令人眼花缭乱的种种框架,五花八门的前端构建工具更是层出不穷,要在众多选择中选择一套完美的解决方案似乎非常困难。但其实,如果能在关键点上了解各个工具的本质,一切就会显得清晰无比。

前端构建工具

依赖管理


npm

严格意义上,npm不完全是一个前端构建工具,它起步于Node.js,逐步发展为全球最大的开源社区的,为JavaScript开发者提高了大量的前后端库,工具,组件以及框架。npm提供了强大的包管理机制,可以在其中方便地寻找到前端开发过程中需要使用到的各种依赖,将它们集成到项目工程中,并根据开发,生产和单元测试等多种场景对其进行配置管理。许多前端构建工具都可以通过npm进行安装,甚至依赖于它。

Bower

Bower是一个面向Web前端的包管理器,它专注于为Web开发中涉及到的框架、库、资源以及辅助工具等提供依赖管理的服务。不同于npm中的嵌套结构,Bower使用的是扁平式的依赖管理结构,将前端涉及到的所有包统一维护在一个地方。整体上看,Bower所提供的功能更像是npm的一个子集,只不过提供了更简单的配置和相对宽松的包结构约束。Bower目前已经不再更新,只是保持维护,其官方推荐使用Yarn和Webpack来构建前端工程。

Yarn

npm在获取和安装大量依赖包时会同时发送大量并发请求导致下载速度缓慢;另外,有时,两次完全一样的npm install抓取到的却是不同版本的依赖。为了有效解决这些可能影响效率或是埋下安全隐患的痛点,Yarn应运而生,它的机制大体可以概括为:

  • 通过有选择地对依赖包请求进行排队处理,避免了npm的缓慢问题,最大程度地利用了网络资源。
  • 下载依赖包失败时采取稍后重试的方法,使得单个依赖抓取失败不会导致整个过程需要重新开始。
  • 将所有下载过的依赖包缓存起来,以便再次使用能够快速获取,同时也使得离线安装成为可能。
  • 针对每次依赖的获取或更新,在可选的多个依赖本中确定唯一版本,并将其记录到锁文件中,以此保障依赖关系的确定性,避免创建多个依赖副本。

自动化


Grunt

Grunt通过创建不同的任务结合使用不同的插件将前端代码在由开发转向生产过程中涉及到的压缩,混淆,合并,验证等诸多工作进行自动化,以达到节省劳动成本和简化工作内容的目的,开发者因而能够更加专注于开发工作。

Gulp

Gulp和Grunt非常类似,在功能上其实相差不是非常的多,但它在Grunt的基础上做了一定的改进:

  • 使用代码优于配置的策略,让复杂的任务也变得更易于管理;
  • 利用Node.js强大的流处理能力,省略了写入中间文件的过程,提高了构建效率;
  • 遵循严格的设计原则,每个插件只完成一个功能,插件通过流进行交互协作完成任务;
  • 最小化API的设计,大大降低了学习成本

npm Scripts

npm本身化也支持一定的自动化运行机制,因为Grunt和Gulp都有各自自身的学习成本等原因,而npm本身与Node.js大环境的互通性,有的人会选择牺牲一定的劳动成本去使用npm Scripts来实现更加灵活可控,更适合自己的自动化。

模块打包


Browserify

Browserify是对具有Node.js风格的前端commonjs模块进行编译打包并提高第三方库或插件的模块打包方案。Browserify本身的模块系统和Node.js是一样的,也采用了模块化的实现方式。 Browserify配置简洁,结构清晰,具有很强的可定制性,结合Gulp和Grunt等工具可以灵活地构建前端系统。 不过,在常用的场景中Browserify往往需要搭配其他工具才能完成预期的目标,需要更多的适配工作。

Webpack

得益于健全的功能和便利的特性,Webpack一度成为前端构建的标配,占据了主要的市场。

在Webpack中,所有文件都是模块,它会根据指定的模块入口文件递归地扫描所有关联模块,通过使用不同的loader来对不同类型的模块进行加载,根据扫描结果构建模块之间的依赖网络。 Webpack还有一个重要的组成部分,那就是plugin,Webpack自身核心也是以plugin的形式构建的,plugin承担了代码优化,依赖注入,文件抽取,模板引擎等等所有loader不能做到的事情。 结合loader和plugin以及具体配置,Webpack最终会将所有文件按一定的形式打包成若干个出口文件。模块化的特点加上较为全面插件系统为开发提供了极大的便利。此外,Webpack还支持自定义plugin,根据需要对模块进行处理,为系统提供了一定的可扩展性。

rollup.js

rollup使用ES6定义的模块化标准对JavaScript和CSS进行模块打包,在理论上要比Browserify和Webpack使用commonjs规范的性能更好。 rollup还具有tree-shaking特性,可以剔除引用的模块中没有使用到方法,从而将打包文件尽可能的压缩到最小。 相对于Webpack,rollup在性能和规范化上似乎更胜一筹,但由于还在成长中,rollup的插件生态和相关文档还很匮乏,有待进一步的发展。

Parcel

Parcel是最近横空出世的新兴模块打包方案,主打快速打包和零配置。具体包括:使用多核编译和文件缓存来有效提升打包工作的速度;支持对多种格式的文件打以及基于内置的babel等对代码进行自动转换而不需要插件和配置;借助动态的import方法对代码进行拆分以实现代码懒加载。同时,Parcel还提供了模块热替换以及高亮错误提示等实用功能。 当然,Parcel也存在一定的局限性,比如打包文件比较大,使用的场景有限,可配置程度相对较低等。

脚手架


Yeoman

Yeoman旨在借助一些预定义好的经过考验的最佳实践为新项目的展开提供参考和基础架构, 它会通过不同的generator生成一个包含脚手架 工具,构建工具以及包管理器的完整前端工作流,为开发者节约大量的劳动成本。

总结


  • 前端的构建工具还有很多,这里只是选取了部分作为参考,期望能够举一反三。
  • 避免刻意追赶潮流,结合实际需要合理地选择适当的工具。
  • 在允许的情况下可以选择更为简单的方案,而不是非要强调最优解。