本文深入解析Webpack中Loader与Plugin的核心区别。Loader专注于文件类型转换,如将CSS、Less转为JS模块;Plugin则通过钩子机制介入打包全流程,实现HTML生成、资源清理等自动化任务。文章详细对比了两者工作原理、执行顺序及开发方式,并列举了常用Loader与Plugin的配置示例,帮助开发者掌握Webpack构建系统的核心机制。
一、Loader
1. Loader的作用
Webpack原生仅支持JavaScript格式的代码。对于非JS文件,必须通过预处理将其转换为JS代码,才能纳入打包流程。Loader(加载器)正是承担这一转换任务的工具。
2. Loader的工作原理
Loader由Webpack的loader runner负责调用执行。它接收原始资源数据作为输入参数(当配置了多个Loader链式使用时,前一个Loader的输出将作为下一个Loader的输入),最终输出JavaScript代码(以及可选的Source Map)供Webpack进行后续编译处理。
3. Loader的执行顺序
1). Loader类型
Loader主要分为四种类型:pre(前置)、normal(普通)、inline(内联)和post(后置)。
2). 执行优先级
4类 loader 的执行优先级为:pre > normal > inline > post 。 相同优先级的 loader 执行顺序为:从右到左,从下到上。 3. 前缀的作用
3. 前缀的作用
内联Loader可以通过添加特定的前缀来跳过其他类型的Loader处理。具体规则如下:!用于跳过normal类型的Loader;-!用于跳过pre和normal类型的Loader;!!用于跳过pre、normal和post所有类型的Loader。这些前缀机制在复杂构建场景中非常实用。
4. 如何开发一个Loader
Loader本质上是一个导出为函数的Node.js模块。
1). 最简单的Loader示例
当只有一个Loader应用于资源文件时,它接收源码作为参数,并输出转换后的JS代码。
// loaders/simple-loader.js module.exports = function loader (source) { console.log('simple-loader is working'); return source; } 揭秘webpack loader - 知乎
以style-loader为例,其最终需返回一段js脚本:该脚本会在运行时动态创建一个style标签,将css代码赋值给该style标签,最后将这个style标签插入到html页面的head节点中。
二、Plugin
1. Plugin解决更多的自动化打包工作
Plugin的作用范围更广,功能也更为强大。
它能够实现多种自动化任务,例如:自动生成HTML文件并自动引入打包后的资源;在打包前自动清除dist目录中的旧内容;将未直接引入但需打包的静态资源一并处理;对打包结果进行特殊定制处理;压缩打包内容,或对打包结果执行更细粒度的自定义操作。
2. 自定义插件开发
1)在开发插件前,需理解其原理。与Loader仅作用于模块加载环节不同,Plugin可介入打包过程的每一个阶段,类似于Vue的生命周期机制。Webpack的插件机制基于钩子(Hooks)机制,整个打包过程被划分为多个环节,Webpack在每个环节提供了相应的钩子,开发者可利用这些钩子实现自定义功能。
2)Webpack提供了哪些Hooks?
常见的Hooks包括:entry-option(初始化选项)、run(开始编译)、compile(真正开始编译,在创建compilation对象之前)、compilation(生成compilation对象)、make(从entry开始递归分析依赖,准备对每个模块进行build)、after-compile(编译build过程结束)、emit(将内存中assets内容写入磁盘文件夹之前)、after-emit(写入磁盘之后)、done(完成所有编译过程)、failed(编译失败时)等。
3)Webpack要求插件必须是一个函数,或者是一个包含apply方法的对象。通常我们会定义一个类,并在该类中实现apply方法,最后通过实例化该类来使用插件。
const pluginName = 'myplugin'
module.exports = class myplugin {
apply(){}
}
这个apply方法接收一个名为compiler的参数对象,它是Webpack工作中最核心的对象,包含了此次构建的所有配置信息。通过该对象,我们可以注册所需的钩子函数。
const pluginName = 'myplugin'
module.exports = class myplugin {
apply(compiler){
compiler.hooks.run.tap(pluginName, () =>{
{
console.log('开始编译');
}
})
}
}
例如,若想在run阶段输出“开始编译”信息,需在webpack.config.js中引入并配置插件。
const myplugin = require('./myplugin')
plugins:[
new myplugin()
]
常见的Loader和Plugin
常用Loader列表
style-loader:在HTML文件中创建style标签,将JS中的样式插入页面。
css-loader:将CSS文件转换为CommonJS模块加载到JS中,输出为样式字符串。
less-loader:将Less语法转换为CSS。
url-loader配合内置file-loader:处理图片资源(注意:不能直接处理HTML中的图片)。
html-loader:处理HTML中的图片资源,负责引入img标签,使其能被url-loader进一步处理。
{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options:{
limit:5*1024,
esModule: false,
name:[hash:10].[ext] //给图片文件重命名,取哈希值前10位加上原来的扩展名
}
},
type:'javascript/auto' //在webpack4的基础上加上这句话
},
{
test: /\.(htm|html)$/,
loader: 'html-loader',
}
file-loader:打包其他资源,如字体图标,通常不需要进行优化压缩。
注意:在Webpack 5之后,我们可以直接使用资源模块类型(asset module type)来替代上述部分Loader。
常用Plugin列表
html-webpack-plugin:在构建过程中新建index.html文件,并自动引入打包输出的所有资源(JS/CSS)。可配置template参数以新HTML文件作为模板。
ignore-plugin:用于忽略特定文件的打包。
mini-css-extract-plugin:将CSS单独打包为一个独立的CSS文件。
clean-webpack-plugin:用于清除目录文件。在生产环境编译时,可先清空dist目录再生成新文件。
serviceworker-webpack-plugin:提供离线缓存功能。
webpack-parallel-uglify-plugin:通过多线程压缩JS代码,以加快构建速度。
以上即为Webpack中Loader与Plugin区别的详细解析,更多关于Webpack中Loader与Plugin区别的资料,请关注本站其他相关文章!