Come raggruppare separatamente gli script del fornitore e richiederli come necessario con Webpack?

Sto cercando di fare qualcosa che ritengo dovrebbe essere ansible, ma non riesco davvero a capire come farlo solo dalla documentazione del webpack.

Sto scrivendo una libreria JavaScript con diversi moduli che possono o meno dipendere l’uno dall’altro. Inoltre, jQuery viene utilizzato da tutti i moduli e alcuni di essi potrebbero richiedere plug-in jQuery. Questa libreria verrà quindi utilizzata in diversi siti Web che potrebbero richiedere alcuni o tutti i moduli.

Definire le dipendenze tra i miei moduli era molto semplice, ma la definizione delle loro dipendenze di terze parti sembra essere più difficile di quanto mi aspettassi.

Cosa mi piacerebbe ottenere : per ogni app voglio avere due file bundle uno con le dipendenze di terze parti necessarie e altri con i moduli necessari dalla mia libreria.

Esempio : immaginiamo che la mia libreria abbia i seguenti moduli:

  • a (richiede: jquery, jquery.plugin1)
  • b (richiede: jquery, a)
  • c (richiede: jquery, jquery.ui, a, b)
  • d (richiede: jquery, jquery.plugin2, a)

E ho un’app (vederla come un file di immissione univoco) che richiede i moduli a, be c. Webpack per questo caso dovrebbe generare i seguenti file:

  • bundle del fornitore : con jquery, jquery.plugin1 e jquery.ui;
  • bundle del sito Web : con i moduli a, b e c;

Alla fine, preferirei avere jQuery come globale, quindi non ho bisogno di richiederlo su ogni singolo file (potrei richiederlo solo sul file principale, per esempio). E i plugin jQuery estenderebbero il $ globale nel caso in cui fossero richiesti (non è un problema se sono disponibili per altri moduli che non ne hanno bisogno).

Supponendo che questo sia ansible, quale sarebbe un esempio di un file di configurazione del webpack per questo caso? Ho provato diverse combinazioni di caricatori, periferiche esterne e plug-in sul mio file di configurazione, ma non riesco davvero a capire cosa stanno facendo e quali dovrei usare. Grazie!

nel mio file webpack.config.js (versione 1,2,3), ho

function isExternal(module) { var context = module.context; if (typeof context !== 'string') { return false; } return context.indexOf('node_modules') !== -1; } 

nel mio array di plugin

 plugins: [ new CommonsChunkPlugin({ name: 'vendors', minChunks: function(module) { return isExternal(module); } }), // Other plugins ] 

Ora ho un file che aggiunge solo librerie di terze parti a un file come richiesto.

Se vuoi diventare più granulare dove separi i tuoi fornitori e i tuoi file entry point:

 plugins: [ new CommonsChunkPlugin({ name: 'common', minChunks: function(module, count) { return !isExternal(module) && count >= 2; // adjustable } }), new CommonsChunkPlugin({ name: 'vendors', chunks: ['common'], // or if you have an key value object for your entries // chunks: Object.keys(entry).concat('common') minChunks: function(module) { return isExternal(module); } }) ] 

Nota che l’ordine dei plugin conta molto.

Inoltre, questo cambierà nella versione 4. Quando è ufficiale, aggiorno questa risposta.

Aggiornamento: indexOf cambio di ricerca per utenti Windows

Non sono sicuro di comprendere appieno il problema, ma poiché ho avuto problemi simili recentemente cercherò di aiutarti.

Pacchetto fornitore.

Dovresti usare CommonsChunkPlugin per quello. nella configurazione si specifica il nome del blocco (ad es. vendor ) e il nome del file che verrà generato ( vendor.js ).

 new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity), 

Ora una parte importante, ora devi specificare cosa significa libreria del vendor e lo fai in una sezione di voce. Un altro elemento per l’elenco di voci con lo stesso nome del nuovo chunk dichiarato (ad es. “Venditore” in questo caso). Il valore di tale voce dovrebbe essere l’elenco di tutti i moduli che si desidera spostare nel bundle del vendor . nel tuo caso dovrebbe assomigliare a qualcosa:

 entry: { app: 'entry.js', vendor: ['jquery', 'jquery.plugin1'] } 

JQuery come globale

Ho avuto lo stesso problema e l’ho risolto con ProvidePlugin . qui non si sta definendo un object globale ma una sorta di shurtcuts ai moduli. cioè puoi configurarlo in questo modo:

 new webpack.ProvidePlugin({ $: "jquery" }) 

E ora puoi semplicemente usare $ ovunque nel tuo codice – il webpack lo convertirà automaticamente in

 require('jquery') 

Spero che sia stato d’aiuto. puoi anche guardare il mio file di configurazione del webpack che è qui

Adoro il webpack, ma sono d’accordo sul fatto che la documentazione non sia la più bella del mondo … ma hey … la gente stava dicendo la stessa cosa sulla documentazione Angular all’inizio 🙂


Modificare:

Per avere porzioni di fornitori specifici per un punto di accesso è sufficiente utilizzare CommonsChunkPlugins più volte:

 new webpack.optimize.CommonsChunkPlugin("vendor-page1", "vendor-page1.js", Infinity), new webpack.optimize.CommonsChunkPlugin("vendor-page2", "vendor-page2.js", Infinity), 

e quindi dichiarare diverse librerie extenral per file diversi:

 entry: { page1: ['entry.js'], page2: ['entry2.js'], "vendor-page1": [ 'lodash' ], "vendor-page2": [ 'jquery' ] }, 

Se alcune librerie si sovrappongono (e per la maggior parte di esse) tra i punti di ingresso, puoi estrarle in un file comune usando lo stesso plug-in solo con configurazioni diverse. Vedi questo esempio.

Nel caso tu sia interessato a raggruppare automaticamente i tuoi script separatamente da quelli dei fornitori:

 var webpack = require('webpack'), pkg = require('./package.json'), //loads npm config file html = require('html-webpack-plugin'); module.exports = { context : __dirname + '/app', entry : { app : __dirname + '/app/index.js', vendor : Object.keys(pkg.dependencies) //get npm vendors deps from config }, output : { path : __dirname + '/dist', filename : 'app.min-[hash:6].js' }, plugins: [ //Finally add this line to bundle the vendor code separately new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.min-[hash:6].js'), new html({template : __dirname + '/app/index.html'}) ] }; 

Puoi leggere ulteriori informazioni su questa funzionalità nella documentazione ufficiale .

Inoltre, non sono sicuro di comprendere appieno il tuo caso, ma qui è config snippet per creare blocchi separati del fornitore per ciascuno dei tuoi bundle:

 entry: { bundle1: './build/bundles/bundle1.js', bundle2: './build/bundles/bundle2.js', 'vendor-bundle1': [ 'react', 'react-router' ], 'vendor-bundle2': [ 'react', 'react-router', 'flummox', 'immutable' ] }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'vendor-bundle1', chunks: ['bundle1'], filename: 'vendor-bundle1.js', minChunks: Infinity }), new webpack.optimize.CommonsChunkPlugin({ name: 'vendor-bundle2', chunks: ['bundle2'], filename: 'vendor-bundle2-whatever.js', minChunks: Infinity }), ] 

E collega ai documenti CommonsChunkPlugin : http://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin