简介
loader作用:将源代码转换成javascript格式的目标代码
webpack.config.js配置示例
rules: [
{
test: /\.css$/,
use: [
{
loader: 'css-loader',
options: {}
},
path.resolve(__dirname, 'myloader')
]
},
],
loader介绍
loader分类:
// (1) 内联形式
import util from 'raw-loader!../utils.js'
// (2) webpack config 配置形式: test相同的数组并列形式
{
test : /\.css$/,
loader: 'style-loader',
// pre, normal(默认)
enforce: 'post'
}
执行优先级
- 不同级:pre > normal > inline > post
- 同级: 从右到左,从下到上
内联方式(前缀)
- 使用
!前缀,将禁用所有已配置的 normal loader(普通 loader) - 使用
!!前缀,将禁用所有已配置的 loader(preLoader, loader, postLoader) - 使用
-!前缀,将禁用所有已配置的 preLoader 和 loader,但是不禁用 postLoaders
执行顺序
划分为pitch(需定义),execution两个阶段;
若任一loader在pitch阶段有返回值,则loader阻断,直接进入上一个Loade的execution阶段
自定义loader
my-style-loader
const loaderUtils = require('loader-utils')
function loader(source) {
// 测试
let style = `
let style = document.createElement('style')
style.innerHTML = ${JSON.stringify(source)}
document.head.appendChild(style)
`
return style
}
// remainingRequest:loader链中排在自己后面的 loader 以及资源文件的绝对路径以`!`作为连接符组成的字符串。
// precedingRequest:loader链中排在自己前面的 loader 的绝对路径以`!`作为连接符组成的字符串。
// data:每个 loader 中存放在上下文中的固定字段,可用于 pitch 给 loader 传递数据
loader.pitch = function(remainingRequest,precedingRequest,data) { // 剩余的读取绝对路径
// 自定义条件
let str = `
let style = document.createElement('style')
style.innerHTML = ${loaderUtils.stringifyRequest(this, '!!' + remainingRequest)}
document.head.appendChild(style)
`
return str
}
module.exports = loader
my-url-loader
const loaderUtils = require('loader-utils')
const mime = require('mine')
function loader(source) {
let { limit } = loaderUtils.getOptions(this)
if (limit && limit > source.length) {
return `module.exports="data:${mime.getType(this.resoucePath)};base64,${source.toString('base64')}"`
} else {
return require('./file-loader').call(this, source)
}
}
// source为二进制输入
loader.raw = true
module.exports = loader
常用API:
// https://www.webpackjs.com/api/loaders/#%E7%A4%BA%E4%BE%8B
this.emitFile(name, content, sourceMap) // 写file
this.cacheable(false) // 不缓存
// 同步: 直接执行同步fn 或 this.callback(null, fn(content), map, meta) 生成
// 异步:
let cb = this.async()
cb(null, res, map, meta)
工具库
const loaderUtils = require('loader-utils')
let option = loaderUtils.getOptions(this)
// loaderUtils.stringifyRequest() // 将绝对路径转换为相对路径
// schema校验
const validateOptions = require('schema-utils')
const schema = {
type: 'object',
properties: {
text: {
type: 'string'
},
filename: {
type: 'string'
}
}
}
validateOptions(schema, option)
参考:
loader API
## 揭秘webpack loader : 图片引用