Frage Webpack ProvidePlugin vs externe?


Ich erkunde die Idee des Verwendens Webpaket mit Backbone.js.

Ich habe die Kurzanleitung verfolgt und habe eine allgemeine Vorstellung davon, wie Webpack funktioniert, aber ich weiß nicht, wie man die Abhängigkeitsbibliothek wie jquery / backbone / underscore laden kann.

Sollten sie extern mit geladen werden <script> oder ist das etwas, was Webpack wie RequireJS's Shim handhaben kann?

Entsprechend der webpack doc: Shimming-Module, ProvidePlugin und externals scheinen damit verwandt zu sein (so ist es bundle! Loader irgendwo), aber ich kann nicht herausfinden, wann ich welche verwenden soll.

Vielen Dank


75
2018-04-26 01:39


Ursprung


Antworten:


Es ist beides möglich: Sie können Bibliotheken mit einbeziehen <script> (z. B. um eine Bibliothek von einem CDN zu verwenden) oder sie in das erzeugte Bündel aufzunehmen.

Wenn Sie es über laden <script> Tag, können Sie die verwenden externals Option zu erlauben, zu schreiben require(...) in deinen Modulen.

Beispiel mit Bibliothek aus 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");

Beispiel mit Bibliothek im Bundle enthalten:

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");

Das ProvidePlugin kann Module auf (freie) Variablen abbilden. So könnten Sie definieren: "Jedes Mal wenn ich die (freie) Variable verwende xyz Innerhalb eines Moduls sollte man (Webpack) einstellen xyz zu require("abc"). "

Beispiel ohne ProvidePlugin:

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

Beispiel mit ProvidePlugin:

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

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

Zusammenfassung:

  • Bibliothek von CDN: Verwenden <script> Tag und externals Möglichkeit
  • Bibliothek aus Dateisystem: Fügen Sie die Bibliothek in das Paket ein. (Vielleicht modifizieren resolve Optionen, um die Bibliothek zu finden)
  • externals: Stellen Sie globale Variablen als Modul zur Verfügung
  • ProvidePlugin: Stellen Sie Module als freie Variablen innerhalb von Modulen zur Verfügung

139
2018-04-29 19:58



Etwas cooles zu beachten ist, dass wenn Sie das verwenden ProvidePlugin in Kombination mit der externals Eigentum wird es Ihnen erlauben zu haben jQuery in Ihren Webpack-Modul-Abschluss ohne explizit zu übergeben require es. Dies kann zum Refactoring von Legacy-Code mit vielen verschiedenen Referenzdateien nützlich sein $.

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

jetzt in index.js

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

Ich habe eine kompilierte Ausgabe mit etwas wie unten in die webpackBootstrap Schließung:

/******/ ([
/* 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;

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

Daher können Sie das sehen $ verweist auf das globale / Fenster jQuery aus dem CDN, wird aber in die Schließung weitergeleitet. Ich bin mir nicht sicher, ob dies die beabsichtigte Funktionalität oder ein glücklicher Hack ist, aber es scheint gut für meinen Anwendungsfall zu funktionieren.


21
2018-06-02 04:18



Ich weiß, das ist ein alter Post, aber ich denke, es wäre nützlich zu erwähnen, dass der Webpack-Skriptlader auch in diesem Fall nützlich sein könnte. Aus den Webpack-Dokumenten:

"script: Führt eine JavaScript-Datei einmal im globalen Kontext aus (wie im Skript-Tag), Requests werden nicht analysiert."

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

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

Ich fand dies besonders nützlich, wenn ältere Build-Prozesse migriert werden, die JS-Herstellerdateien und Anwendungsdateien zusammenführen. Ein Warnhinweis ist, dass der Skriptlader nur durch Überladen funktioniert require() und funktioniert nicht so weit, wie ich sagen kann, indem es in einer Datei webpack.config angegeben wird. Obwohl viele argumentieren, dass Überlastung requireist eine schlechte Übung, kann es sehr nützlich sein, wenn Sie Vendor- und App-Skript in einem Bundle zusammenfassen und gleichzeitig JS-Globals, die nicht in zusätzliche Webpack-Bundles eingefügt werden müssen, verfügbar machen. Beispielsweise:

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

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

Dies würde $ .cookie, History und moment global innerhalb und außerhalb dieses Bundles verfügbar machen und diese Vendor-Bibliotheken mit dem main.js-Skript und allem, was es ist, bündeln required Dateien.

Auch nützlich bei dieser Technik ist:

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

welches Bower benutzt, wird auf die aussehen main Datei in jedem required Bibliotheken package.json. Im obigen Beispiel hat History.js kein a main Datei angegeben, so dass der Pfad zu der Datei erforderlich ist.


11
2018-01-25 22:14