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/,// 使用本地的 Loaderuse: [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/,// 使用本地的 Loaderuse: [{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 下的 LoaderresolveLoader: {modules: ["node_modules", "./loaders"]},module: {rules: [{test: /\.js/,// 使用本地的 Loaderuse: [{loader: "replaceLoader",options: {name: "test"}}]}]}}
