Ich verwende Webpack in meiner Anwendung, in der ich zwei Einstiegspunkte erstelle: bundle.js für alle meine JavaScript-Dateien / -Codes und vendor.js für alle Bibliotheken wie jQuery und React. Was mache ich, um Plugins zu verwenden, deren Abhängigkeiten jQuery sind, und ich möchte sie auch in vendor.js haben? Was ist, wenn diese Plugins mehrere Abhängigkeiten haben?
Derzeit versuche ich, dieses jQuery-Plugin hier zu verwenden - https://github.com/mbklein/jquery-elastic . In der Webpack-Dokumentation werden ProvidePlugin und Imports-Loader erwähnt. Ich habe requirePlugin verwendet, aber das jQuery-Objekt ist immer noch nicht verfügbar. So sieht meine webpack.config.js aus:
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;
Trotzdem wird immer noch ein Fehler in der Browserkonsole ausgegeben:
Nicht erfasster ReferenceError: jQuery ist nicht definiert
Wenn ich den Import-Loader verwende, wird ebenfalls ein Fehler ausgegeben:
erfordern ist nicht definiert '
in dieser Zeile:
var jQuery = require("jquery")
Ich könnte jedoch dasselbe Plugin verwenden, wenn ich es nicht zu meiner Datei vendor.js hinzufüge und es stattdessen auf normale AMD-Weise benötige, wie ich meine anderen JavaScript-Codedateien einbinde, wie z.
define(
[
'jquery',
'react',
'../../common-functions',
'../../libs/jquery.elastic.source'
],function($,React,commonFunctions){
$("#myInput").elastic() //It works
});
Dies ist jedoch nicht das, was ich tun möchte, da dies bedeuten würde, dass jquery.elastic.source.js zusammen mit meinem JavaScript-Code in bundle.js gebündelt wird und ich möchte, dass alle meine jQuery-Plugins im Bundles vendor.js enthalten sind. Wie gehe ich vor, um dies zu erreichen?
quelle
Antworten:
Sie haben verschiedene Ansätze zum Einbeziehen älterer Anbietermodule gemischt. So würde ich es angehen:
1. Bevorzugen Sie nicht minimiertes CommonJS / AMD gegenüber
dist
Die meisten Module verknüpfen die
dist
Version immain
Bereich ihrerpackage.json
. Während dies für die meisten Entwickler nützlich ist, ist es für Webpack besser, diesrc
Version zu aliasen, da Webpack auf diese Weise Abhängigkeiten besser optimieren kann (z. B. bei Verwendung vonDedupePlugin
).In den meisten Fällen
dist
funktioniert die Version jedoch auch einwandfrei.2. Verwenden Sie die
ProvidePlugin
, um implizite Globals zu injizierenDie meisten Legacy-Module basieren auf dem Vorhandensein bestimmter globaler Module, wie dies bei jQuery-Plugins auf
$
oder der Fall istjQuery
. In diesem Szenario können Sie das Webpack so konfigurieren,var $ = require("jquery")
dass es jedes Mal vorangestellt wird, wenn es auf die globale$
Kennung trifft .3. Konfigurieren Sie mit dem Import-Loader
this
Einige ältere Module sind darauf angewiesen
this
, daswindow
Objekt zu sein. Dies wird zu einem Problem, wenn das Modul in einem CommonJS-Kontext ausgeführt wird, in demthis
gleich istmodule.exports
. In diesem Fall können Siethis
mit dem Import-Loader überschreiben .Lauf
npm i imports-loader --save-dev
und dannDer Import-Loader kann auch zum manuellen Einfügen von Variablen aller Art verwendet werden. Aber meistens
ProvidePlugin
ist das nützlicher, wenn es um implizite Globale geht.4. Deaktivieren Sie AMD mit dem Import-Loader
Es gibt Module, die verschiedene Modulstile unterstützen, wie AMD, CommonJS und Legacy. Meistens suchen sie jedoch zuerst nach
define
etwas eigenartigem Code, um Eigenschaften zu exportieren, und verwenden ihn dann. In diesen Fällen kann es hilfreich sein, den CommonJS-Pfad durch Festlegen zu erzwingendefine = false
.5. Verwenden Sie den Script-Loader , um Skripte global zu importieren
Wenn Sie sich nicht für globale Variablen interessieren und nur möchten, dass ältere Skripte funktionieren, können Sie auch den Script-Loader verwenden. Es führt das Modul in einem globalen Kontext aus, als hätten Sie es über das
<script>
Tag eingefügt.6. Verwenden Sie
noParse
diese Option, um große Entfernungen einzuschließenWenn es keine AMD / CommonJS-Version des Moduls gibt und Sie die einschließen möchten
dist
, können Sie dieses Modul als kennzeichnennoParse
. Dann enthält das Webpack nur das Modul, ohne es zu analysieren, wodurch die Erstellungszeit verbessert werden kann. Dies bedeutet, dass Funktionen, für die AST erforderlich ist , wie z. B. dieProvidePlugin
, nicht funktionieren.quelle
ProvidePlugin
wird auf alle Vorkommen der angegebenen Bezeichner in allen Dateien angewendet. Dasimports-loader
kann nur auf bestimmte Dateien angewendet werden, Sie sollten jedoch nicht beide für dieselben Variablen / Abhängigkeiten verwenden.$
Variablen abhängen ."module": { "loaders": [ { test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" },
und es hat gut funktioniert.Für den globalen Zugriff auf jquery stehen mehrere Optionen zur Verfügung. In meinem letzten Webpack-Projekt wollte ich globalen Zugriff auf jquery, daher habe ich meinen Plugins-Deklarationen Folgendes hinzugefügt:
Dies bedeutet dann, dass auf jquery aus dem JavaScript-Quellcode über die globalen Referenzen $ und jQuery zugegriffen werden kann.
Natürlich müssen Sie jquery auch über npm installiert haben:
Ein funktionierendes Beispiel für diesen Ansatz finden Sie in meiner App auf Github
quelle
ProvidePlugin
Ihnen vorgeschlagene Lösung bereits vorgeschlagen wurde?./~/jQuery/dist/jquery.js There is another module with an equal name when case is ignored.
und die gleiche mit./~/jquery/dist/jquery.js
'window.jQuery': 'jquery'
dieser Liste hinzufügen , damit das Paket ms-signalr-client npm geladen wurde. Ich habe auch'window.$': 'jquery'
für ein gutes Maß eingesetzt :)Ich weiß nicht, ob ich sehr gut verstehe, was Sie versuchen, aber ich musste jQuery-Plugins verwenden, für die jQuery im globalen Kontext (Fenster) sein musste, und ich habe Folgendes in mein
entry.js
:Das muss ich nur benötigen wo immer ich will
jqueryplugin.min.js
undwindow.$
wird wie erwartet mit dem Plugin erweitert.quelle
Ich habe Dinge gut arbeiten , während auszusetzen
$
undjQuery
als globale Variablen mit Webpack 3.8.1 und den folgenden.Installieren Sie jQuery als Projektabhängigkeit. Sie können die
@3.2.1
Installation der neuesten Version unterlassen oder eine andere Version angeben.Installieren Sie
expose-loader
als Entwicklungsabhängigkeit , wenn nicht bereits installiert ist .Konfigurieren Sie Webpack so, dass jQuery für uns geladen und verfügbar gemacht wird.
quelle
expose-loader
müssen, damit es richtig funktioniertnpm install expose-loader --save-dev
expose-loaded
hat es für mich getan. Ich habe beim Kompilieren keinen Fehler erhalten, aber in Chrome-Entwicklertools. Das ist jetzt gelöst.Fügen Sie dies Ihrem Plugins-Array in webpack.config.js hinzu
dann benötigen Sie normalerweise jquery
Wenn der Schmerz weiterhin besteht, dass andere Skripte es sehen, versuchen Sie, es explizit über (im Eintrag js) in den globalen Kontext zu stellen.
quelle
Fügen Sie in Ihrer Datei webpack.config.js Folgendes hinzu:
Installieren Sie jQuery mit npm:
Fügen Sie in der Datei app.js die folgenden Zeilen hinzu:
Das hat bei mir funktioniert. :) :)
quelle
Ich habe einige der Antworten ausprobiert, aber keine schien zu funktionieren. Dann habe ich das versucht:
Scheint zu funktionieren, egal welche Version ich benutze
quelle
$
außerhalb eines Webpacks erforderliche Datei zu verwenden, ist diese undefiniert.Dies funktioniert in Webpack 3:
in der Datei webpack.config.babel.js:
Und verwenden Sie ProvidePlugin
quelle
Die beste Lösung, die ich gefunden habe, war:
https://github.com/angular/angular-cli/issues/5139#issuecomment-283634059
Grundsätzlich müssen Sie eine Dummy-Variable in typings.d.ts einfügen, alle "import * as $ from 'jquery" aus Ihrem Code entfernen und dann manuell ein Tag zum jQuery-Skript zu Ihrem SPA-HTML hinzufügen. Auf diese Weise steht Ihnen das Webpack nicht im Weg, und Sie sollten in allen Ihren Skripten auf dieselbe globale jQuery-Variable zugreifen können.
quelle
Dies funktioniert bei mir in der Datei webpack.config.js
in einem anderen Javascript oder in HTML hinzufügen:
quelle
Bearbeiten: Manchmal möchten Sie Webpack einfach als Modulbündler für ein einfaches Webprojekt verwenden, um Ihren eigenen Code zu organisieren. Die folgende Lösung ist für diejenigen gedacht, die nur möchten, dass eine externe Bibliothek in ihren Modulen wie erwartet funktioniert - ohne viel Zeit in Webpack-Setups zu investieren. (Bearbeitet nach -1)
Schnelle und einfache (es6) Lösung, wenn Sie immer noch Probleme haben oder die externe Konfiguration / zusätzliche Webpack-Plugin-Konfiguration vermeiden möchten:
innerhalb eines Moduls:
quelle