loader处理器
主要用处理源码的编译工作,将代码进行根据自己的要求进行编译
因为webpack本身只支持js的编译工作, 无法进行css、png的编译。
所以我们可以用loader进行个性化的编译工作
将entry的入口文件,进行test匹配
module.exports = {
module:{
rules:[
{
test:/\.css$/,
use:[
// 用来讲css插入dom中
{ loader: 'style-loader'},
// css进行编译
{ loader:'css-loader',
// 配置项
options:{
}
},
// 将sass编译成css
{
loader:"sass-loader"
}
]
}
]
}
}
Vue-Cli
// chain-webpack
module.exports =(config)=>{
config.module.rule('customloader').
use('../../tocss.js')
.loader('../../tocss.js')
.end();
}
特性
- 可以同步,也可以异步
- webpack是在node中运行,可以随时debug
- pulgin可以为loader带来更多收益
- loader会产生额外文件
常用loader
style-loader: 可以将css添加到内联样式中去
css-loader: 允许将css文件require的方式引入,并返回css代码
less-loader:将less代码处理
sass-loader: 将sass代码处理
postcss-loader: 将css用postcss处理
autoprefixer-loader:处理css3属性前缀
flie-loader: 分发文件到out目录并返回对应路径
url-loader: 和file相似,当文件小于设定的limit的时候,返回data-url
html-minify-loader: 压缩html
bable-loader:通过babel来处理代码
loader执行顺序
由下往下,由右往左
Url-loader
一般匹配图片,将设置一个阙值,低于阙值转为b64,高于阙值则依旧是url链接打出
rules:[
{
test:/.(png|jpe?g|gif)$/,
use:[
{loader:'url-loader',
limit:100,
// 命名: 文件名+hash值+后缀
name:"[name]_[hash].[ext]",
// 打包后save的位置
outputPath:'./image',
//打包后文件的url
publickPath:'./image'
}
]
}
]
Plugin
如果说loader是个处理器,那么Plogin,就是使用loader的人
可以将入口entry ,加入loader处理,然后output输出
Pulgin和Loader的区别
- loader是文件处理,可以简单通过函数逻辑处理代码的转换器
- pulgin是mini完整处理周期,在webpack整个生态都是可以用的,我们利用pulgin在周期内广播传输事件,进行处理修改webpack的api
手写loader
loader本质是函数,他的上下文是webpack中的,所以不能为一个箭头函数
// 执行上下文是webpack中的一个函数
export.module = function(source){
// 处理完成后的代码
const content = ToDo(source);
// 获取loader的配置参数
// async异步返回
this.callback(null, content)
// 同步返回
return content
}
手写Plugin
Webpack采用是的发布订阅模式,在运行的生命周期,会触发多个钩子事件,我们可以利用Plugin去监听钩子时间,在特定的阶段是完成特定的事情
webpack的编译阶段有2个核心对象
Compiler: 包含了webpack运行过程所有的配置信息,包含options,loader和pluginCompilation:包作为plugin内置事件回调函数的参数,包含了当前模块的资源、编译生成的资源、变换的文件,以及状态信息,简单一个文件变换,一次新的compilation将会被创建
规则
- 插件必须要是一个函数或者是一个含有apply的对象,便于可以基于webpack下,
- 传给每个插件的comiler和comilation对象都是同一个引用,引用为webpack,不要修改
- 异步事件完成需要在插件处理完调用毁掉参数同时webpack开启下个,否则会被挂起
总结:
必须要有可以apply的函数
不要去修改compiler和compilation属性
异步事件必须要一个成功回调~
module.exports = class {
constructor(a) {
this.plugin = a;
}
// 必须含有apply 否则无法进行
apply(comilper, comilper2) {
comilper.hooks.emit.tap('littlePlugin', function (e) {
// e 为compilation
// 每次完成时候,都去触发这个函数
console.log(e);
});
return;
}
};