Loader Interface
loader-utils
loader-runner
一個最簡單的 loader 代碼結(jié)構(gòu)
定義: loader 只是一個導(dǎo)出為函數(shù)的 JavaScript 模塊
module.exports = function (source) {
return source;
};
使用loader-runner進行l(wèi)oader的調(diào)試
定義:允許你在不安裝webpack的情況下運行l(wèi)oaders
作用:作為webpack的依賴荧呐,在webpack中執(zhí)行l(wèi)oader
進行l(wèi)oader的開發(fā)和調(diào)試
import {runLoaders} from 'loader-runner';
runLoaders({
resource: "/abs/path/to/file.txt?query",
loaders: [],
context: {},
readResource: fs.readFile.bind(fs)
}, function(err, result) {
// err
// result
});
屬性名 | 說明 |
---|---|
resource | 資源的絕對路徑(可以增加查詢字符串) |
loaders | loader 的絕對路徑(可以增加查詢字符串) |
context | 基礎(chǔ)上下文之外的額外 loader 上下文 |
readResource | 讀取資源的函數(shù) |
loader的參數(shù)獲取
通過loader-utils的getOptions方法獲取
const loaderUtils = require("loader-utils");
module.exports = function(content) {
const { name } = loaderUtils.getOptions(this);
};
loader的異常處理
1、loader 內(nèi)直接通過 throw 拋出
2查刻、通過傳遞錯誤
this.callback(
err: Error | null,
content: string | Buffer,
sourceMap?: SourceMap,
meta?:any
);
loader的異步處理
module.exports = function(input) {
const callback = this.async();
// No callback -> return synchronous results // if (callback) { ... }
callback(null, input + input); //第一個參數(shù)是 Error,第二個參數(shù)是處理的結(jié)果
};
在 loader 中使用緩存
webpack 中默認開啟 loader 緩存
(可以使用 this.cacheable(false) 關(guān)掉緩存)
緩存條件: loader 的結(jié)果在相同的輸入下有確定的輸出
(有依賴的 loader 無法使用緩存)
loader 如何進行文件輸出
const loaderUtils = require("loader-utils");
module.exports = function (content) {
const url = loaderUtils.interpolateName(this, "[hash].[ext]", {
content,
});
this.emitFile(url, content);
const path = `__webpack_public_path__ + ${JSON.stringify(url)};`;
return `export default ${path}`;
};
插件的運行環(huán)境
只能在 webpack 里面運行
插件的基本結(jié)構(gòu)
基本結(jié)構(gòu)
/* 插件名稱 */
class MyPlugin {
/* apply方法 */
apply(compiler) {
/* 插件的hooks */
compiler.hooks.done.tap(' My Plugin', (
stats/* stats is passed as argument when done hook is tapped. */
) => {
/* 邏輯 */
console.log('Hello World!');
});
}
}
module.exports = MyPlugin;
插件使用:
plugins: [ new MyPlugin() ]
搭建插件的運行環(huán)境
const path = require("path");
const DemoPlugin = require("./plugins/demo-plugin.js");
const PATHS = {
lib: path.join(__dirname, "app", "shake.js"),
build: path.join(__dirname, "build")
};
module.exports = {
entry: {
lib: PATHS.lib,
},
output: {
path: PATHS.build,
filename: "[name].js",
},
plugins: [new DemoPlugin()]
};
插件中如何獲取傳遞的參數(shù)
通過插件的構(gòu)造函數(shù)進行獲取
constructor(options) {
this.options = options;
}
new ZipPlugin({
filename: 'offline'
})
插件的錯誤處理
參數(shù)校驗階段可以直接 throw 的方式拋出
throw new Error(“ Error Message”);
通過 compilation 對象的 warnings 和 errors 接收
compilation.warnings.push("warning");
compilation.errors.push("error");
通過 Compilation 進行文件寫入
Compilation 上的 assets 可以用于文件寫入
文件寫入需要使用 webpack-sources (https://www.npmjs.com/package/webpack-sources)
const {
RawSource
} = require("webpack-sources");
module.exports = class DemoPlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
const {
name
} = this.options;
compiler.plugin("emit", (compilation, cb) => {
compilation.assets[name] = new RawSource("demo");
cb();
})
}
};