Web开发

首页 » 常识 » 诊断 » 模块化之前端打包工具webpack
TUhjnbcbe - 2021/8/28 12:05:00
山东白癜风医院 http://baidianfeng.39.net/a_yufang/131228/4318885.html
谈谈你对webpack的看法

webpack是一个模块打包工具,可以使用webpack管理模块依赖,并编译输出模块们所需的静态文件。它能很好地管理、打包web开发中所用到的html、css、js以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack有对应的模块加载器。webpack模块打包器会分析模块间的依赖关系,最后生成了优化且合并后的静态资源。

特点

对CommonJS、AMD、ES6的语法做了兼容处理

对js、css、图片等资源文件都支持打包

串联模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如对ES6的支持

可以将代码切割成不同的chunk,实现按需加载,降低了初始化的时间

支持sourcemap,易于调试

具有强大的plugin接口,大多是内部插件,使用起来比较灵活

webpack有什么优劣势

grunt和gulp是基于任务和流(Task、Stream)的,找到一个(或一类)文件,对其做一些链式操作,更新流上的数据,整条链式操作构成一个任务,多个任务就构成整个web构建流程。

rollup和webpack类似,但更专注于ES6的模块打包。它最大亮点是利用ES6模块设计,生成更简洁、更简单的代码。

webpack是模块化管理工具和打包工具,它是基于入口。webpack会自动递归解析入口所需要加载的所有资源文件,然后用不同的loader来处理不同的文件,用Plugin来扩展webpack功能。

虽然目前主流方向是webpack,但是一些轻量化的任务还是会用gulp来处理,比如单独打包CSS文件;另外一些库也会使用rollup打包。

loader和plugin的区别从功能上说

loader用于加载待打包的资源,Plugin用于扩展webpack功能。

loader本质上就是一个函数,在该函数中对接收到的内容进行转换,返回转换后的结果,主要用于加载某些资源文件。因为webpack只会加载js和json,这就需要对应的loader将资源转化,加载进来。

plugin用于扩展webpack的功能(loader其实也是扩展功能,但是只专注于转化文件这一领域),在webpack运行的生命周期中会广播许多生命周期钩子事件,plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结果。

从运行时机角度区分

loader运行在打包文件之前(loader为模块加载时的预处理文件)

plugin在整个编译周期都起作用

从使用角度区分

loader在rules中配置,类型为数组,每一项都是一个Object,内部包含了test(类型文件)、loader、options(参数)等属性

plugin在plugins中单独配置,类型为数组,每一项是一个Plugin的实例,参数都通过构造函数传入

webpack构建过程

webpack的运行流程是一个串行的过程

初始化参数

从配置文件和Shell语句中读取与合并参数,得出最终的参数

开始编译

用上一部得到的参数初始化Compiler对象,加载所有配置的插件,执行对象的run方法开始执行编译

确定入口

根据配置中的entry找出所有文件的入口

编译模块

从入口文件出发,调用所有配置的loader对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过本步骤处理

完成模块编译

再经过第4步使用loader翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系

输出资源

根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk,再把每个chunk转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会

输出完成

在确定输出内容后,根据配置确定输出的路径和文件名,把文件内容写入文件系统

其他

以上过程中,webpack会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用webpack提供API改变webpack的运行结果

简单来说:

初始化:启动构建,读取与合并配置参数,加载plugin,实例化Compiler

编译:从entry出发,针对每个Module串行调用对应的loader去翻译文件的内容,在找到该module依赖的module,递归的进行编译处理

输出:将编译后的module组合成chunk,将chunk转换成文件,输出到文件系统中

webpack如何解析代码路径

webpack依赖enhanced-resolve来解析代码模块路径,这个模块像Node.js那一套模块路径解析的增强版,有很多可以自定义的解析配置。

模块解析规则分三种:

解析相对路径

查找想对当前模块的路径下是否有对应的文件或文件夹,是文件则直接加载

如果是文件夹则找到对应文件夹下是否有package.json文件

有的话就按照文件中的main字段的文件名来查找文件

没有package.json或main字段,则查找index.js文件

解析绝对路径:直接查找对应路径文件,不建议使用,因为不同的机器会用绝对路径查找不到

解析模块名:查找当前文件目录,父级直至根目录下的node_modules文件夹,看是否有对应名称的模块

通过配置resolve.alias、resolve.extensions、resolve.modules等字段优化路径查找速度

sourcemap的作用和原理

sourcemap是将编译、打包、压缩之后的代码映射回源码的过程。打包压缩后,代码不具备良好的可读性,想要调试源码就需要sourcemap,出错的时候控制台会直接显示原始代码出错的位置。

map文件只要不打开开发者工具,浏览器是不会加载的。

模块打包原理

webpack根据webpack.config.js中的入口文件,在入口文件里识别模块依赖,不管这里的模块依赖是用CommonJS写的,还是ES6Module规范写的,webpack会自动进行分析,并通过转换、编译代码,打包成最终文件。最终文件中的模块实现是基于webpack自己实现的webpack_require(es5代码),所以打包后的文件可以跑在浏览器上。

同时意味着在webpack环境中,你可以使用es6语法,也可以使用

1
查看完整版本: 模块化之前端打包工具webpack