Gestione della dipendenza del plugin jQuery nel webpack

Sto usando Webpack nella mia applicazione, in cui creo due punti di accesso: bundle.js per tutti i miei file / codici JavaScript e vendors.js per tutte le librerie come jQuery e React. Cosa faccio per usare plugin che hanno jQuery come dipendenze e voglio averli anche in vendors.js? Cosa succede se questi plugin hanno più dipendenze?

Attualmente sto cercando di utilizzare questo plugin jQuery qui: https://github.com/mbklein/jquery-elastic . La documentazione di Webpack menziona providePlugin e imports -loader. Ho usato providePlugin, ma l’object jQuery non è ancora disponibile. Ecco come appare il mio webpack.config.js-

var webpack = require('webpack'); var bower_dir = __dirname + '/bower_components'; var node_dir = __dirname + '/node_modules'; var lib_dir = __dirname + '/public/js/libs'; var config = { addVendor: function (name, path) { this.resolve.alias[name] = path; this.module.noParse.push(new RegExp(path)); }, plugins: [ new webpack.ProvidePlugin({ $: "jquery", jquery: "jQuery", "window.jQuery": "jquery" }), new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity) ], entry: { app: ['./public/js/main.js'], vendors: ['react','jquery'] }, resolve: { alias: { 'jquery': node_dir + '/jquery/dist/jquery.js', 'jquery.elastic': lib_dir + '/jquery.elastic.source.js' } }, output: { path: './public/js', filename: 'bundle.js' }, module: { loaders: [ { test: /\.js$/, loader: 'jsx-loader' }, { test: /\.jquery.elastic.js$/, loader: 'imports-loader' } ] } }; config.addVendor('react', bower_dir + '/react/react.min.js'); config.addVendor('jquery', node_dir + '/jquery/dist/jquery.js'); config.addVendor('jquery.elastic', lib_dir +'/jquery.elastic.source.js'); module.exports = config; 

Ma nonostante ciò, genera ancora un errore nella console del browser:

Uncaught ReferenceError: jQuery non è definito

Allo stesso modo, quando utilizzo il caricatore di importazioni, genera un errore,

richiedere non è definito ‘

in questa linea:

 var jQuery = require("jquery") 

Tuttavia, potrei usare lo stesso plug-in quando non lo aggiungo al mio file vendors.js e invece lo richiedevo nel normale modo AMD come se includessi i miei altri file di codice JavaScript, come-

 define( [ 'jquery', 'react', '../../common-functions', '../../libs/jquery.elastic.source' ],function($,React,commonFunctions){ $("#myInput").elastic() //It works }); 

Ma questo non è quello che voglio fare, poiché ciò significherebbe che jquery.elastic.source.js è in bundle insieme al mio codice JavaScript in bundle.js, e voglio che tutti i miei plugin jQuery siano nel bundle vendors.js. Quindi, come faccio a raggiungere questo?

Hai mescolato diversi approcci su come includere i moduli dei fornitori precedenti. Ecco come lo affronterei:

1. Preferire CommonJS / AMD non risolto su dist

La maggior parte dei moduli collega la versione dist nel campo main del loro package.json . Mentre questo è utile per la maggior parte degli sviluppatori, per il webpack è meglio fare l’alias della versione di src perché in questo modo webpack è in grado di ottimizzare le dipendenze meglio (ad esempio quando si usa DedupePlugin ).

 // webpack.config.js module.exports = { ... resolve: { alias: { jquery: "jquery/src/jquery" } } }; 

Tuttavia, nella maggior parte dei casi anche la versione dist funziona bene.


2. Utilizzare ProvidePlugin per iniettare globali implicite

La maggior parte dei moduli legacy si basa sulla presenza di elementi globali specifici, come i plugin jQuery su $ o jQuery . In questo scenario puoi configurare webpack, per anteporre var $ = require("jquery") ogni volta che incontra l’identificatore $ globale.

 var webpack = require("webpack"); ... plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ] 

3. Usa import-loader per configurarlo

Alcuni moduli precedenti si basano sul fatto che this è l’object window . Questo diventa un problema quando il modulo viene eseguito in un contesto CommonJS dove this uguale a module.exports . In questo caso puoi sovrascriverlo con il caricatore di importazioni .

Esegui npm i imports-loader --save-dev e poi

 module: { loaders: [ { test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/, loader: "imports-loader?this=>window" } ] } 

Il caricatore di importazioni può anche essere utilizzato per iniettare manualmente variabili di tutti i tipi. Ma la maggior parte delle volte ProvidePlugin è più utile quando si tratta di globali impliciti.


4. Usa il caricatore di importazioni per disabilitare AMD

Ci sono moduli che supportano diversi stili di moduli, come AMD, CommonJS e legacy. Tuttavia, la maggior parte delle volte prima verifica la define e quindi usa un codice bizzarro per esportare le proprietà. In questi casi, potrebbe essere utile forzare il percorso CommonJS impostando define = false .

 module: { loaders: [ { test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/, loader: "imports-loader?define=>false" } ] } 

5. Utilizzare lo script-loader per importare gli script a livello globale

Se non ti preoccupi delle variabili globali e vuoi solo che gli script legacy funzionino, puoi anche utilizzare il programma di caricamento degli script. Esegue il modulo in un contesto globale, proprio come se li avessi inclusi tramite il tag .


6. Usa noParse per includere grandi distanze

Quando non esiste una versione AMD / CommonJS del modulo e si desidera includere la dist , è ansible contrassegnare questo modulo come noParse . Quindi il webpack includerà semplicemente il modulo senza analizzarlo, che può essere usato per migliorare i tempi di compilazione. Ciò significa che qualsiasi funzione che richiede AST , come ProvidePlugin , non funzionerà.

 module: { noParse: [ /[\/\\]node_modules[\/\\]angular[\/\\]angular\.js$/ ] } 

Per l’accesso globale a jquery esistono diverse opzioni. Nel mio più recente progetto webpack, volevo l’accesso globale a jquery, quindi ho aggiunto quanto segue alle dichiarazioni dei miei plugin:

  plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ] 

Ciò significa quindi che jquery è accessibile dall’interno del codice sorgente JavaScript tramite riferimenti globali $ e jQuery.

Naturalmente, è necessario aver installato jquery tramite npm:

 $ npm i jquery --save 

Per un esempio funzionante di questo approccio, non esitare a inserire la mia app su github

Non so se capisco molto bene cosa stai cercando di fare, ma ho dovuto usare i plugin jQuery che richiedevano jQuery per essere nel contesto globale (finestra) e ho inserito quanto segue nel mio entry.js :

 var $ = require('jquery'); window.jQuery = $; window.$ = $; 

Devo solo richiedere dove voglio jqueryplugin.min.js e window.$ È esteso con il plugin come previsto.

Aggiungi questo al tuo array di plugin in webpack.config.js

 new webpack.ProvidePlugin({ 'window.jQuery': 'jquery', 'window.$': 'jquery', }) 

quindi richiede jquery normalmente

 require('jquery'); 

Se il dolore persiste nell’ottenere altri script per vederlo, prova a inserirlo esplicitamente nel contesto globale tramite (nella voce js)

 window.$ = jQuery; 

Ho funzionato bene mentre esponevo $ e jQuery come variabili globali con Webpack 3.8.1 e quanto segue.

Installa jQuery come dipendenza del progetto. Puoi omettere @3.2.1 per installare la versione più recente o specificare un’altra versione.

 npm install --save jquery@3.2.1 

Installare expose-loader come dipendenza di sviluppo se non è già installato.

 npm install expose-loader --save-dev 

Configura Webpack per caricare ed esporre jQuery per noi.

 // webpack.config.js const webpack = require('webpack') module.exports = { entry: [ // entry bits ], output: { // output bits }, module: { rules: [ // any other rules { // Exposes jQuery for use outside Webpack build test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' },{ loader: 'expose-loader', options: '$' }] } ] }, plugins: [ // Provides jQuery for other JS bundled with Webpack new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }) ] } 

Funziona nel webpack 3:

nel file webpack.config.babel.js:

 resolve: { alias: { jquery: "jquery/src/jquery" }, .... } 

E usa ProvidePlugin

 new webpack.ProvidePlugin({ '$': 'jquery', 'jQuery': 'jquery', }) 

Ho provato alcune delle risposte fornite ma nessuna sembrava funzionare. Allora ho provato questo:

 new webpack.ProvidePlugin({ 'window.jQuery' : 'jquery', 'window.$' : 'jquery', 'jQuery' : 'jquery', '$' : 'jquery' }); 

Sembra funzionare a prescindere dalla versione che sto usando

La soluzione migliore che ho trovato è stata:

https://github.com/angular/angular-cli/issues/5139#issuecomment-283634059

Fondamentalmente, devi includere una variabile dummy su typings.d.ts, rimuovere qualsiasi “importazione * come $ da” jquery “dal tuo codice e quindi aggiungere manualmente un tag allo script jQuery sul tuo html SPA. In questo modo, il webpack non sarà sulla tua strada e dovresti essere in grado di accedere alla stessa variabile globale jQuery in tutti i tuoi script.

Questo funziona per me sul webpack.config.js

  new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' }), 

in un altro javascript o in HTML aggiungi:

 global.jQuery = require('jquery'); 

Modifica: A volte si desidera utilizzare Webpack semplicemente come un modulo di raggruppamento per un semplice progetto Web – per mantenere organizzato il proprio codice. La seguente soluzione è per coloro che desiderano semplicemente una libreria esterna che funzioni come previsto all’interno dei propri moduli, senza impiegare molto tempo per l’immersione nelle configurazioni del Webpack. (Modificato dopo -1)

Soluzione rapida e semplice (es6) se si è ancora in difficoltà o si desidera evitare la configurazione esterna di configurazione config / webpack aggiuntivo:

     

all’interno di un modulo:

 const { jQuery: $, Underscore: _, etc } = window; 

Nel tuo file webpack.config.js aggiungi sotto:

  var webpack = require("webpack"); plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ], 

Installa jQuery usando npm:

 $ npm i jquery --save 

Nel file app.js aggiungi le seguenti righe:

 import $ from 'jquery'; window.jQuery = $; window.$ = $; 

Questo ha funzionato per me. 🙂