Webpack
中文:
Loader Interface | webpack 中文文档
如何编写一个Loader
呢?其实非常的简单,Loader
就是一个函数用来处理代码的逻辑。
编写一个 Loader
新建初始化一个项目:
$ npm init -y
安装Webpack
:
$ npm install webpack webpack-cli -S
到此全部的文件目录
mark-loader
├─package-lock.json
├─package.json
├─webpack.config.js
├─src
| └index.js
├─loaders
| └replaceLoader.js
loaders
文件夹下存放所有的自己编写的Loader
,我们在index.js
文件写自己的业务逻辑:
console.log("hello dll");
方法接收一个source
参数:
module.exports = function (source) {
// 接收 js 文件的内容
return source.replace("dll", "dllLee")
}
使用我们新写的Loader
:
const path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
module: {
rules: [{
test: /\.js/,
// 使用本地的 Loader
use: [path.resolve(__dirname, "./loaders/replaceLoader.js")]
}]
}
}
然后运行npm run build
我们就能看到dist/ main.js
文件中的输出是dllLee
。
Loader 的配置项目
我们自己编写的Loader
如何进行参数配置呢?
和其他Loader
一样新增options
属性:
const path = require("path")
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
module: {
rules: [{
test: /\.js/,
// 使用本地的 Loader
use: [{
loader: path.resolve(__dirname, "./loaders/replaceLoader.js"),
options: {
name: "test"
}
}]
}]
}
}
现在我们虽然配置options
,那么如何才能获取到它呢?
使用this.query
就能获取到optins
里面的参数:
Loader Interface | webpack 中文文档
module.exports = function (source) {
// 接收 js 文件的内容
return source.replace("dll", this.query.name)
}
假设我们现在有需求要返回sourcemap
怎么做呢?可以使用callback
:
Loader Interface | webpack 中文文档
module.exports = function (source) {
// 接收 js 文件的内容
let result = source.replace("dll", this.query.name);
this.callback(Error, result, SourceMap, meta)
}
处理异步Loader
假如我们的Loader
里面存在异步的方法,就像这样:
module.exports = function (source) {
let result = source.replace("dll", this.query.name)
setTimeout(() => {
this.callback(null, result);
}, 1000)
}
这个时候运行npm run build
就会报错,而报错的原因就是说我们没有返回代码的处理结果,而实际上我们是在一秒后才会返回处理的接口,这个时候就需要用this.async()
来帮我们解决了。
this.async()
的参数配置和this.callback()
是一样的:
module.exports = function (source) {
let result = source.replace("dll", this.query.name)
let callback = this.async();
setTimeout(() => {
callback(null, result);
}, 1000)
}
简化 Loader 路径
到目前呀我们就能实现一个自定义的Loader
了,但是他的路径非常的长如何才能简化呢?配置resolveLoader
:
const path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
// 寻找 Loader 的路径(从左到右),如果 node_module 下存在就使用 node 下的 Loader
resolveLoader: {
modules: ["node_modules", "./loaders"]
},
module: {
rules: [{
test: /\.js/,
// 使用本地的 Loader
use: [{
loader: "replaceLoader",
options: {
name: "test"
}
}]
}]
}
}