国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Webpack5入門到原理17:Loader 原理

這篇具有很好參考價(jià)值的文章主要介紹了Webpack5入門到原理17:Loader 原理。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

loader 概念

幫助 webpack 將不同類型的文件轉(zhuǎn)換為 webpack 可識(shí)別的模塊。

loader 執(zhí)行順序

分類

  • pre: 前置 loader
  • normal: 普通 loader
  • inline: 內(nèi)聯(lián) loader
  • post: 后置 loader

執(zhí)行順序

  • 4 類 loader 的執(zhí)行優(yōu)級(jí)為:pre > normal > inline > post 。
  • 相同優(yōu)先級(jí)的 loader 執(zhí)行順序?yàn)椋簭挠业阶螅瑥南碌缴稀?/li>

例如:

// 此時(shí)loader執(zhí)行順序:loader3 - loader2 - loader1
module: {
  rules: [
    {
      test: /\.js$/,
      loader: "loader1",
    },
    {
      test: /\.js$/,
      loader: "loader2",
    },
    {
      test: /\.js$/,
      loader: "loader3",
    },
  ],
},
// 此時(shí)loader執(zhí)行順序:loader1 - loader2 - loader3
module: {
  rules: [
    {
      enforce: "pre",
      test: /\.js$/,
      loader: "loader1",
    },
    {
      // 沒有enforce就是normal
      test: /\.js$/,
      loader: "loader2",
    },
    {
      enforce: "post",
      test: /\.js$/,
      loader: "loader3",
    },
  ],
},

使用 loader 的方式

  • 配置方式:在 webpack.config.js 文件中指定 loader。(pre、normal、post loader)
  • 內(nèi)聯(lián)方式:在每個(gè) import 語句中顯式指定 loader。(inline loader)

inline loader

用法:import Styles from 'style-loader!css-loader?modules!./styles.css';

含義:

使用 css-loader 和 style-loader 處理 styles.css 文件

通過 ! 將資源中的 loader 分開

inline loader 可以通過添加不同前綴,跳過其他類型 loader。

! 跳過 normal loader。

import Styles from '!style-loader!css-loader?modules!./styles.css';

-! 跳過 pre 和 normal loader。

import Styles from '-!style-loader!css-loader?modules!./styles.css';

!! 跳過 pre、 normal 和 post loader。

import Styles from '!!style-loader!css-loader?modules!./styles.css';

開發(fā)一個(gè) loader

1. 最簡單的 loader

// loaders/loader1.js
module.exports = function loader1(content) {
  console.log("hello loader");
  return content;
};

它接受要處理的源碼作為參數(shù),輸出轉(zhuǎn)換后的 js 代碼。

2. loader 接受的參數(shù)

  • content 源文件的內(nèi)容
  • map SourceMap 數(shù)據(jù)
  • meta 數(shù)據(jù),可以是任何內(nèi)容

loader 分類

1. 同步 loader

module.exports = function (content, map, meta) {
  return content;
};

this.callback 方法則更靈活,因?yàn)樗试S傳遞多個(gè)參數(shù),而不僅僅是 content。

module.exports = function (content, map, meta) {
  // 傳遞map,讓source-map不中斷
  // 傳遞meta,讓下一個(gè)loader接收到其他參數(shù)
  this.callback(null, content, map, meta);
  return; // 當(dāng)調(diào)用 callback() 函數(shù)時(shí),總是返回 undefined
};

2. 異步 loader

module.exports = function (content, map, meta) {
  const callback = this.async();
  // 進(jìn)行異步操作
  setTimeout(() => {
    callback(null, result, map, meta);
  }, 1000);
};

由于同步計(jì)算過于耗時(shí),在 Node.js 這樣的單線程環(huán)境下進(jìn)行此操作并不是好的方案,我們建議盡可能地使你的 loader 異步化。但如果計(jì)算量很小,同步 loader 也是可以的。

3. Raw Loader

默認(rèn)情況下,資源文件會(huì)被轉(zhuǎn)化為 UTF-8 字符串,然后傳給 loader。通過設(shè)置 raw 為 true,loader 可以接收原始的 Buffer。

module.exports = function (content) {
  // content是一個(gè)Buffer數(shù)據(jù)
  return content;
};
module.exports.raw = true; // 開啟 Raw Loader

4. Pitching Loader

module.exports = function (content) {
  return content;
};
module.exports.pitch = function (remainingRequest, precedingRequest, data) {
  console.log("do somethings");
};

webpack 會(huì)先從左到右執(zhí)行 loader 鏈中的每個(gè) loader 上的 pitch 方法(如果有),然后再從右到左執(zhí)行 loader 鏈中的每個(gè) loader 上的普通 loader 方法。

在這個(gè)過程中如果任何 pitch 有返回值,則 loader 鏈被阻斷。webpack 會(huì)跳過后面所有的的 pitch 和 loader,直接進(jìn)入上一個(gè) loader 。

loader API

方法名 含義 用法
this.async 異步回調(diào) loader。返回 this.callback const callback = this.async()
this.callback 可以同步或者異步調(diào)用的并返回多個(gè)結(jié)果的函數(shù) this.callback(err, content, sourceMap?, meta?)
this.getOptions(schema) 獲取 loader 的 options this.getOptions(schema)
this.emitFile 產(chǎn)生一個(gè)文件 this.emitFile(name, content, sourceMap)
this.utils.contextify 返回一個(gè)相對路徑 this.utils.contextify(context, request)
this.utils.absolutify 返回一個(gè)絕對路徑 this.utils.absolutify(context, request)

更多文檔,請查閱?webpack 官方 loader api 文檔?

手寫 clean-log-loader

作用:用來清理 js 代碼中的console.log

// loaders/clean-log-loader.js
module.exports = function cleanLogLoader(content) {
  // 將console.log替換為空
  return content.replace(/console\.log\(.*\);?/g, "");
};

手寫 banner-loader

作用:給 js 代碼添加文本注釋

loaders/banner-loader/index.js

const schema = require("./schema.json");

module.exports = function (content) {
  // 獲取loader的options,同時(shí)對options內(nèi)容進(jìn)行校驗(yàn)
  // schema是options的校驗(yàn)規(guī)則(符合 JSON schema 規(guī)則)
  const options = this.getOptions(schema);

  const prefix = `
    /*
    * Author: ${options.author}
    */
  `;

  return `${prefix} \n ${content}`;
};

loaders/banner-loader/schema.json

{
  "type": "object",
  "properties": {
    "author": {
      "type": "string"
    }
  },
  "additionalProperties": false
}

手寫 babel-loader

作用:編譯 js 代碼,將 ES6+語法編譯成 ES5-語法。

下載依賴

npm i @babel/core @babel/preset-env -D

loaders/babel-loader/index.js

const schema = require("./schema.json");
const babel = require("@babel/core");

module.exports = function (content) {
  const options = this.getOptions(schema);
  // 使用異步loader
  const callback = this.async();
  // 使用babel對js代碼進(jìn)行編譯
  babel.transform(content, options, function (err, result) {
    callback(err, result.code);
  });
};

loaders/banner-loader/schema.json

{
  "type": "object",
  "properties": {
    "presets": {
      "type": "array"
    }
  },
  "additionalProperties": true
}

手寫 file-loader

作用:將文件原封不動(dòng)輸出出去

下載包

npm i loader-utils -D

loaders/file-loader.js

const loaderUtils = require("loader-utils");

function fileLoader(content) {
  // 根據(jù)文件內(nèi)容生產(chǎn)一個(gè)新的文件名稱
  const filename = loaderUtils.interpolateName(this, "[hash].[ext]", {
    content,
  });
  // 輸出文件
  this.emitFile(filename, content);
  // 暴露出去,給js引用。
  // 記得加上''
  return `export default '${filename}'`;
}

// loader 解決的是二進(jìn)制的內(nèi)容
// 圖片是 Buffer 數(shù)據(jù)
fileLoader.raw = true;

module.exports = fileLoader;

loader 配置

{
  test: /\.(png|jpe?g|gif)$/,
  loader: "./loaders/file-loader.js",
  type: "javascript/auto", // 解決圖片重復(fù)打包問題
},

手寫 style-loader

作用:動(dòng)態(tài)創(chuàng)建 style 標(biāo)簽,插入 js 中的樣式代碼,使樣式生效。

loaders/style-loader.js文章來源地址http://www.zghlxwxcb.cn/news/detail-816030.html

const styleLoader = () => {};

styleLoader.pitch = function (remainingRequest) {
  /*
    remainingRequest: C:\Users\86176\Desktop\source\node_modules\css-loader\dist\cjs.js!C:\Users\86176\Desktop\source\src\css\index.css
      這里是inline loader用法,代表后面還有一個(gè)css-loader等待處理

    最終我們需要將remainingRequest中的路徑轉(zhuǎn)化成相對路徑,webpack才能處理
      希望得到:../../node_modules/css-loader/dist/cjs.js!./index.css

    所以:需要將絕對路徑轉(zhuǎn)化成相對路徑
    要求:
      1. 必須是相對路徑
      2. 相對路徑必須以 ./ 或 ../ 開頭
      3. 相對路徑的路徑分隔符必須是 / ,不能是 \
  */
  const relativeRequest = remainingRequest
    .split("!")
    .map((part) => {
      // 將路徑轉(zhuǎn)化為相對路徑
      const relativePath = this.utils.contextify(this.context, part);
      return relativePath;
    })
    .join("!");

  /*
    !!${relativeRequest} 
      relativeRequest:../../node_modules/css-loader/dist/cjs.js!./index.css
      relativeRequest是inline loader用法,代表要處理的index.css資源, 使用css-loader處理
      !!代表禁用所有配置的loader,只使用inline loader。(也就是外面我們style-loader和css-loader),它們被禁用了,只是用我們指定的inline loader,也就是css-loader

    import style from "!!${relativeRequest}"
      引入css-loader處理后的css文件
      為什么需要css-loader處理css文件,不是我們直接讀取css文件使用呢?
      因?yàn)榭赡艽嬖贎import導(dǎo)入css語法,這些語法就要通過css-loader解析才能變成一個(gè)css文件,否則我們引入的css資源會(huì)缺少
    const styleEl = document.createElement('style')
      動(dòng)態(tài)創(chuàng)建style標(biāo)簽
    styleEl.innerHTML = style
      將style標(biāo)簽內(nèi)容設(shè)置為處理后的css代碼
    document.head.appendChild(styleEl)
      添加到head中生效
  */
  const script = `
    import style from "!!${relativeRequest}"
    const styleEl = document.createElement('style')
    styleEl.innerHTML = style
    document.head.appendChild(styleEl)
  `;

  // style-loader是第一個(gè)loader, 由于return導(dǎo)致熔斷,所以其他loader不執(zhí)行了(不管是normal還是pitch)
  return script;
};

module.exports = styleLoader;

到了這里,關(guān)于Webpack5入門到原理17:Loader 原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Webpack5入門到原理2:基本使用

    Webpack 是一個(gè)靜態(tài)資源打包工具。 它會(huì)以一個(gè)或多個(gè)文件作為打包的入口,將我們整個(gè)項(xiàng)目所有文件編譯組合成一個(gè)或多個(gè)文件輸出出去。 輸出的文件就是編譯好的文件,就可以在瀏覽器段運(yùn)行了。 我們將 Webpack 輸出的文件叫做 bundle。 Webpack 本身功能是有限的: 開發(fā)模式:

    2024年01月22日
    瀏覽(20)
  • Webpack5入門到原理5:處理樣式資源

    我們學(xué)習(xí)使用 Webpack 如何處理 Css、Less、Sass、Scss、Styl 樣式資源 Webpack 本身是不能識(shí)別樣式資源的,所以我們需要借助 Loader 來幫助 Webpack 解析樣式資源 我們找 Loader 都應(yīng)該去官方文檔中找到對應(yīng)的 Loader,然后使用 官方文檔找不到的話,可以從社區(qū) Github 中搜索查詢 Webpack 官

    2024年01月21日
    瀏覽(21)
  • Webpack5入門到原理14:生產(chǎn)模式介紹

    生產(chǎn)模式是開發(fā)完成代碼后,我們需要得到代碼將來部署上線。 這個(gè)模式下我們主要對代碼進(jìn)行優(yōu)化,讓其運(yùn)行性能更好。 優(yōu)化主要從兩個(gè)角度出發(fā): 優(yōu)化代碼運(yùn)行性能 優(yōu)化代碼打包速度 我們分別準(zhǔn)備兩個(gè)配置文件來放不同的配置 因?yàn)槲募夸涀兞?,所以所有絕對路徑需要

    2024年01月23日
    瀏覽(63)
  • Webpack5入門到原理21:提升開發(fā)體驗(yàn)

    開發(fā)時(shí)我們運(yùn)行的代碼是經(jīng)過 webpack 編譯后的,例如下面這個(gè)樣子: 所有 css 和 js 合并成了一個(gè)文件,并且多了其他代碼。此時(shí)如果代碼運(yùn)行出錯(cuò)那么提示代碼錯(cuò)誤位置我們是看不懂的。一旦將來開發(fā)代碼文件很多,那么很難去發(fā)現(xiàn)錯(cuò)誤出現(xiàn)在哪里。 所以我們需要更加準(zhǔn)確

    2024年01月25日
    瀏覽(17)
  • Webpack5入門到原理3:基本配置

    在開始使用 Webpack 之前,我們需要對 Webpack 的配置有一定的認(rèn)識(shí)。 entry(入口) 指示 Webpack 從哪個(gè)文件開始打包 output(輸出) 指示 Webpack 打包完的文件輸出到哪里去,如何命名等 loader(加載器) webpack 本身只能處理 js、json 等資源,其他資源需要借助 loader,Webpack 才能解析

    2024年01月20日
    瀏覽(52)
  • Webpack5入門到原理6:處理圖片資源

    過去在 Webpack4 時(shí),我們處理圖片資源通過 file-loader 和 url-loader 進(jìn)行處理 現(xiàn)在 Webpack5 已經(jīng)將兩個(gè) Loader 功能內(nèi)置到 Webpack 里了,我們只需要簡單配置即可處理圖片資源 src/images/1.jpeg src/images/2.png src/images/3.gif src/less/index.less src/sass/index.sass src/styl/index.styl 打開 index.html 頁面查看

    2024年01月20日
    瀏覽(23)
  • Webpack5入門到原理22:提升打包構(gòu)建速度

    開發(fā)時(shí)我們修改了其中一個(gè)模塊代碼,Webpack 默認(rèn)會(huì)將所有模塊全部重新打包編譯,速度很慢。 所以我們需要做到修改某個(gè)模塊代碼,就只有這個(gè)模塊代碼需要重新打包編譯,其他模塊不變,這樣打包速度就能很快。 HotModuleReplacement(HMR/熱模塊替換):在程序運(yùn)行中,替換、

    2024年01月21日
    瀏覽(21)
  • Webpack5入門到原理11:處理 js 資源

    有人可能會(huì)問,js 資源 Webpack 不能已經(jīng)處理了嗎,為什么我們還要處理呢? 原因是 Webpack 對 js 處理是有限的,只能編譯 js 中 ES 模塊化語法,不能編譯其他語法,導(dǎo)致 js 不能在 IE 等瀏覽器運(yùn)行,所以我們希望做一些兼容性處理。 其次開發(fā)中,團(tuán)隊(duì)對代碼格式是有嚴(yán)格要求的

    2024年01月20日
    瀏覽(55)
  • Webpack5入門到原理12:處理 Html 資源

    webpack.config.js 去掉引入的 js 文件,因?yàn)?HtmlWebpackPlugin 會(huì)自動(dòng)引入 此時(shí) dist 目錄就會(huì)輸出一個(gè) index.html 文件

    2024年01月23日
    瀏覽(24)
  • Webpack5 vue-loader和VueLoaderPlugin

    .vue 文件是用戶用 HTML-like 的語法編寫的 Vue 組件。每個(gè)vue 文件都包括三部分 , VueLoaderPlugin 是一個(gè)解析 Vue.js 的插件,用于在 webpack 構(gòu)建過程中解析和轉(zhuǎn)換 .vue 單文件組件。它的作用是將 .vue 文件中的模板、樣式和腳本進(jìn)行編譯,并將其轉(zhuǎn)換為 JavaScript 模塊,以供Webpack打包使

    2024年02月15日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包