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

資訊專欄INFORMATION COLUMN

手把手教你寫(xiě)一個(gè) Webpack Loader

JiaXinYi / 2020人閱讀

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

本文示例源代碼請(qǐng)戳github博客,建議大家動(dòng)手敲敲代碼。

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

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

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

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

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

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

由于 Loader 運(yùn)行在 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));
  });
};

這里我們事簡(jiǎn)單實(shí)現(xiàn)一個(gè)xml-loader;

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

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

// 這里是 source 模塊

轉(zhuǎn)化為

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

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

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

寫(xiě)完后我們要怎么在本地驗(yàn)證呢?下面我們來(lái)寫(xiě)個(gè)簡(jiǎn)單的demo進(jìn)行驗(yàn)證。

2.1、驗(yàn)證

首先我們創(chuàng)建一個(gè)根目錄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)建一個(gè)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());

同時(shí)還有一個(gè)foo.xml文件



    Mary
    John
    Reminder  dd
    Call Cindy on Tuesday dd

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

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

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

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

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

那么我們?cè)趌oader中怎么獲取這寫(xiě)配置信息呢?答案是loader-utils。這個(gè)由webpack提供的工具。下面我們來(lái)看下使用方法

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

沒(méi)錯(cuò)就是這么簡(jiǎn)單。

3.2、加載本地 Loader

1、path.resolve
可以簡(jiǎn)單通過(guò)在 rule 對(duì)象設(shè)置 path.resolve 指向這個(gè)本地文件

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

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

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

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

完成 npm link 的步驟如下:

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

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

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

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

3.3、緩存加速

在有些情況下,有些轉(zhuǎn)換操作需要大量計(jì)算非常耗時(shí),如果每次構(gòu)建都重新執(zhí)行重復(fù)的轉(zhuǎn)換操作,構(gòu)建將會(huì)變得非常緩慢。 為此,Webpack 會(huì)默認(rèn)緩存所有 Loader 的處理結(jié)果,也就是說(shuō)在需要被處理的文件或者其依賴的文件沒(méi)有發(fā)生變化時(shí), 是不會(huì)重新調(diào)用對(duì)應(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 格式編碼的字符串。 但有些場(chǎng)景下 Loader 不是處理文本文件,而是處理二進(jìn)制文件,例如 file-loader,就需要 Webpack 給 Loader 傳入二進(jìn)制格式的數(shù)據(jù)。 為此,你需要這樣編寫(xiě) Loader:

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

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

3.5、同步與異步

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

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

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

參考

編寫(xiě)一個(gè)webpack loader

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

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

相關(guān)文章

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

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

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

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

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

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

    quietin 評(píng)論0 收藏0
  • 把手教你一個(gè) Webpack Loader

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

    sugarmo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<