前端 Webpack 工程化的最佳实践


前端 Webpack 工程化的最佳实践

文章插图
作者 | 阿里文娱前端开发专家 芃苏
责编 | 屠敏
头图 | CSDN 下载自视觉中国
 引言
? 前端构建工具的演变
回想在2015-2016年的时候,开发者们开始渐渐把视线从大量使用Task Runner的Grunt工具,转移到Gulp这种Pipeline形式的工具 。Gulp还可以配合上众多个性化插件(如gulp-streamify),从而使得整个前端的准备工作链路,变得清晰易控,如刷新页面、代码的编译和压缩等等 。自动化“流水线”工具取代了很多繁杂的手动工作,可以说,是具有跨时代意义的 。之于Webpack而言,其本质是是基于“模块化”思想的一个“JS预编译”解决方案,诞生初期,和其相似的方案还有Browserify,和Webpack属于同门不同派别的还有sea.js或require.js,这二者需“在线依赖”解释器编译 。
时至今日,多数日常工作接触的项目,已经可以完全的舍弃Gulp了 。但工作中有时还会接触一些老项目,其中Gulp的使用和维护屡见不鲜 。2019年初之时,通过一个老项目(gulp 3.x + webpack 3.x)的技术升级,借机了解了gulp 4.x的动态,又不禁让人回想起gulp-browserify,和gulp-webpack(五年前发布,目前改名为webpack-stream) 。所以,Webpack做为某一个垂直方向的解决方案,当然可以manaually built-in Gulp中 。在拿Webpack“方案”和Gulp类“工具”去做正面比较的时候,需要明晰两者解决问题的范围和思路 。如今再次回顾历史,对技术的发展演变顺序,能有一个基本客观的概念 。
在2017年的时候,Gulp和Webpack在用户的使用率和“将继续使用”的意向上,还不分伯仲 。但从《State of JAVAscript 2019》 中可以看到,Webpack已经完全碾压了其它工具和类库,成为了首屈一指被大家广泛使用、讨论的Build Tool 。2018年2月25日Webpack 发布了4.0.0正式版本;那是对不少项目进行了Webpack 4.10.2版本的升级;过年前后,又将部分项目升级到了4.29.0 最新版本 。这一系列的“跟进式升级”中,一方面是在不断融入Webpack对于模块构建的新思路和理念,为了能够更好的适应其未来的变化(Webpack 5.x的beta版过应该不久就会面世了),另一方面是在一个好的方案中不断尝试,结合项目的基础设施优化,从而提高效能,保障产品稳定 。
? 本次回顾
Webpack工具虽说只是前端项目CI流程的一个小部分(构建 build),就它自身而言,所涉及到的Node知识和包依赖管理经验,是一整块技能 。细节来看,里面涉及了Webpack自己的包和第三方plugin生态,还要配合恰当的babel、typescript、flow.js、eslint配置等多个生态,去处理JavaScript语言本身的编译/转译 。以及,正确管理本地静态资源文件和远端CDN资源文件路径(打包配置决定打包结果),涉及到了跨域知识和Node层服务配置、模板配置知识 。更进一步还有,NPM众多包的版本管理等让人头疼的问题 。其中琐碎细节数不胜数,当所有第三方工具正确使用的前提下,也许还有些plugin小工具,需要开发者去自研发 。知识谱系之大,可见一斑 。
本文不描述Webpack Docs使用指南,也不描述第三方插件的使用“指北” 。更多的是结合过往项目经验,记录实践得出的使用技巧,也记录一些走过的弯路所带来的问题,希望对其它众多的前端技术人能够起到一点借鉴作用 。(Package Checking List:React: 16.3.2,Babel: 7.0.0,Webpack: 4.29.0,Node: 11.8.0)
 文件结构
在4.x版本中的早期,CLI工具集里的命令是Webpack主包自带的,但在Webpack 4.x后期的版本,将webpack-cli作为独立包剔除出去,需要手动单独安装才可以执行tnpm run start这样的脚本命令 。其次,对于开发/日常环境(dev)和预发/生产环境(prod)来说,打包的策略是截然不同的:
1. 对于dev日常环境:
  1. 方便的debug和troubleshootin,有比较强的source mApping;
  2. 希望能够得到颗粒度较小、且有根据变动代码针对性的的加载(live reloading/hot module replacement);
  3. 希望可以做一些代理Proxy相关的调试;
  4. 可以方便的根据开发者的情况,对本地的dev-server进行配置等 。
2. 对于Prod生产环境:
  1. 通过压缩Javscript/css代码,获取更小的文件加载体积;
  2. 通过包的拆解来得到更优的加载策略,从而降低load time;
  3. 比较轻量的source mapping(当然,当你需要一些trace信息做日志和报警的时候是另外一番情景);


    推荐阅读