webpack在资源打包方面是近年来非常流行的自动化构建工具,其强大社区生态,基本上能满足日常开发常规打包的需求,作为前端开发者对它常规使用应该是熟悉的,但是webpack内部是怎样实现?是本次我们的主题。最后我们也将实现一个简单的仿webpack的小工具,希望对您了解webpack有一定的帮助。
为什么前端需要模块化及问题?
随着前端业务的越来越复杂,许多复杂的场景,需要借助很多开源库来完成,不同资源组合使用之后,就会出现代码冲突,依赖难管理,功能块重复等问题,前端模块化主要解决这类问题。由于历史原因前端相关技术及相关理论,对同类问题有不同的处理方式,其中就包括了模块化的规范。目前最流行的有CommonJS,AMD,CMD,ES6等模块化规范,各类模块化规范在使用场景,运行时都有差异。例如CommonJS适用于服务端编程(Node),AMD与CMD虽适用浏览器,但二者在规范细节也有不小的差异。例如 AMD推崇依赖前置,CMD推崇依赖就近,虽然功能无差别,思想上有出入,反应到了写法细节上。最后ES6模块功能在语言的标准上实现,目前来看完全可以取代Commonjs与AMD/CMD规范,成为通用的模块化解决方案,其主要特点静态化,其特点可以做一些代码分析。如此多的模块化资源,往往还要组合使用,所以需要对此做进一步资源打包处理。
为什么需要模块打包?
往往项目中含有JS,CSS,HTML,模板,字体,图片等各类资源需要处理(优化,组合,按需..),最开始是手动管理包括图片的压缩,样式压缩,模板处理,随着数量增加,手动解决已难以维持,为此产生Grunt,Gulp等工具,来自动化构建,后又出现了集成化打包工具Webpack,Parcel,Rollup等如其目的主要提升开发体验,提高开发效率,资源组织,编译,优化,发布等各类问题,前端正朝着“工程化”的方向发展。
为什么选择Webpack来作为模块打包工具?
近些年最流行莫过于Webpack,它最核心的能力就是解决模块间的依赖问题,相比其他构建打包工具有如下优势:
-
Webpack支持多种模块标准,包括CommonJS,AMD,CMD,ES6等,尤其对一个复杂项目中依赖多种模块规范的库,
-
除了JS,webpack还可以把CSS,HTML,模板,字体,图片等各类资源打包成模块建立清晰的依赖关系
-
提供了许多优化资源方案例如code splitting,tree shaking,提取,压缩,souce Map...以及强大的社区生态
为什么Webpack这么强悍?
Webpack除了内置功能外,社区提供了非常多的"库"扩展了webpack的能力,Webpack有一套自己的生命周期,你也可以理解为打包一个资源的处理管道。生命周期中每个特定钩子(或者当事件理解-但钩子与事件有一定区别)都会对外开放都让外部可订阅如: 初始化阶段 run , 编译阶段 make build-module ,输出阶段 emit done 等。
钩子(插件)机制是怎么实现的?
Tapable.js简介:
更多请移步官网 https://github.com/webpack/tapable
tapable 对外暴露了很多钩子类,这些钩子类主要为插件创建钩子
SyncHook,
SyncBailHook,
SyncWaterfallHook,
SyncLoopHook,
AsyncParallelHook,
AsyncParallelBailHook,
AsyncSeriesHook,
AsyncSeriesBailHook,
AsyncSeriesWaterfallHook
如何使用?
钩子类创建钩子
const hookTest = new SyncHook(["arg1", "arg2", "arg3"]);
注册钩子
tapPromise // AsyncxxxHook
tapAsync // Asy