拟通过制作Plugin和Loader加深对Webpack的认知。
前言
我为什么写下这些东西
-
曾经看过一部印象深刻的电视剧,记得当时大结局被感动得一塌糊涂,也有还几部小说看得励志打鸡血的。我只记得有那么几个深受触动的瞬间,却总也找不回了。
也曾有学习巩固基础,感觉学完后目空一切尽在彀中的自信。没想到出道即巅峰,见识或许慢慢的是长了,但心态在随后的繁琐事中慢慢的也没了。
我想记录下自己此时的状态。或者说,我有这么一个期望,当我回顾此时的学习过程和心路历程,能够快速找回此时的状态。
-
这不是我第一遍学webpack了,以前学的时候也听别人讲了webpack的基本原理,讲了这个资源加载用哪几个loader,要做那个使用什么plugin,开发环境该怎么配置,生产环境又怎么怎么样。
但是没用。没过多久基本上全忘了。有人说这些配置只在项目初始化那会配置一次,而且流行的框架基本上都有脚手架,配置都是现成的,看看文档的事,忘也就忘了。
我也这样认为,而且一直这样认为,到现在也一样。
但是当我尝试自己新建一个工程,npm i -S -D一大片相关依赖,然后因为版本问题折腾了半天不成功时,我感到十分沮丧,以及前所未有的挫败感。
我知道这是因为版本升级,组件接口或者功能变化,组件之间协调出了问题造成的,但也仅此而已了。除了在网上搜索恰当的版本号,我对此无能为力。
我意识到我从来没有真正了解过Webpack。
我又想起另一件事情。
在我上学的时候是有《计算机网络》这门课程的,教材谢希仁那本,那本书挺好,我感觉当时也学得挺好的,至少绩点上还过得去。
作为一门网络课程,理所当然提到了HTTP协议。你跟我考试这部分,我肯定没问题;你要我说,我也能说个三四五六来。
但你要我基于套接字手撸一个简单的HTTP0.9服务器,我只能回你一个黑人问号脸。即使这之前因为项目原因我没少做UDP/TCP通信的case。
这就很尴尬了。
你以为你懂了,但其实并没有,至少不能学以致用。
不过真的致用以后,你又会发现其实也就那么一回事,先前只是脑子没开窍。
接下来HTTP1.1/HTTP2等更加复杂,也许你的coding能力并不足以较小的代价优雅地将它实现,但你应该有了底气。
举个不那么恰当的例子,虽然你不一定会做菜,但你仍旧可以点评厨师做的食物。当然前提是你品尝过它。
也正是因为这个经历,我想通过写plugin和loader的方法,从另一个角度重新认识webpack。
-
在写这些之前,其实plugin和loader都已经做好了,毕竟只要入了门其实很简单。现在把它写下来告诉别人我是怎么做怎么想的(假设会有人),应该能巩固所学吧。
-
我并不能对自己写的内容保证什么。人在面对未知时,视野总是狭隘的。也许经验丰富后高屋建瓴回看此时的东西会不那么成熟。
说实话,我现在看我半年前写的东西都会感叹那都是些什么啊。
总不能玩过几下云服务器/服务器就说自己会运维了,写过几个爬虫就说自己会js分析了,跑过几轮模型训练就说自己会机器学习了,用过几次frida就会说自己会Android逆向了,照着别人做了几个玩具就说自己有项目实战经验了。
我就自曝一下吧,以前学Java Web的时候,我一度以为生产环境和开发没啥两样,都是把Eclipse打开放在那里,然后跑起来…[捂脸]
在此我还是要狡辩几句,这是因为我从图书馆里借的那几本书没提打包war包以及Apache部署(或许提了,只是我跳过了),而且实习的时候也没接触到项目打包那一块。哈哈哈。
为此,我还专门想了一下,没了IDE我们应该怎么打包我们的java源代码。 嗨,入门的第一个hello world就是写个类,然后javac编译,然后java执行。 类多了以后,把它们都编译成.class,放个MANIFEST说明文件,把它们压缩一下,改个.jar后缀名,这不就出来了吗。。。
有时候我们自己都不知道自己无知得多离谱。。。
学习大前端的一些想法
-
我接触html/js/css算是比较早的,那时h5和css3才刚刚兴起,前端这一块远未成熟。 基本上还属于页面靠下载模板或者直接从其它网页里面抠,撸起袖子直接靠jQuery蛮干的野蛮生长的阶段。
现在查了一下,Bootstrap那时才刚出生😳。
当时重心没放在这块,主要在学jsp + java struts2,感觉前端js这东西真的简单,有手就行,我上我也行。
后来听说了js的新规范ES6,也没怎么关注,感觉反正能用就行。
再后来因为需要,主要玩工控机、Arm板或者单片机这些东西,有很长一段时间没有搞过Web这一块,前后端都没有,感觉生疏了不少。
一段时间过去,前端变化是真的大。
以前想要引个库,看别人的readMe基本上是给个script标签引入再加段js代码。 慢慢的这样的Repo越来越少了,清一色的npm + import开干,我尼玛,对非前端人员太不友好了,tmd。
这其实是前端逐渐工程化的一个过程,渐渐不再是手撸html再手撸js+css的事了,即使是新语法的<script type='module' src=...>
应对也十分吃力,我们写的源文件在慢慢变成浏览器看不懂的东西,需要经过一定的润色翻译。
但做出这样的牺牲是有原因的,像Vue、jsx、less这些不说。举一个html模板的例子,这种使用liquid语法实现html套娃,复用代码的方式,就是最早的一种尝试。
浏览器能读得懂html模板吗?
也许可以,但那肯定缺少数据,只是个空壳UI。当拆分的更加细致,连样子都会看不到了。举个例子,这篇博客所用的Jekyll,就是这样的实践。
或许你会说Jekyll用的是ruby,这不算数。但要我说,要是nodejs没有出生,没准这事还真让ruby给包了。当然也可能是其它语言,就看那位伟大的全栈工程师哪个用的最顺手了。 -
我一度很排斥js和python这两门语言,将它们放在程序语言的底端。排斥是因为它们上手实在是才容易了,然后到处攻城略地。
浏览器有js,桌面应用electron有js,后端node experss有js,移动端React Native有js,整个都包圆了,到处都有js就离谱。
还有python,我就没见过搞机器学习的不会python的。不得不说python的生态很完好,你能想到的日常功能基本上都实现了。他们把程序都写好了,只差你写几行代码调用了。 -
Python、JavaScript这类弱类型的语言,写起来非常爽,但是看起来非常费力,这是我的感觉。
不是它的实现者,对整个工程十分熟悉,在修改较底层代码时会非常吃力。
我知道我要传入或者返回一个东西,它的作用我也比较了解,但我不知道应该怎么去构造/修改它。 我不确认这个对象具体应该具有哪些属性,生怕多了少了或者错了。 我在要修改的地方上下溯源了几个函数,它们有的只是简单的传递参数,有的只是涉及到部分属性,但我看到的这部分属性就是需要修改的全部了吗?
我不确定。即使我的修改生效消除了一个bug,心里也没底,不知道是否埋下了不知名的隐患。
我不知道我的理解到不到位,但我相信TypeScript的诞生是有道理的。 -
但说了那么多,最后还是逃不过一句真香。。。
我对Webpack的一些理解
-
Webpack是用于将前端代码(.js/ts/jsx/vue/css/less/html…)打包生成浏览器(或其它终端)可用的前端资源的一个工具。
与Java开发做一个类比,它有点像maven,但又不是。
因为它缺少maven的包管理功能,这是由npm或yarn来完成的。
但某些方面又远比maven强大,因为它的编译打包机制使得它在开发测试的过程中占据重要地位。
可实际上又非常弱鸡,离开插件/加载器模块寸步难行。
扯这么多,实际上单独拿出来做对比没啥意义,就当大脑的热身运动。 -
Webpack,以及辅助实现webpack功能的plugin、loader的js,可以把它看作与python、ruby、java等语言类同,最好将它和浏览器里运行的js区分开来。
因为遵从浏览器规范的js是有局限的,本地文件的读写、不受限制的网络请求是它跨不去的坎。
所以,plugin、loader开发时使用的是node所遵循的规范CommonJS,而不是浏览器的ES6。
当然,开发时因为测试需要传入浏览器的那部分不算,把这个代入到其它语言的场景应该也很好理解。
反而是src里面的代码,因为我们要站在浏览器的角度去思考,所以常常写的是ES6。但实际上ES6或者CommonJS二者皆可,因为最终都是要经过node执行babel来翻译,CommonJS它肯定也是认识的。
我该如何获取帮助
- 一般而言,有四种情况:
- 中文社区
- 国外社区
- 官方文档(专指接下来的工作)
- 源码(专指接下来的工作)
- 对于前两种(尤其是第一种)情况下获得的信息,需要抱着审慎的态度。
因为它很可能过时了;或者并不适用于你的问题,因为会有很多不同的原因导致相同的异常抛出,当情况复杂时尤其如此。
正因如此,我从不在CSDN等地方写下自己的东西,只是在自己的小窝里做下笔记。-
因为我知道自己不能保证写下的东西的有效性。
一个东西做完了,过了一段时间还能使用吗?我不确定。
即使过了很久很久,久到它百分百过时了,我会专门去改动它、删除它吗?我不会。 -
因为我也不知道自己的视野是不是狭隘,导致我的想法偏于正途;野路子虽然能实现目标,但实际上也许有更优的解决方案。
-