国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

手把手教你寫一個 Webpack Loader

JiaXinYi / 2021人閱讀

摘要:這個由提供的工具。在轉(zhuǎn)換步驟是異步時,你可以這樣告訴本次轉(zhuǎn)換是異步的,會在中回調(diào)結(jié)果通過返回異步執(zhí)行后的結(jié)果參考編寫一個

本文示例源代碼請戳github博客,建議大家動手敲敲代碼。

本文不會介紹loader的一些使用方法,不熟悉的同學(xué)請自行查看Webpack loader
1、背景

首先我們來看一下為什么需要loader,以及他能干什么?
webpack 只能理解 JavaScriptJSON 文件。loaderwebpack 能夠去處理其他類型的文件,并將它們轉(zhuǎn)換為有效模塊,以供應(yīng)用程序使用,以及被添加到依賴圖中。

本質(zhì)上來說,loader 就是一個 node 模塊,這很符合 webpack 中「萬物皆模塊」的思路。既然是 node 模塊,那就一定會導(dǎo)出點什么。在 webpack 的定義中,loader 導(dǎo)出一個函數(shù),loader 會在轉(zhuǎn)換源模塊resource的時候調(diào)用該函數(shù)。在這個函數(shù)內(nèi)部,我們可以通過傳入 this 上下文給 Loader API 來使用它們。最終裝換成可以直接引用的模塊。

2、xml-Loader 實現(xiàn)

前面我們已經(jīng)知道,由于 Webpack 是運行在 Node.js 之上的,一個 Loader 其實就是一個 Node.js 模塊,這個模塊需要導(dǎo)出一個函數(shù)。 這個導(dǎo)出的函數(shù)的工作就是獲得處理前的原內(nèi)容,對原內(nèi)容執(zhí)行處理后,返回處理后的內(nèi)容。
一個簡單的loader源碼如下

module.exports = function(source) {
  // source 為 compiler 傳遞給 Loader 的一個文件的原內(nèi)容
  // 該函數(shù)需要返回處理后的內(nèi)容,這里簡單起見,直接把原內(nèi)容返回了,相當(dāng)于該 Loader 沒有做任何轉(zhuǎn)換
  return source;
};

由于 Loader 運行在 Node.js 中,你可以調(diào)用任何 Node.js 自帶的 API,或者安裝第三方模塊進(jìn)行調(diào)用:

const xml2js = require("xml2js");
const parser = new xml2js.Parser();

module.exports =  function(source) {
  this.cacheable && this.cacheable();
  const self = this;
  parser.parseString(source, function (err, result) {
    self.callback(err, !err && "module.exports = " + JSON.stringify(result));
  });
};

這里我們事簡單實現(xiàn)一個xml-loader;

注意:如果是處理順序排在最后一個的 loader,那么它的返回值將最終交給 webpackrequire,換句話說,它一定是一段可執(zhí)行的 JS 腳本 (用字符串來存儲),更準(zhǔn)確來說,是一個 node 模塊的 JS 腳本,所以我們需要用module.exports =導(dǎo)出。

整個過程相當(dāng)于這個 loader 把源文件

// 這里是 source 模塊

轉(zhuǎn)化為

// example.js
module.exports = "這里是 source 模塊";

然后交給 require 調(diào)用方:

// applySomeModule.js
var source = require("example.js"); 
console.log(source); // 這里是 source 模塊

寫完后我們要怎么在本地驗證呢?下面我們來寫個簡單的demo進(jìn)行驗證。

2.1、驗證

首先我們創(chuàng)建一個根目錄xml-loader,此目錄下 npm init -y生成默認(rèn)的package.json文件 ,在文件中配置打包命令

"scripts": {
    "dev": "webpack-dev-server"
  },

之后npm i -D webpack webpack-cli,安裝完webpack,在根目錄 創(chuàng)建配置文件webpack.config.js

const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  module: {
    rules: [
      {
        test: /.xml$/,
        use: ["xml-loader"],
      }
    ]
  },
  resolveLoader: {
    modules: [path.join(__dirname, "/src/loader")]
  },
  devServer: {
    contentBase: "./dist",
    overlay: {
      warnings: true,
      errors: true
    },
    open: true
  }
}

在根目錄創(chuàng)建一個src目錄,里面創(chuàng)建index.js,

import data from "./foo.xml";

function component() {
  var element = document.createElement("div");
  element.innerHTML = data.note.body;
  element.classList.add("header");
  console.log(data);
  return element;
}

document.body.appendChild(component());

同時還有一個foo.xml文件



    Mary
    John
    Reminder  dd
    Call Cindy on Tuesday dd

最后把上面的xml-loader放到src/loader文件夾下。
完整的demo源碼請看
最終我們的運行效果如下圖

至此一個簡單的webpack loader就實現(xiàn)完成了。當(dāng)然最終使用你可以發(fā)布到npm上。

3、一些議論知識補(bǔ)充 3.1、獲得 Loader 的 options

當(dāng)我們配置loader時我們經(jīng)常會看到有這樣的配置

ules: [{
    test: /.html$/,
    use: [ {
      loader: "html-loader",
      options: {
        minimize: true
      }
    }],
  }]

那么我們在loader中怎么獲取這寫配置信息呢?答案是loader-utils。這個由webpack提供的工具。下面我們來看下使用方法

const loaderUtils = require("loader-utils");
module.exports = function(source) {
  // 獲取到用戶給當(dāng)前 Loader 傳入的 options
  const options = loaderUtils.getOptions(this);
  return source;
};

沒錯就是這么簡單。

3.2、加載本地 Loader

1、path.resolve
可以簡單通過在 rule 對象設(shè)置 path.resolve 指向這個本地文件

{
  test: /.js$/
  use: [
    {
      loader: path.resolve("path/to/loader.js"),
      options: {/* ... */}
    }
  ]
}

2、ResolveLoader
這個就是上面我用到的方法。ResolveLoader 用于配置 Webpack 如何尋找 Loader。 默認(rèn)情況下只會去 node_modules 目錄下尋找,為了讓 Webpack 加載放在本地項目中的 Loader 需要修改 resolveLoader.modules
假如本地的 Loader 在項目目錄中的 ./loaders/loader-name 中,則需要如下配置:

module.exports = {
  resolveLoader:{
    // 去哪些目錄下尋找 Loader,有先后順序之分
    modules: ["node_modules","./loaders/"],
  }
}

加上以上配置后, Webpack 會先去 node_modules 項目下尋找 Loader,如果找不到,會再去 ./loaders/ 目錄下尋找。
3、npm link
npm link 專門用于開發(fā)和調(diào)試本地 npm 模塊,能做到在不發(fā)布模塊的情況下,把本地的一個正在開發(fā)的模塊的源碼鏈接到項目的 node_modules 目錄下,讓項目可以直接使用本地的 npm 模塊。 由于是通過軟鏈接的方式實現(xiàn)的,編輯了本地的 Npm 模塊代碼,在項目中也能使用到編輯后的代碼。

完成 npm link 的步驟如下:

確保正在開發(fā)的本地 npm 模塊(也就是正在開發(fā)的 Loader)的 package.json 已經(jīng)正確配置好;

在本地 npm 模塊根目錄下執(zhí)行 npm link,把本地模塊注冊到全局;

在項目根目錄下執(zhí)行 npm link loader-name,把第2步注冊到全局的本地 Npm 模塊鏈接到項目的 node_moduels 下,其中的 loader-name 是指在第1步中的package.json 文件中配置的模塊名稱。

鏈接好 Loader 到項目后你就可以像使用一個真正的 Npm 模塊一樣使用本地的 Loader 了。(npm link不是很熟,復(fù)制被人的)

3.3、緩存加速

在有些情況下,有些轉(zhuǎn)換操作需要大量計算非常耗時,如果每次構(gòu)建都重新執(zhí)行重復(fù)的轉(zhuǎn)換操作,構(gòu)建將會變得非常緩慢。 為此,Webpack 會默認(rèn)緩存所有 Loader 的處理結(jié)果,也就是說在需要被處理的文件或者其依賴的文件沒有發(fā)生變化時, 是不會重新調(diào)用對應(yīng)的 Loader 去執(zhí)行轉(zhuǎn)換操作的。

如果你想讓 Webpack 不緩存該 Loader 的處理結(jié)果,可以這樣:

module.exports = function(source) {
  // 關(guān)閉該 Loader 的緩存功能
  this.cacheable(false);
  return source;
};
3.4、處理二進(jìn)制數(shù)據(jù)

在默認(rèn)的情況下,Webpack 傳給 Loader 的原內(nèi)容都是 UTF-8 格式編碼的字符串。 但有些場景下 Loader 不是處理文本文件,而是處理二進(jìn)制文件,例如 file-loader,就需要 Webpack 給 Loader 傳入二進(jìn)制格式的數(shù)據(jù)。 為此,你需要這樣編寫 Loader:

module.exports = function(source) {
    // 在 exports.raw === true 時,Webpack 傳給 Loader 的 source 是 Buffer 類型的
    source instanceof Buffer === true;
    // Loader 返回的類型也可以是 Buffer 類型的
    // 在 exports.raw !== true 時,Loader 也可以返回 Buffer 類型的結(jié)果
    return source;
};
// 通過 exports.raw 屬性告訴 Webpack 該 Loader 是否需要二進(jìn)制數(shù)據(jù) 
module.exports.raw = true;

以上代碼中最關(guān)鍵的代碼是最后一行 module.exports.raw = true;,沒有該行 Loader 只能拿到字符串。

3.5、同步與異步

Loader 有同步和異步之分,上面介紹的 Loader 都是同步的 Loader,因為它們的轉(zhuǎn)換流程都是同步的,轉(zhuǎn)換完成后再返回結(jié)果。 但在有些場景下轉(zhuǎn)換的步驟只能是異步完成的,例如你需要通過網(wǎng)絡(luò)請求才能得出結(jié)果,如果采用同步的方式網(wǎng)絡(luò)請求就會阻塞整個構(gòu)建,導(dǎo)致構(gòu)建非常緩慢。

在轉(zhuǎn)換步驟是異步時,你可以這樣:

module.exports = function(source) {
    // 告訴 Webpack 本次轉(zhuǎn)換是異步的,Loader 會在 callback 中回調(diào)結(jié)果
    var callback = this.async();
    someAsyncOperation(source, function(err, result, sourceMaps, ast) {
        // 通過 callback 返回異步執(zhí)行后的結(jié)果
        callback(err, result, sourceMaps, ast);
    });
};

參考

編寫一個webpack loader

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/103821.html

相關(guān)文章

  • 教你webpack、react和node.js環(huán)境配置(上篇)

    摘要:這里是里面的內(nèi)容安裝如果速度太慢,建議使用淘寶的,和的區(qū)別建議去了解一下。安裝以及相關(guān)插件使用加載器繼續(xù)修改里面的內(nèi)容,給對象加一個屬性。 很多人剛學(xué)習(xí)react的時候,往往因為繁瑣的配置而頭疼,這里我將手把手教大家怎么用webpack配置react和redux的環(huán)境,這篇教程包括前端react和后臺node整個網(wǎng)站的環(huán)境配置,對node沒興趣的可以只看這篇。這里是下篇鏈接:手把手教你...

    SoapEye 評論0 收藏0
  • 教你webpack、react和node.js環(huán)境配置(上篇)

    摘要:這里是里面的內(nèi)容安裝如果速度太慢,建議使用淘寶的,和的區(qū)別建議去了解一下。安裝以及相關(guān)插件使用加載器繼續(xù)修改里面的內(nèi)容,給對象加一個屬性。 很多人剛學(xué)習(xí)react的時候,往往因為繁瑣的配置而頭疼,這里我將手把手教大家怎么用webpack配置react和redux的環(huán)境,這篇教程包括前端react和后臺node整個網(wǎng)站的環(huán)境配置,對node沒興趣的可以只看這篇。這里是下篇鏈接:手把手教你...

    alexnevsky 評論0 收藏0
  • 把手教你從零搭建react局部熱加載環(huán)境

    摘要:有沒有辦法實現(xiàn)就局部刷新呢當(dāng)然是有第十步執(zhí)行為了實現(xiàn)局部熱加載,我們需要添加插件。 前言 用了3個多月的vue自認(rèn)為已經(jīng)是一名合格的vue框架api搬運工,對于vue的api使用到達(dá)了一定瓶頸,無奈水平有限,每每深入底層觀賞源碼時候都迷失了自己。 遂決定再找個框架學(xué)習(xí)學(xué)習(xí)看看能否突破思維局限,加上本人早已對React、RN技術(shù)垂涎已久,于是決定找找教程來學(xué)習(xí)。無奈第一步就卡在了環(huán)境搭...

    quietin 評論0 收藏0
  • 把手教你一個 Webpack Loader

    摘要:夾在中間的被鏈?zhǔn)秸{(diào)用,他們拿到上個的返回值,為下一個提供輸入。最終把返回值和傳給。前面我們說過,也是一個模塊,它導(dǎo)出一個函數(shù),該函數(shù)的參數(shù)是的源模塊,處理后把返回值交給下一個。 文:小 boy(滬江網(wǎng)校Web前端工程師)本文原創(chuàng),轉(zhuǎn)載請注明作者及出處 showImg(https://segmentfault.com/img/remote/1460000012990131?w=1083...

    sugarmo 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<