Webpack:Node 接口

2023-05-09 15:39 更新

Webpack 提供了 Node.js API,可以在 Node.js 運行時下直接使用。

當你需要自定義構建或開發(fā)流程時,Node.js API 非常有用,因為此時所有的報告和錯誤處理都必須自行實現(xiàn),webpack 僅僅負責編譯的部分。所以 stats 配置選項不會在 webpack() 調(diào)用中生效。

安裝(Installation)

開始使用 webpack 的 Node.js API 之前,首先你需要安裝 webpack:

npm install --save-dev webpack

在 Node.js 文件中,引入 webpack 模塊:

const webpack = require('webpack');

或者如果你更喜歡 ES2015:

import webpack from 'webpack';

webpack()

導入的 webpack 函數(shù)會將 配置對象 傳給 webpack,如果同時傳入回調(diào)函數(shù)會在 webpack compiler 運行時被執(zhí)行:

const webpack = require('webpack');

webpack({}, (err, stats) => {
  if (err || stats.hasErrors()) {
    // ...
  }
  // 處理完成
});

Compiler 實例(Compiler Instance)

如果你不向 webpack 傳入可執(zhí)行的回調(diào)函數(shù), 它會返回一個 webpack Compiler 實例。 你可以通過手動執(zhí)行它或者為它的構建時添加一個監(jiān)聽器, 就像 CLI 類似。Compiler 實例提供了以下方法:

  • .run(callback)
  • .watch(watchOptions, handler)

通常情況下,僅會創(chuàng)建一個主要 Compiler 實例, 雖然可以創(chuàng)建一些子 compiler 來代理到特定任務。 Compiler 基本上只是執(zhí)行最低限度的功能,以維持生命周期運行的功能。 它將所有的加載、打包和寫入工作, 都委托到注冊過的插件上。

Compiler 實例上的 hooks 屬性,用于將一個插件注冊 到 Compiler 的生命周期中的所有鉤子事件上。webpack 使用 WebpackOptionsDefaulter 和 WebpackOptionsApply 來配置 Compiler 實例以及所有內(nèi)置插件。

使用 run 方法啟動所有編譯工作。 完成之后,執(zhí)行傳入的的 callback 函數(shù)。 最終記錄下來的概括信息(stats)和錯誤(errors),都應在這個 callback 函數(shù)中獲取。

執(zhí)行(Run)

調(diào)用 Compiler 實例的 run 方法跟上文提到的 快速執(zhí)行方法很類似:

const webpack = require('webpack');

const compiler = webpack({
  // ...
});

compiler.run((err, stats) => {
  // ...

  compiler.close((closeErr) => {
    // ...
  });
});

監(jiān)聽(Watching)

調(diào)用 watch 方法會觸發(fā) webpack 執(zhí)行,但之后會監(jiān)聽變更(很像 CLI 命令: webpack --watch), 一旦 webpack 檢測到文件變更,就會重新執(zhí)行編譯。 該方法返回一個 Watching 實例。

watch(watchOptions, callback);
const webpack = require('webpack');

const compiler = webpack({
  // ...
});

const watching = compiler.watch(
  {
    // 示例
    aggregateTimeout: 300,
    poll: undefined,
  },
  (err, stats) => {
    // 這里打印 watch/build 結果...
    console.log(stats);
  }
);

關閉 Watching (Close Watching)

watch 方法返回一個 Watching 實例,該實例會暴露一個 .close(callback) 方法。 調(diào)用該方法將會結束監(jiān)聽:

watching.close((closeErr) => {
  console.log('Watching Ended.');
});

Invalidate Watching

使用 watching.invalidate,你可以手動使當前編譯循環(huán)(compiling round)無效, 而不會停止監(jiān)聽進程(process):

watching.invalidate();

Stats 對象(Stats Object)

stats 對象會被作為 webpack() 回調(diào)函數(shù)的第二個參數(shù)傳遞, 可以通過它獲取到代碼編譯過程中的有用信息, 包括:

  • 錯誤和警告(如果有的話)
  • 計時信息
  • module 和 chunk 信息

webpack CLI 正是基于這些信息在控制臺 展示友好的格式輸出。

stats 對象暴露了以下方法:

stats.hasErrors()

可以用來檢查編譯期是否有錯誤, 返回值為 true 或 false。

stats.hasWarnings()

可以用來檢查編譯期是否有警告, 返回值為 true 或 false。

stats.toJson(options)

以 JSON 對象形式返回編譯信息。 options 可以是一個字符串(預設值)或是顆?;刂频膶ο?

stats.toJson('minimal');
stats.toJson({
  assets: false,
  hash: true,
});

所有可用的配置選項和預設值都可查詢 stats 文檔。

stats.toString(options)

以格式化的字符串形式返回描述編譯信息 (類似 CLI 的輸出)。

配置對象與 stats.toJson(options) 一致,除了額外增加的一個選項:

stats.toString({
  // 增加控制臺顏色開關
  colors: true,
});

下面是 stats.toString() 用法的示例:

const webpack = require('webpack');

webpack(
  {
    // ...
  },
  (err, stats) => {
    if (err) {
      console.error(err);
      return;
    }

    console.log(
      stats.toString({
        chunks: false, // 使構建過程更靜默無輸出
        colors: true,  // 在控制臺展示顏色
      })
    );
  }
);

MultiCompiler

MultiCompiler 模塊可以讓 webpack 同時執(zhí)行多個配置。 如果傳給 webpack 的 Node.js API 的 options 參數(shù), 該參數(shù)由是由多個配置對象構成的數(shù)組,webpack 會相應地創(chuàng)建多個 compiler 實例, 并且在所有 compiler 執(zhí)行完畢后調(diào)用 callback 方法。

var webpack = require('webpack');

webpack(
  [
    { entry: './index1.js', output: { filename: 'bundle1.js' } },
    { entry: './index2.js', output: { filename: 'bundle2.js' } },
  ],
  (err, stats) => {
    process.stdout.write(stats.toString() + '\n');
  }
);

錯誤處理(Error Handling)

完備的錯誤處理中需要考慮以下三種類型的錯誤:

  • 致命的 wepback 錯誤(配置出錯等)
  • 編譯錯誤(缺失的 module,語法錯誤等)
  • 編譯警告

下面是一個覆蓋這些場景的示例:

const webpack = require('webpack');

webpack(
  {
    // ...
  },
  (err, stats) => {
    if (err) {
      console.error(err.stack || err);
      if (err.details) {
        console.error(err.details);
      }
      return;
    }

    const info = stats.toJson();

    if (stats.hasErrors()) {
      console.error(info.errors);
    }

    if (stats.hasWarnings()) {
      console.warn(info.warnings);
    }

    // Log result...
  }
);

自定義文件系統(tǒng)(Custom File Systems)

默認情況下,webpack 使用普通文件系統(tǒng)來讀取文件并將文件寫入磁盤。 但是,還可以使用不同類型的文件系統(tǒng)(內(nèi)存(memory), webDAV 等)來更改輸入或輸出行為。 為了實現(xiàn)這一點, 可以改變 inputFileSystem 或 outputFileSystem。 例如,可以使用 memfs 替換默認的 outputFileSystem, 以將文件寫入到內(nèi)存中, 而不是寫入到磁盤:

const { createFsFromVolume, Volume } = require('memfs');
const webpack = require('webpack');

const fs = createFsFromVolume(new Volume());
const compiler = webpack({
  /* options */
});

compiler.outputFileSystem = fs;
compiler.run((err, stats) => {
  // 之后讀取輸出:
  const content = fs.readFileSync('...');
  compiler.close((closeErr) => {
    // ...
  });
});

值得一提的是,被 webpack-dev-server 及眾多其他包依賴的 webpack-dev-middleware 就是通過這種方式, 將你的文件神秘地隱藏起來,但卻仍然可以用它們?yōu)闉g覽器提供服務!


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號