Webpack ProvidePluginと外部?


84

Backbone.jsでWebpackを使用するというアイデアを模索しています。

クイックスタートガイドに従い、Webpackがどのように機能するかについての一般的な考え方はありますが、jquery /バックボーン/アンダースコアなどの依存関係ライブラリをロードする方法がわかりません。

それらを外部にロードする<script>必要がありますか、それともWebpackがRequireJSのシムのように処理できるものですか?

よるとWebPACKのドキュメント:モジュールをシミングProvidePluginおよびexternalsこれに関連すると思われる(そうであるbundle!ローダどこか)が、私は使用する際に把握することはできません。

ありがとう

回答:


153

両方の可能性があります。ライブラリを<script>(つまり、CDNのライブラリを使用するために)インクルードするか、生成されたバンドルにインクルードすることができます。

<script>タグを介してロードする場合は、externalsオプションを使用require(...)してモジュールへの書き込みを許可できます。

CDNのライブラリを使用した例:

<script src="https://code.jquery.com/jquery-git2.min.js"></script>

// the artifial module "jquery" exports the global var "jQuery"
externals: { jquery: "jQuery" }

// inside any module
var $ = require("jquery");

ライブラリがバンドルに含まれている例:

copy `jquery-git2.min.js` to your local filesystem

// make "jquery" resolve to your local copy of the library
// i. e. through the resolve.alias option
resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } }

// inside any module
var $ = require("jquery");

ProvidePlugin(無料)の変数にモジュールをマップすることができます。したがって、次のように定義できます。「xyzモジュール内で(自由)変数を使用するたびに、(webpack)を設定xyzする必要がありrequire("abc")ます。」

なしの例ProvidePlugin

// You need to require underscore before you can use it
var _ = require("underscore");
_.size(...);

ProvidePlugin

plugins: [
  new webpack.ProvidePlugin({
    "_": "underscore"
  }) 
]

// If you use "_", underscore is automatically required
_.size(...)

概要:

  • CDNのライブラリ:<script>タグとexternalsオプションを使用
  • ファイルシステムからのライブラリ:ライブラリをバンドルに含めます。(resolveライブラリを見つけるためにオプションを変更するかもしれません)
  • externals:グローバル変数をモジュールとして使用可能にする
  • ProvidePlugin:モジュールをモジュール内の自由変数として利用できるようにする


スクリプトローダーを使用しないのはなぜですか?@dtothefpが説明したように、これははるかに簡単です
timaschew 2016

webpack.configファイルがjavascriptというフォルダーにあり、その中にベンダーというフォルダーがあり、jqueryファイルが含まれています。パスはそうではありません。解決:{エイリアス:{jquery: "vendor /jquery-1.10.2.js"}}。エイリアスを使用してもまだ機能しません
me-me

3
エイリアスオプションに絶対パスを渡すだけです。相対パスを渡すと、webpack1のrequire / importの場所からの相対パスになります。webpack2では、webpack.config.jsファイルの相対パスになります。コンテキストオプション。
Tobias K.

@TobiasK。絶対パスはデフォルトのエクスポートと連携しません。ファイルでは{__esModule: true, default: MY_DEFAULT_EXPORT}なくオブジェクトを取得MY_DEFAULT_EXPORTしています。
mgol 2016

25

プロパティとProvidePlugin組み合わせて使用すると、明示的にすることなくwebpackモジュールクロージャーに渡すexternalsことができることにjQuery注意してください。requireし。これは、を参照する多くの異なるファイルを使用してレガシーコードをリファクタリングする場合に役立ちます$

//webpack.config.js
module.exports = {
  entry: './index.js',
  output: { 
    filename: '[name].js' 
  },
  externals: {
    jquery: 'jQuery'
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
    })
  ]
};

今index.jsに

console.log(typeof $ === 'function');

以下のようなものがwebpackBootstrapクロージャーに渡されたコンパイル済み出力があります。

/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    /* WEBPACK VAR INJECTION */(function($) {
        console.log(typeof $ === 'function');

    /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

    module.exports = jQuery;

/***/ }
/******/ ])

したがって、それ$jQueryCDNからグローバル/ウィンドウを参照しているが、クロージャーに渡されていることがわかります。これが意図された機能なのかラッキーハックなのかはわかりませんが、私のユースケースではうまく機能しているようです。


あなたがそれに行かなければ、あなたはどちらのプラグインも必要としませんでしrequire/importた。$何があってもグローバルスコープに到達するので、うまくいくでしょう。ProviderPluginそれは高価なプラグインですので、ASTを解析する必要があり、著しくビルド時に追加されます。つまり、基本的には無駄です。
faceyspacey.com 2018

@dtohefpこの答えは天の恵みです。モジュールを外部に追加しない限りProvidePlugin、なぜのようなオブジェクトが返されたのか説明できますmyModule.defaultか?直接的な関係があるとは思ってもみませんでした。
Slbox

11

私はこれが古い投稿であることを知っていますが、webpackスクリプトローダーがこの場合にも役立つ可能性があることを言及することは有用だと思いました。webpackドキュメントから:

「スクリプト:JavaScriptファイルをグローバルコンテキストで1回実行します(スクリプトタグのように)。requiresは解析されません。」

http://webpack.github.io/docs/list-of-loaders.html

https://github.com/webpack/script-loader

これは、JSベンダーファイルとアプリファイルを連結する古いビルドプロセスを移行するときに特に便利です。警告の言葉は、スクリプトローダーはオーバーロードrequire()を介してのみ機能するようであり、webpack.configファイル内で指定されていることで私が知る限りは機能しないということです。オーバーロードrequireは悪い習慣であると多くの人が主張していますが、ベンダーとアプリのスクリプトを1つのバンドルにまとめると同時に、追加のWebpackバンドルにシムする必要のないJSグローバルを公開するのに非常に役立ちます。例えば:

require('script!jquery-cookie/jquery.cookie');
require('script!history.js/scripts/bundled-uncompressed/html4+html5/jquery.history');
require('script!momentjs');

require('./scripts/main.js');

これにより、$。cookie、履歴、およびモーメントがこのバンドルの内外でグローバルに利用可能になり、これらのベンダーライブラリがmain.jsスクリプトとそのすべてにバンドルされます。 requiredファイルにます。

また、この手法で役立つのは次のとおりです。

resolve: {
  extensions: ["", ".js"],
  modulesDirectories: ['node_modules', 'bower_components']
},
plugins: [
  new webpack.ResolverPlugin(
    new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
   )
]

Bowerを使用している場合はmain、各requiredライブラリpackage.json内のファイルを確認します。上記の例では、History.jsにmainファイルが指定されていないため、ファイルへのパスが必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.