webpack真香
前言
在目前前端快速发展的情况下,以前就是简单地会去使用别人的脚手架来搭建项目,然后在项目中进行业务的开发,但是慢慢地,随着业务的正常发展,会发现
原本的脚手架好像已经不能够满足当前的业务,需要在目前项目上进行一个优化工作,但是基本上大部分都是不清楚脚手架里面都有什么配置,也不知道项目中
的配置都用来干嘛,都有什么用途,那么怎能够去站在这个脚手架的上面,来理解并优化项目的架构呢?如果连基本的关于webpack知识点都不清楚,不能弄懂其中的原理,又怎能去满足日益曾长的业务发展,来打造适合项目业务的完美方案呢?
本文以黄金圈规则来简单阐述,用以告诫自己也顺便提醒自己学习webpack的一个初衷!!!
🤔什么是webpack
webpack
是一个现在静态模块打包工具,针对js应用程序(任何使用js来编写的项目,比如react、vue、react-native、普通js、electron等等),
当webpack处理应用程序时,它会在内部从一个或者多个入口点开始,将入口文件所引用到的资源依赖”变成”一棵依赖树,树的根就时入口文件,从根出发,
所依赖的每一个模块就当作时树上的”枝叶”,将这些模块组合成为一个或者多个bundles,而webpack原本只有支持js+json打包的,但是项目中一般都会
使用到其他的资源(比如图片、css等等),这个时候,则需要借助于loader
了,loader对象定义在配置文件的module
属性中,以rule作为关键词的一个
数组,其目的时告诉webpack在遇到符合类型的文件的时候,将采用loader定义的加载器来加载对应的文件,然后再使用公共的require/import
的方式来加载
到对应的依赖,而其中所提供的所提供的plugin
插件,就是用来辅助打包,并控制打包过程、打包结果的对象。
根据官网文档对应编写了1⃣️简单的webpack入门项目(如下所示):
针对上述例子,执行对应的命令:
webpack
则会自动寻找对应的webpack.config.js
文件进行解析
🤔为什么要学习webpack
如果我们平时正常使用传统方式来开发web应用程序的话,随着项目越来越大,单纯通过手动部署,覆盖文件进行部署的方式的话,估计想死的❤️都🈶️了,而且也无法享受到
模块编程,针对任何资源的模块编程、一键盘部署、对项目的架构进行高度定制化的服务,一旦我们使用了webpack
,我们便可以更好的来管理自己的项目,将那些繁琐的、
又臭又长的逻辑操作,都交给webpack来做,将工作的中心放到业务的实现与跟进上来。
只有从根本上理解了webpack
的工作原理,甚至于,我们还可以开发自定义的Loader
或者Plugin
,来满足项目业务需求!!!
- commonJS引入了
require
机制,它允许我们在当前文件中加载和使用某个模块,导入需要的每个模块,帮助我们解决了作用域问题。- npm + node.js + modules = 大规模分发模块
🤔如何来学习webpack
✨ 既然webpack是一个工具,那么对应的学习方式肯定是线上工具/文档的学习,通过对其工作原理、代码分析,从使用到源码解读,了解关于webpack中所涉及的相关概念、
API、Loader、Plugin的配合,来深入学习如何使用webpack来打包自己的项目,一步步地优化项目的打包工作,提供工作开发效率!!!
相关的概念:
模块(Modules)
在模块化编程中,开发者将程序分解为功能离散的
chunk
,并称之为模块。
每个模块都拥有小于完整程序的体积,使得验证、调试以及测试变得轻而易举,精心编写的模块提供了可靠的抽象和封装界限
🤔 关于chunk的理解,可以这样子简单地来理解:项目中使用的每个文件都是一个chunk,通过chunk的互相引用,这些chunk会形成一个图数据结构,
而在打包的过程中,chunk会被合并成为chunk组,并形成一个通过模块互相链接的图。比如有以下一个配置文件:
1 | // webpack.config.js |
针对👆的配置文件,通过webpack
工具打包出来的chunk应该是怎样的呢?
👉 此时会创建一个名为main
的chunk组(因为main是入口起点的默认名称),此chunk组包含./index.js
模块,然后随着webpack的parser解析器在处理./index.js
内部的import时,
新的chunk模块就会被添加到这个chunk组中
这里也同时说明了一个情况:如果在使用之前没有做任何的额外的动作的话,一个chunk组中可能有多个chunk,这个时候我们可以使用
SplitChunksPlugin
插件来将一个chunk拆分为一个或者多个chunk
✨ 通过对上述中chunk组的理解,应该可以是在日常的编程中,如果想要优化打包出来的js过大的其中一个小点,可以考虑将入口所形成的chunk/chunk组所形成的bundle图给进行缩减,将资源调整为按需加载,
或者是动态加载,也就是在还未使用到的时候,不采用静态导入加载的方式,才是采用在需要的时候才来导入调用,在不影响到交互以及业务的情况下!!!!
🌟 chunk有两种形式:
- initial(初始化):也就是上述的入口起点的main chunk,此chunk包含为入口起点指定的所有模块以及其依赖模块
- non-initial(延迟加载的chunk):延迟加载的chunk,比如动态导入或者是拆分模块导入
比如有👇的一个简单例子,例子中的依赖关系如下:
index.js -> foo.js -> xx.css
-> bar.js
这里对于foo.js以及bar.js的引用机制不一样的,foo.js采用的静态依赖,而bar.js采用的动态依赖,因此生成的chunk.js中,index.js + foo.js + xx.css = main-chunk所在的组中,而bar.js属于单独的一个chunk组
manifest与runtime
在使用
webpack
构建的典型应用程序或者站点中,有三种主要的代码类型:
- 团队所编写的源码;
- 依赖的第三方的库或者vendor代码
- webpack的runtime和manifest,管理所有模块的交互
runtime(chunk加载逻辑以及解析逻辑代码)
runtime以及伴随的manifest数据,主要指的是在浏览器运行过程中,webpack用来连接模块化应用程序所需的所有代码(chunk),包含有以下几个逻辑动作:
- 在模块交互时,连接模块所需的加载和解析逻辑;
- 已经加载到浏览器中的连接模块逻辑
- 尚未加载模块的待延迟加载逻辑
manifest(保留的所有chunk的标识符)
一旦通过浏览器打开*.html的时候,它会自动去加载bundle以及其他的通过依赖来关联的chunk,这些chunk是已经通过打包、压缩、延迟加载等操作的细小的chunk,与源代码中的文件结构已经
完全没有半毛钱关系了,manifest就是管理打包后的chunk与打包前的源代码模块之间的一个关联关系
🤔课题预留:如何根据学习的webpack来优化自己目前的项目
- 从0⃣️开始搭建自己的vue项目基础框架
- 从0⃣️开始搭建自己的ejs + webpack静态生成页面基础框架
- 从0⃣️开始搭建生成静态html页面基础框架