loader是什么?
loader用来对模块中的代码进行转换,在import或加载模块时预处理文件,
将webpack中不能识别的类型文件识别成webpack可识别的文件
webpack做的仅仅只是分析模块间的依赖关系,形成资源列表,最终打包至指定输出位置中。
默认情况下,webpack只支持对js和json文件打包,对于其他如同css、png、svg等类型文件时,webpack是不识别的,这时就需要通过loader来对文件内容进行解析
加载模块的执行顺序如图:
当webpack遇到不识别的模块时,webpack会在配置中查找对应文件的解析规则
loader分类
pre loader前置 normal loader普通 inline loader内联 post loader后置
执行顺序 ——————————————————————————》
相同优先级 《——————————————————————————
loader配置方式
- 配置文件方式:在webpack.config.js文件中指定loader
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true
}
},
{ loader: 'sass-loader' }
]
}
]
}
};
- 内联方式:在import语句中显示指定loader
用法:import style from 'style-loader!css-loader?modules'
!用于分割loader
inline loader 还可以通过添加不同前缀,跳过其他loader
1. !: 跳过normal loader
2. -!: 跳过pre和normal loader
3. !!: 跳过pre、normal、post loader
- CLI方式:在Shell命令中指定他们
因为loader支持链式调用,链中的loader会处理上次处理过的资源,最终转换为js代码,执行顺序为从下往上(从右往左),上述执行顺序依次为sass、css、style
常用loader
- style-loader: 将css添加到DOM的内联样式标签style里
- css-loader :允许将css文件通过require的方式引入,并返回css代码
- less-loader: 处理less
- sass-loader: 处理sass
- postcss-loader: 用postcss来处理CSS
- file-loader: 分发文件到output目录并返回相对路径
- url-loader: 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url
- html-minify-loader: 压缩HTML
- babel-loader :用babel来转换ES6文件到ES
自定义loader
webpack调用对应类型的loader解析资源,在加载loader配置时,调用loader属性中提供的loader函数,并将处理文件作为参数传到loader函数中,进行处理并返回出去
loader接收参数
content:被处理后的文件内容
map:sourceMap
mate:别的loader传递的数据
loader不同方式
- 同步loader
//方式一
//当前资源只需一个loader处理,推荐使用这种方式
module.exports = function (content, sourceMap, meta) {
console.log("content:",content);
return content;
}
//方式二
//处理的资源需要使用多个loader时推荐使用
module.exports = function (content, sourceMap, meta) {
// console.log(content);
// 第一个参数为是否有错误
this.callback(null,content,sourceMap,meta)
}
loader使用:
// webpack.config.js
const path = require('path');
module.exports = {
entry: {...},
output: {...},
module: {
rules: [
{
test: /\.txt$/,
loader: require.resolve('./loader/sync-loader.js')
}
]
}
}
打印txt文件内容:
- 异步loder:
module.exports = function (content, sourceMap, mate) {
const callback = this.async(); // 告诉loader将会异步地回调
setTimeout(()=>{
console.log("test2");
callback(null, content, sourceMap, mate);
},1000)
}
编译时期,webpack会在执行该loader1秒之后输出test2
- raw loader :接收的content数据是Buffer数据
raw loader主要用来处理图片、字体等资源,需要将loader上的raw属性设置为true,使loadaer支持二进制格式。
module.exports = function(source) {
// 将输出 buffer 类型的二进制数据
console.log(source);
// todo handle source
let result = 'results of processing source'
return `
module.exports = '${result}'
`;
}
// 告诉 wepack 这个 loader 需要接收的是二进制格式的数据
module.exports.raw = true;
- pitch loader:pitch loader执行顺序
如配置loader链:
use: ['loader1', 'loader2', 'loader3']
pitch loader的执行分为两个阶段,‘pitch阶段’和‘normal阶段’,webpack会先从左到右执行pitch链中的loader ,然后从右到左执行normal链中的loader
在任一个pitch loader中return,会导致loader链被中断,webpack会跳过后续loader的执行,进入上个loader中的normal阶段往下执行。
loader使用:
module.exports = function (content) {
console.log('normal 阶段1:');
return content;
}
// loader上的pitch方法,非必须
module.exports.pitch = function() {
console.log('pitching 阶段1');
}
module.exports = function (content) {
console.log('normal 阶段2:');
return content;
}
// loader上的pitch方法,非必须
module.exports.pitch = function() {
console.log('pitching 阶段2');
}
{
test: [/\.txt$/],
// 直接指明 loader 的绝对路径
use: [
require.resolve('./loader/pitch-loader1.js'),
require.resolve('./loader/pitch-loader2.js')
]
},