Webpack ProvidePlugin vs esterni?

Sto esplorando l’idea di usare Webpack con Backbone.js .

Ho seguito la guida rapida e ho un’idea generale di come funziona Webpack, ma non sono chiaro su come caricare la libreria delle dipendenze come jquery / backbone / underscore.

Dovrebbero essere caricati esternamente con o è qualcosa che Webpack può gestire come lo shim di RequireJS?

Secondo il webpack doc: i moduli ProvidePlugin , ProvidePlugin e gli externals sembrano essere correlati a questo (quindi è bundle! Loader da qualche parte) ma non riesco a capire quando usare quale.

Grazie

È ansible entrambe: puoi includere le librerie con uno (cioè utilizzare una libreria da un CDN) o includerle nel pacchetto generato.

Se lo carichi tramite il tag , puoi usare l'opzione externals per consentire di scrivere require(...) nei tuoi moduli.

Esempio con libreria da CDN:

  // the artifial module "jquery" exports the global var "jQuery" externals: { jquery: "jQuery" } // inside any module var $ = require("jquery"); 

Esempio con libreria inclusa nel pacchetto:

 copy `jquery-git2.min.js` to your local filesystem // make "jquery" resolve to your local copy of the library // ie through the resolve.alias option resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } } // inside any module var $ = require("jquery"); 

ProvidePlugin può mappare i moduli alle variabili (gratuite). Quindi potresti definire: "Ogni volta che uso la variabile (libera) xyz all'interno di un modulo tu (webpack) dovresti impostare xyz per require("abc") ."

Esempio senza ProvidePlugin :

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

Esempio con ProvidePlugin :

 plugins: [ new webpack.ProvidePlugin({ "_": "underscore" }) ] // If you use "_", underscore is automatically required _.size(...) 

Sommario:

  • Libreria da CDN: usa l'opzione tag ed externals
  • Libreria dal filesystem: includi la libreria nel pacchetto. (Forse modificare le opzioni di resolve per trovare la libreria)
  • externals : rende disponibili le vars globali come modulo
  • ProvidePlugin : rende i moduli disponibili come variabili libere all'interno dei moduli

Qualcosa di interessante da notare è che se si utilizza ProvidePlugin in combinazione con la proprietà di externals ti permetterà di avere jQuery passato alla chiusura del tuo modulo webpack senza doverlo require esplicitamente. Questo può essere utile per il refactoring del codice legacy con molti file diversi che fanno riferimento a $ .

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

ora in index.js

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

avrà un output compilato con qualcosa di simile passato nella chiusura 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; /***/ } /******/ ]) 

Pertanto, puoi vedere che $ sta facendo riferimento al jQuery globale / della finestra dal CDN, ma viene passato alla chiusura. Non sono sicuro che si tratti di funzionalità o di un attacco fortunato, ma sembra funzionare bene per il mio caso d’uso.

So che questo è un vecchio post ma ho pensato che sarebbe utile menzionare che il loader di script webpack potrebbe essere utile anche in questo caso. Dai documenti del pacchetto web:

“script: esegue un file JavaScript una volta nel contesto globale (come nel tag dello script), non richiede l’analisi dei dati.”

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

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

Ho trovato questo particolarmente utile durante la migrazione di processi di compilazione più vecchi che concatenano file di fornitori JS e file di app. Un avvertimento è che il caricatore di script sembra funzionare solo tramite overloading require() e non funziona per quanto posso dire essendo specificato all’interno di un file webpack.config. Sebbene, molti sostengano che l’overloading require sia una ctriggers pratica, può essere abbastanza utile per conciliare lo script di fornitore e app in un unico bundle, esponendo allo stesso tempo JS Globals che non devono essere sparsi in bundle di webpack aggiuntivi. Per esempio:

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

Ciò renderebbe $ .cookie, storia e momento globalmente disponibili all’interno e all’esterno di questo pacchetto, e impacchettare queste librerie di fornitori con lo script main.js e tutti i suoi file richiesti.

Inoltre, utile con questa tecnica è:

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

che sta usando Bower, guarderà il file main in ogni pacchetto di librerie richieste d.json. Nell’esempio precedente, History.js non ha un file main specificato, quindi è necessario il percorso del file.