Externals

externals 設定オプションは、出力バンドルから依存関係を除外する方法を提供します。代わりに、作成されたバンドルは、コンシューマー (エンドユーザーアプリケーション) の環境にその依存関係が存在することを前提としています。この機能は、通常、ライブラリ開発者にとって最も便利ですが、さまざまなアプリケーションに利用できます。

externals

string object function RegExp [string, object, function, RegExp]

特定の import されたパッケージのバンドル化を防止し、代わりに実行時にこれらの外部依存関係を取得します。

たとえば、バンドルする代わりに CDN から jQuery を含めるには

index.html

<script
  src="https://code.jquery.com/jquery-3.1.0.js"
  integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
  crossorigin="anonymous"
></script>

webpack.config.js

module.exports = {
  //...
  externals: {
    jquery: 'jQuery',
  },
};

これにより、依存モジュールは変更されません。つまり、以下のコードは引き続き機能します。

import $ from 'jquery';

$('.my-element').animate(/* ... */);

上記の webpack.config.jsexternals で指定されたプロパティ名 jquery は、import $ from 'jquery' のモジュール jquery をバンドルから除外する必要があることを示します。このモジュールを置き換えるために、デフォルトの外部ライブラリタイプが var であるため、値 jQuery がグローバルな jQuery 変数を取得するために使用されます。 externalsType を参照してください。

上記では外部グローバル変数を使用する例を示しましたが、外部は実際には、グローバル変数、CommonJS、AMD、ES2015 モジュールなど、次のいずれかの形式で利用できます。詳細については、externalsType を参照してください。

string

externalsType によっては、これはグローバル変数 ( 'global''this''var''window' を参照) またはモジュール (amdcommonjsmoduleumd を参照) の名前である可能性があります。

外部を 1 つだけ定義する場合は、ショートカット構文も使用できます。

module.exports = {
  //...
  externals: 'jquery',
};

と同等

module.exports = {
  //...
  externals: {
    jquery: 'jquery',
  },
};

${externalsType} ${libraryName} 構文を使用して、外部の 外部ライブラリタイプ を指定できます。これにより、externalsType オプションで指定されたデフォルトの外部ライブラリタイプが上書きされます。

たとえば、外部ライブラリが CommonJS モジュールの場合、次のように指定できます。

module.exports = {
  //...
  externals: {
    jquery: 'commonjs jquery',
  },
};

[string]

module.exports = {
  //...
  externals: {
    subtract: ['./math', 'subtract'],
  },
};

subtract: ['./math', 'subtract'] を使用すると、モジュールの一部を選択できます。ここで、./math はモジュールであり、バンドルは subtract 変数下のサブセットのみを必要とします。

externalsTypecommonjs の場合、この例は require('./math').subtract; に変換され、externalsTypewindow の場合、この例は window["./math"]["subtract"]; に変換されます。

string 構文と同様に、配列の最初の項目で ${externalsType} ${libraryName} 構文を使用して外部ライブラリタイプを指定できます。たとえば、

module.exports = {
  //...
  externals: {
    subtract: ['commonjs ./math', 'subtract'],
  },
};

object

module.exports = {
  //...
  externals: {
    react: 'react',
  },

  // or

  externals: {
    lodash: {
      commonjs: 'lodash',
      amd: 'lodash',
      root: '_', // indicates global variable
    },
  },

  // or

  externals: {
    subtract: {
      root: ['math', 'subtract'],
    },
  },
};

この構文は、外部ライブラリが利用可能になる可能性のあるすべての方法を記述するために使用されます。ここでの lodash は、AMD および CommonJS モジュールシステムでは lodash として利用可能ですが、グローバル変数形式では _ として利用可能です。ここでの subtract は、グローバルな math オブジェクト (例: window['math']['subtract']) の下のプロパティ subtract を介して利用できます。

function

  • function ({ context, request, contextInfo, getResolve }, callback)
  • function ({ context, request, contextInfo, getResolve }) => promise 5.15.0+

webpack から外部化する内容の動作を制御するために、独自の関数を定義すると便利な場合があります。たとえば、webpack-node-externals は、node_modules ディレクトリからすべてのモジュールを除外して、許可リストパッケージを許可するオプションを提供します。

以下は、関数が受け取ることができる引数です

  • ctx (object): ファイルの詳細を含むオブジェクト。
    • ctx.context (string): インポートを含むファイルのディレクトリ。
    • ctx.request (string): 要求されているインポートパス。
    • ctx.contextInfo (object): 発行者 (レイヤーやコンパイラーなど) に関する情報が含まれています。
    • ctx.getResolve 5.15.0+: 現在のリゾルバーオプションを使用して resolve 関数を取得します。
  • callback (function (err, result, type)): モジュールをどのように外部化するかを示すために使用されるコールバック関数。

コールバック関数は 3 つの引数を取ります

  • err (Error): インポートの外部化中にエラーが発生した場合を示すために使用されます。エラーがある場合は、これのみが使用されるパラメーターである必要があります。
  • result (string [string] object): 他の外部形式 ( string[string]、または object) を使用して外部モジュールを記述します
  • type (string): モジュールの 外部タイプ を示すオプションのパラメーター (result パラメーターで既に示されていない場合)。

例として、インポートパスが正規表現に一致するすべてのインポートを外部化するには、次のようにすることができます。

webpack.config.js

module.exports = {
  //...
  externals: [
    function ({ context, request }, callback) {
      if (/^yourregex$/.test(request)) {
        // Externalize to a commonjs module using the request path
        return callback(null, 'commonjs ' + request);
      }

      // Continue without externalizing the import
      callback();
    },
  ],
};

異なるモジュール形式を使用するその他の例

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // The external is a `commonjs2` module located in `@scope/library`
      callback(null, '@scope/library', 'commonjs2');
    },
  ],
};

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // The external is a global variable called `nameOfGlobal`.
      callback(null, 'nameOfGlobal');
    },
  ],
};

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // The external is a named export in the `@scope/library` module.
      callback(null, ['@scope/library', 'namedexport'], 'commonjs');
    },
  ],
};

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // The external is a UMD module
      callback(null, {
        root: 'componentsGlobal',
        commonjs: '@scope/components',
        commonjs2: '@scope/components',
        amd: 'components',
      });
    },
  ],
};

RegExp

指定された正規表現に一致するすべての依存関係は、出力バンドルから除外されます。

webpack.config.js

module.exports = {
  //...
  externals: /^(jquery|\$)$/i,
};

この場合、名前が jQuery の依存関係 (大文字または小文字を区別しない) または $ は外部化されます。

構文の組み合わせ

上記の構文を組み合わせて使用したい場合があります。これは、次の方法で実行できます。

webpack.config.js

module.exports = {
  //...
  externals: [
    {
      // String
      react: 'react',
      // Object
      lodash: {
        commonjs: 'lodash',
        amd: 'lodash',
        root: '_', // indicates global variable
      },
      // [string]
      subtract: ['./math', 'subtract'],
    },
    // Function
    function ({ context, request }, callback) {
      if (/^yourregex$/.test(request)) {
        return callback(null, 'commonjs ' + request);
      }
      callback();
    },
    // Regex
    /^(jquery|\$)$/i,
  ],
};

この構成の使用方法の詳細については、ライブラリの作成方法に関する記事を参照してください。

byLayer

function object

レイヤーごとに外部化を指定します。

webpack.config.js

module.exports = {
  externals: {
    byLayer: {
      layer: {
        external1: 'var 43',
      },
    },
  },
};

externalsType

string = 'var'

外部のデフォルトタイプを指定します。amdumdsystem、および jsonp の外部は、output.libraryTarget が同じ値に設定されていることに依存します。たとえば、amd ライブラリ内でのみ amd 外部を使用できます。

サポートされているタイプ

webpack.config.js

module.exports = {
  //...
  externalsType: 'promise',
};

externalsType.commonjs

外部のデフォルトタイプを 'commonjs' として指定します。Webpack は、モジュールで使用される外部に対して const X = require('...') のようなコードを生成します。

import fs from 'fs-extra';

webpack.config.js

module.exports = {
  // ...
  externalsType: 'commonjs',
  externals: {
    'fs-extra': 'fs-extra',
  },
};

次のようなものが生成されます。

const fs = require('fs-extra');

出力バンドルに require() があることに注意してください。

externalsType.global

外部のデフォルトタイプを 'global' として指定します。Webpack は、globalObject のグローバル変数として外部を読み取ります。

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'global',
  externals: {
    jquery: '$',
  },
  output: {
    globalObject: 'global',
  },
};

次のようなものが生成されます。

const jq = global['$'];
jq('.my-element').animate(/* ... */);

externalsType.module

外部のデフォルトタイプを 'module' として指定します。Webpack は、モジュールで使用される外部に対して import * as X from '...' のようなコードを生成します。

experiments.outputModule を最初に有効にしてください。そうしないと、webpack はエラーをスローします。

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  experiments: {
    outputModule: true,
  },
  externalsType: 'module',
  externals: {
    jquery: 'jquery',
  },
};

次のようなものが生成されます。

import * as __WEBPACK_EXTERNAL_MODULE_jquery__ from 'jquery';

const jq = __WEBPACK_EXTERNAL_MODULE_jquery__['default'];
jq('.my-element').animate(/* ... */);

出力バンドルに import ステートメントがあることに注意してください。

externalsType.node-commonjs

外部のデフォルトタイプを 'node-commonjs' として指定します。Webpack は、モジュールで使用される外部をロードするための require 関数を構築するために、'module' から createRequire をインポートします。

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.export = {
  experiments: {
    outputModule: true,
  },
  externalsType: 'node-commonjs',
  externals: {
    jquery: 'jquery',
  },
};

次のようなものが生成されます。

import { createRequire } from 'module';

const jq = createRequire(import.meta.url)('jquery');
jq('.my-element').animate(/* ... */);

出力バンドルに import ステートメントがあることに注意してください。

externalsType.promise

外部のデフォルトタイプを 'promise' として指定します。Webpack は、外部をグローバル変数として ( 'var' と同様に) 読み取り、それを await します。

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'promise',
  externals: {
    jquery: '$',
  },
};

次のようなものが生成されます。

const jq = await $;
jq('.my-element').animate(/* ... */);

externalsType.self

外部のデフォルトタイプを 'self' として指定します。Webpack は、self オブジェクトのグローバル変数として外部を読み取ります。

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'self',
  externals: {
    jquery: '$',
  },
};

次のようなものが生成されます。

const jq = self['$'];
jq('.my-element').animate(/* ... */);

externalsType.script

外部のデフォルトタイプを 'script' として指定します。Webpack は、HTML <script> 要素を使用して、定義済みのグローバル変数を公開するスクリプトとして外部をロードします。<script> タグは、スクリプトがロードされた後に削除されます。

構文

module.exports = {
  externalsType: 'script',
  externals: {
    packageName: [
      'http://example.com/script.js',
      'global',
      'property',
      'property',
    ], // properties are optional
  },
};

プロパティを指定しない場合は、ショートカット構文も使用できます。

module.exports = {
  externalsType: 'script',
  externals: {
    packageName: 'global@http://example.com/script.js', // no properties here
  },
};

output.publicPath が指定された URL に追加されないことに注意してください。

CDNからlodashをロードしてみましょう。

webpack.config.js

module.exports = {
  // ...
  externalsType: 'script',
  externals: {
    lodash: ['https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js', '_'],
  },
};

そして、コードの中でそれを使います。

import _ from 'lodash';
console.log(_.head([1, 2, 3]));

上記例に対するプロパティの指定方法はこちらです。

module.exports = {
  // ...
  externalsType: 'script',
  externals: {
    lodash: [
      'https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js',
      '_',
      'head',
    ],
  },
};

lodashimportすると、ローカル変数headとグローバルなwindow._の両方が公開されます。

import head from 'lodash';
console.log(head([1, 2, 3])); // logs 1 here
console.log(window._.head(['a', 'b'])); // logs a here

externalsType.this

externalsのデフォルトの型を'this'として指定します。Webpackは、thisオブジェクト上のグローバル変数としてexternalsを読み取ります。

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'this',
  externals: {
    jquery: '$',
  },
};

次のようなものが生成されます。

const jq = this['$'];
jq('.my-element').animate(/* ... */);

externalsType.var

externalsのデフォルトの型を'var'として指定します。Webpackは、グローバル変数としてexternalsを読み取ります。

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'var',
  externals: {
    jquery: '$',
  },
};

次のようなものが生成されます。

const jq = $;
jq('.my-element').animate(/* ... */);

externalsType.window

externalsのデフォルトの型を'window'として指定します。Webpackは、windowオブジェクト上のグローバル変数としてexternalsを読み取ります。

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'window',
  externals: {
    jquery: '$',
  },
};

次のようなものが生成されます。

const jq = window['$'];
jq('.my-element').animate(/* ... */);

externalsPresets

object

特定のターゲットに対するexternalsのプリセットを有効にします。

オプション説明入力タイプ
electronメインコンテキストとプリロードコンテキストにおけるelectronipcshellのような一般的なelectron組み込みモジュールを外部モジュールとして扱い、使用時にrequire()経由でロードします。boolean
electronMainメインコンテキストにおけるappipc-mainshellのようなelectron組み込みモジュールを外部モジュールとして扱い、使用時にrequire()経由でロードします。boolean
electronPreloadプリロードコンテキストにおけるweb-frameipc-renderershellのようなelectron組み込みモジュールを外部モジュールとして扱い、使用時にrequire()経由でロードします。boolean
electronRendererレンダラーコンテキストにおけるweb-frameipc-renderershellのようなelectron組み込みモジュールを外部モジュールとして扱い、使用時にrequire()経由でロードします。boolean
nodefspathvmのようなnode.js組み込みモジュールを外部モジュールとして扱い、使用時にrequire()経由でロードします。boolean
nwjsNW.jsのレガシーなnw.guiモジュールを外部モジュールとして扱い、使用時にrequire()経由でロードします。boolean
webhttp(s)://...およびstd:...への参照を外部モジュールとして扱い、使用時にimport経由でロードします。(これにより、externalsはチャンク内の他のコードより先に実行されるため、実行順序が変わることに注意してください)boolean
webAsynchttp(s)://...およびstd:...への参照を外部モジュールとして扱い、使用時にasync import()経由でロードします。(この外部型はasyncモジュールであり、実行にさまざまな影響があることに注意してください)boolean

これらのnode.js関連のプリセットを使用してESモジュールを出力する場合、webpackはデフォルトのexternalsTypenode-commonjsに設定し、require()を使用する代わりにcreateRequireを使用してrequire関数を構築することに注意してください。

nodeプリセットを使用すると、組み込みモジュールはバンドルされず、外部モジュールとして扱われ、使用時にrequire()経由でロードされます。

webpack.config.js

module.exports = {
  // ...
  externalsPresets: {
    node: true,
  },
};

17 貢献者

sokraskipjackpksjcefadysamirsadekbyzykzefmanMistyyyyjamesgeorge007tanhauhausnitin315beejunkEugeneHlushkochenxsanpranshuchittorakinetifexanshumanvSaulSilver