上一篇文章(juejin.cn/post/700202… )从打包结果分析了webpack核心执行流程,这篇文章详细说明laoder触发时机和执行过程,一次性解决loader所有困扰。
1. 为什么要配置loader
因为webpack只认识js和json,对于非js和json的文件类型需要loader转换为标准的js模块
,才能被webpack打包处理。
2. loader本质是什么
loader本质上就是导出为函数的JavaScript模块
。例如一个最简单的loader:
module.exports = function(content, map,meta) {
return `export default "Convert by my custom loader: ${content}"`;
// 注:当需要返回多个参数时,不能直接return,需要按照如下方式返回
// 异步loader
// this.async(null, result, map, meta)
// 同步loader
// this.callback(null, result, map, meta)
// 只有一个参数可以直接return
}
Webpack会对loader注入三个参数:
content:资源文件的内容。// 必须
map:前面loader生成的source map // 可选
meta:其他需要传给后方loader共享的信息,可自定义 // 可选
明白了这个本质,对于自己开发一个loader就非常简单了。例如:新建一个loaders目录,创建my-loader.js文件,内容为导出的javascript模块,拿到content就可以随意处理了。
模块解析默认从当前node_modules查找,如何找到自己开发的loader?只需要配置下解析规则即可
// 手动配置 loader 路径,先从自定义的loaders目录查找,找不到再查找node_modules
resolveLoader: {
modules: [path.resolve(__dirname, 'loaders'), 'node_modules']
}
3. loader是什么时候触发的
上一篇(juejin.cn/post/700202… )我们了解了webpack整体打包流程,其中loader触发时机为标红的部分:
真正触发时机是调用module.build
,build对应源码文件 webpack/lib/NormalModule.js的build方法,build方法又调用了doBuild,doBuild方法执行了runLoaders,如下图:
其中runLoaders是一个单独的工具库(loader-runner),用来执行资源的加载和转换,具体如何执行的继续看第4个问题。
4. loader是如何执行的
了解loader执行流程前,需要知道loader函数包含pitch和normal两部分,其中pitch是非必须的,如果有pitch则会首先执行它,loader执行核心流程如下:
通过执行流程我们也知道了为什么loader按照从右向左的顺序执行,其实是因为loader执行是一个递归调用,判断当前为最后一个loader时才会处理资源。
iteratePitchingLoaders函数执行过程:
processResource函数执行过程
iterateNormalLoaders函数执行过程:
5. loader执行顺序是怎样的
在webpack配置文件中,我们经常看到两种场景:
场景1:同一个规则配置多条loader时是怎么样执行的?
执行优先级为:Pre loader > Inline loader > Normal loader > Post loader,可以通过enforce属性改变loader执行顺序。如果没有enforce则为相同优先级,按照配置顺序执行。
场景2:单条规则配置多个loader执行顺序?
配置中相同优先级会按照从右到左,从下到上的顺序执行,具体为什么是这个顺序通过问题4loader执行过程相信已经明白了。
总结:Loader实际的执行顺序与loader的类型
,pitch方法
,inline-loader的前缀
都有关系。
通过以上5个问题,相信对于loader的所有疑问基本都解决了,码字画图不易感谢点赞支持哟~