編寫 Loader 和插件

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查刻、通過\color{red}{this.callback}傳遞錯誤

this.callback(
    err: Error | null,
    content: string | Buffer, 
    sourceMap?: SourceMap,
    meta?:any
);

loader的異步處理

通過\color{red}{this.async} 來返回一個異步函數(shù)

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 如何進行文件輸出

通過\color{red}{this.emitFile}進行文件寫入

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();
        })
    }
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挚瘟,一起剝皮案震驚了整個濱河市五督,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鞭衩,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異论衍,居然都是意外死亡瑞佩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門坯台,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炬丸,“玉大人,你說我怎么就攤上這事蜒蕾〕砭妫” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵咪啡,是天一觀的道長酸纲。 經(jīng)常有香客問我,道長瑟匆,這世上最難降的妖魔是什么闽坡? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮愁溜,結(jié)果婚禮上疾嗅,老公的妹妹穿的比我還像新娘。我一直安慰自己冕象,他們只是感情好代承,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著渐扮,像睡著了一般论悴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上墓律,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天膀估,我揣著相機與錄音,去河邊找鬼耻讽。 笑死察纯,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的针肥。 我是一名探鬼主播饼记,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼慰枕!你這毒婦竟也來了具则?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤具帮,失蹤者是張志新(化名)和其女友劉穎博肋,沒想到半個月后低斋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡束昵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了葛峻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锹雏。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖术奖,靈堂內(nèi)的尸體忽然破棺而出礁遵,到底是詐尸還是另有隱情,我是刑警寧澤采记,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布佣耐,位于F島的核電站,受9級特大地震影響唧龄,放射性物質(zhì)發(fā)生泄漏兼砖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一既棺、第九天 我趴在偏房一處隱蔽的房頂上張望讽挟。 院中可真熱鬧,春花似錦丸冕、人聲如沸耽梅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽眼姐。三九已至,卻和暖如春佩番,著一層夾襖步出監(jiān)牢的瞬間众旗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工趟畏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留逝钥,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓拱镐,卻偏偏與公主長得像艘款,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子沃琅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容