持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
引言
webpack千奇百怪的loader,如果你还不懂loader的作用或loader的流程,就适合自己手动编写一个loader,这能让你快速了解loader的运行机制以及加深你对它的理解。在面试中如果面试官提到webpack loader,我想你就能镇定自若,得心应手。
本文手动写一个loader,让每一位前端开发者也能自己编写loader,需要有一定的webpack基础
loader 简介
一句话:loader是负责资源文件从输入到输出的转换
因此也可以说loader是webpack 核心
开始
手写一个markdown文件加载器为例:markdown-loader
功能:实现可以在代码中导入markdown文件,读取生成html展示到页面
第一步
搭建webpack基础结构,搭建流程省略,不会的可以私聊我写文章
src下放一个index.js项目入口,里面引入md文件
// index.js
import md from './readme.md'
document.write(md)
src下放一个已经写好的md文件
// readme.md
## 岭南蜀香
### 想吃攀枝花大芒果的联系我!便宜包邮!
**贵妃,金煌上市咯**
再编辑webpack.config.js文件,基本结构:
const path = require('path')
module.exports = {
mode: 'none', // 打包模式
entry: './src/index.js', // 入口
output: { // 输出
filename: 'bundle.js', // 输出文件名
path: path.join(__dirname,'dist'), // 输出目录
}
}
现在,如果直接执行webpack打包命令(yarn webpack
),后报一个错误:
告诉我们需要有一个loader来处理该类型的文件
第二步
目标:新建loader文件,读取md文件,生成html字符串
在第一层目录下新建一个markdown-loader.js文件,每个webpack loader都需要导出一个函数,该函数就是对该资源的一个处理过程,
// markdown-loader.js
module.exports = source => {
console.log(source)
return 'begin!'
}
参数source为输入,首先打印出输入,并返回一个字符串
然后在webpack配置文件中配置上自己的loader
// webpack.config.js
module: {
rules: [
{
test: /.md$/,
use: './markdown-loader.js'
// use写入loader的相对路径
// use不仅可以写入名称,也可以写入路径,和node的require模式是 一样的
}
]
}
现在执行yarn webpack
,后也会报一个错:
告诉我们需要一个额外的加载器来加载我们的处理结果
这是为什么呢?
因为loader的加载过程相当于一个管道
source => loader1 => laoder2 => result
也要求结果result必须是一个js代码,我们返回的字符串'begin!'不符合js语法,所以会报错,告诉我们要么返回js代码,要么继续加loader来继续处理结果
result为什么必须是一个js代码?
我们将返回结果改过:return "console.log('begin!')"
然后执行打包,我们会看到打包结果bundle.js为:
发现打包后的字符串直接拼接到js中了,所以必须得符合js的语法规则,否则就会报错
第三步
安装一个md解析器:marded
然后将解析结果以js规则的结果导出即可
// markdown-loader.js
const marked = require('marked')
module.exports = source => {
const html = marked(source)
return `module.exports = ${JSON.stringify(html)}`
}
此处该loader就算完成!
额外也可以使用多层loader处理方式(方式2):
// markdown-loader.js
const marked = require('marked')
module.exports = source => {
const html = marked(source)
return html // 直接返回html 字符串交给下一个loader处理
}
// webpack.config.js
rules: [
{
test: /.md$/,
use: [
'html-loader',
'./markdown-loader.js'
]
}
]
同样也能达到正确的结果
最终展示的网页:
最后写完可以将markdown-loader发布到npm上作为一个独立的模块使用
总结
我们在手写一个loader的同时,也讲解了webpack loader的运行原理
虽然写一个loader不难,但正真实践手写后,你才会发现一些前所未知的报错,理解为什么会报错,你才会更加深层次的理解这个东西。
往期精彩文章
🌟两种方式轻松做react css样式隔离
🌟彻底理解redux的中间件原理
🌟canvas实现刮刮奖效果
🌟前端实现pdf下载
🌟web前端性能优化(全汇总)
🌟一句话概括this指向问题
🌟MutationObserver 实现微任务原理分析
🌟遇到几次的大厂笔试题:装饰数组push方法
🌟V8垃圾回收策略与GC算法
🌟浏览器缓存策略(强缓存和协商缓存)
🌟$nextTick 源码解读与原理分析
🌟手动封装适合react hook使用的状态管理工具