lodader 基础
loader 分为inline,pre,normal,post loader
- inline 内联laoder写法 import 'style-loader!css-loader!./style.css',用!号分割
内联loader在前面加前缀,表示禁止webpack.config.js配置的loader执行
加 ! 表示禁止normal loader执行 import '!style-loader!css-loader!./style.css'
加 -! 表示禁止 pre 和 normal loader 执行 import '-!style-loader!css-loader!./style.css'
加 !! 表示禁止 pre 和 normal、post loader 执行 import '!!style-loader!css-loader!./style.css'
- loader执行顺序 inline > pre > normal > post,从右到左,从下到上
对js文件匹配到后,都会执行下面loader,不是只执行一个
下面执行顺序是 B -> babel-loader -> D -> A
{
module:{
rules:[
{
test: /\.js$/,
use: ['D-loader']
},
{
test: /\.js$/,
use: ['babel-loader']
},
{
test: /\.js$/,
enforce: 'post',
use: ['A-loader']
},
{
test: /\.js$/,
enforce: 'pre',
use: ['B-loader']
}
]
}
}
loader 是一个函数,参数code,map,meta
-
code 是上一个loader返回字符串
-
map是sourcemap
-
meta是上一个传递下来的参数
module.exports = function(code,map,meta){
return code
}
同步this.callback和异步this.async()
-
this.callback 是同步,或者直接return
-
this.async 返回函数是异步
// 同步
module.exports = function(code,map,meta){
this.callback(null,code,map,meta)
}
// 异步
module.exports = function(code,map,meta){
const callback = this.async()
setTime(()=>{
callback(null,code,map,meta)
},2000)
}
静态属性 raw 表示获取buffer数据
// raw 设置了,那code是buffer格式
module.exports = function MyLoader(code,map,meta){
this.callback(null,code,map,meta)
}
MyLoader.raw = true
pitch loader 从左往右执行,返回数据后熔断后续loader
vue-loader 和 style-loader 原理就是用到 pitch vue-loader原理基本实现
function MyLoader(code,map,meta){
this.callback(null,code,map,meta)
}
MyLoader.pitch = function(){
}
module.exports = MyLoader
常用api
-
this.async 异步调用回调 用法 const callback = this.async()
-
this.callback 同步调研回调 用法 this.callback(error,content,sourceMap?,meta?)
-
this.getOptions(schema) 获取loader的options 用法 this.getOptions(schema)
-
this.emitFile 产生一个文件 用法 this.emitFile(name,content,sourceMap)
-
this.utils.contentify 返回一个相对路径 用法 this.utils.contentify(context, request),别用path
-
this.utils.absolutify 返回一个绝对路径 用法 this.utils.absolutify(context, request),别用path
小技巧:
loader返回字符串用JSON.stringify包装转移为标准字符串
module.exports = function(code){
return `module.exports = ${JSON.stringify(code)}`
}
loader 笔记
-
mark md文件转html
-
html-loader html内容转js
style-loader 例子
/**
1、直接使用style-loader,只能处理样式,不能处理样式中引入的其他资源
use: ['./loaders/styleLoader.js']
2、借助
*/
// const schema = {
// type: "object",
// properties: {
// presets: {
// type: "array",
// },
// },
// addtionProperties: true,
// };
function styleLoader(content) {
// const options = this.getOptions(schema);
return content;
}
styleLoader.pitch = function (remainRequest) {
// remainRequest c:/work/css-loader/dist/cjs.js!c/work/css/index.css
const loaderContext = this;
// 1、将绝对路径改为相对路径,因为后面只能使用相对路径
const relativePath = remainRequest
.split("!")
.map((absolutePath) => {
// 返回相对路径
return loaderContext.utils.contextify(
loaderContext.context,
absolutePath
);
})
.join("!");
// 2、引入css-loader处理后的资源,创建style标签插入样式生效
// 使用 !! 终止配置中css-loader执行
const script = `
import style from '!!${relativePath}';
const styleEl = documeng.createElement('style');
styleEl.innerHTML = style;
document.body.appendChild(styleEl)
`;
return script;
};
module.exports = styleLoader;