前言
前端早已经离不开编译打包了。为了在开发中用上新的语法,先后涌现出babel,SWC等语法转译工具;为了在产线快速定位问题代码,有了sourcemap;为了减小产物代码体积,有了诸如terser一类的代码压缩工具;为了一统前端涉及的文件类型,各种各样的模块解析转换库层出不穷,其中,我印象最深刻的就是webpack的一系列lodaer……正是这些看起来不太相关的功能构成了前端工程化的基础,进一步降低了前端的开发门槛。本文聚焦于简单的前端项目打包及相关工具推荐。
为什么需要打包?
JavaScript 语法降级
是,浏览器是能跑js,但是,js的语法是一直在迭代的,近几年几乎每年都会加上些新功能点,而浏览器在支持js的新功能上肯定不会那么积极与及时。即使浏览器新版本支持了,但是用户不更新浏览器那也白搭。作为前端,我们写的代码不像后端一样是与容器无关的,前端代码的表现和浏览器息息相关,在谷歌浏览器上一切正常,不代表在火狐浏览器上也是。(也正是因为前端代码和容器息息相关,所以前端项目如果是要跑在浏览器上的话,像后端项目那样只写单元测试是远远不够的,e2e测试是重中之重)
可是,js的一些新语法实在是太香了,是能在极大程度上降低开发者的上手成本和提高开发效率的,我想,现在不会有前端喜欢手写es5吧?基于此,JavaScript语法降级大热。它的目标就是支持开发者能够在开发中使用较新的语法,而在编辑打包阶段将新的语法降级到指定的版本,常为es5。当然,你不想降也可以,只要你项目跑得起来。🧐
代码压缩
前端一切的一切都需要在特定的容器里正常执行。作为一个网页项目,你需要关心HTML/CSS/JavaScript文件的大小,因为文件的大小会影响到在网络上的传输速率,在其他条件相同的情况下,自然是文件越小越好;即使不是网页项目,而是类似于APP的项目,也照样需要关注代码的体积。
你说:
const aaaaaaaaaa = 'liting-yes'
console.log(aaaaaaaaaa)
和
const a='liting-yes';console.log(a)
的执行结果一样吗?自然是一样的。代码压缩工具的原理就是这样,在保证功能不受影响的前提下,尽可能地用更小的变量名、更少的空格……甚至换行符都省了,以达到压缩代码的目的。这个时候,就不需要考虑代码的可读性了,又不是不能用,你说是吧?
sourcemap
接着上一节说,现在的代码被压缩了,靠人肯定是读不下去了。但是,万一这个时候代码有bug报错了,该如何排查?那一行成千上万的字符,abcde的变量名,去哪里定位问题?这个时候,sourcemap 就出场了。它通过在项目编译打包时记录代码的位置偏移信息,对代码打包前后的文件位置做了一层映射保存了下来。基于此,在打包后的代码报错后,也可以根据 sourcemap 定位到打包前的代码位置
模块转换
对于浏览器支持的文件类型,你应该可以想起来:HTML/CSS/JavaScript,没错,就这三兄弟。但是,在一个真正地有些许复杂度的前端项目中,涉及到的文件类型就很多了。有css的拓展scss/less/stylus,各种图片类型,vue单文件组件,甚至JS的超集 TypsScript 也算。因为前端项目的基础是JS语法,但是这些类型的文件因为不符合JS的模块标准,JS是识别不了的,所以,才需要一个模块转换的工具,能够将这些各种各样的文件类型都转换为JS模块,至少要JS能够正常的导入导出和读取信息。
打包工具推荐
Vite
在2023年,首推 Vite 不过分吧?它最大的优势是开发时的快速启动和热更新。但是,即使只作为一个简单的打包工具,vite也可以做的很不错,甚至你只需要简单配置一下 build.lib,一切就都能运行的很好
Rollup
作为前端届的新贵,Rollup随着Vite的流行也越来越受欢迎,如果你是想打包一个纯粹的工具库,Rollup是个不错的选择,它的官方文档都已经加入了Vue生态大军了,不得不说,还是挺好看的。不过,虽然英文也能看懂,但是如果官方支持中文版就更好了
Webpack
作为前端界的老大哥,Webpack在我眼里一直都是那个最稳的,你永远可以相信它,就是要自己配置的东西太多了。它实在是太相信开发者了,啥都让自己干。
Tsup
Tsup 是一个基于 esbuild 的打包工具,它简单易上手的配置非常迷人,绝对是新人/工具库开发者的小棉袄,你完全可以使用几行配置文件就搭建好了一个强大通用的打包编译环境。有点小遗憾是它也只有英文文档,我之前无聊到是翻译了一下,感兴趣的也可以点点中文翻译
后话
我本来想仔细写写诸如 tsup 的配置的,但是,一看时间,晚上十二点多了……