Setzen Sie jQuery mit Webpack einem echten Window-Objekt aus

111

Ich möchte das jQuery-Objekt für das globale Fensterobjekt verfügbar machen, auf das in der Entwicklerkonsole im Browser zugegriffen werden kann. Jetzt habe ich in meiner Webpack-Konfiguration folgende Zeilen:

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

Diese Zeilen fügen jeder Datei in meinen Webpack-Modulen die jQuery-Definitionen hinzu. Aber wenn ich das Projekt erstelle und versuche, auf jQuery in der Entwicklerkonsole wie folgt zuzugreifen:

window.$;
window.jQuery;

es heißt, dass diese Eigenschaften undefiniert sind ...

Gibt es eine Möglichkeit, dies zu beheben?

ferbolg
quelle
1
Kann ich auch einstellen this: 'window'? Da viele Bibliotheken davon ausgehen, dass thisVariable das Fensterobjekt ist
Abhinav Singi

Antworten:

129

Sie müssen den Expose-Loader verwenden .

npm install expose-loader --save-dev

Sie können dies entweder tun, wenn Sie es benötigen:

require("expose?$!jquery");

oder Sie können dies in Ihrer Konfiguration tun:

loaders: [
    { test: require.resolve('jquery'), loader: 'expose?jQuery!expose?$' }
]

UPDATE : Ab Webpack 2 müssen Sie den Expose-Loader anstelle von Expose verwenden :

module: {
    rules: [{
        test: require.resolve('jquery'),
        use: [{
            loader: 'expose-loader',
            options: '$'
        }]
    }]
}
Matt Derrick
quelle
11
Das ProvidePluginsollte hauptsächlich in Situationen verwendet werden, in denen Bibliotheken von Drittanbietern auf das Vorhandensein einer globalen Variablen angewiesen sind.
Johannes Ewald
Ich habe die falsche Annahme gemacht, dass die Frage das Bereitstellungs-Plugin für "faule" Zwecke verwendet, die ich online viel gesehen habe, aber Sie haben Recht :)
Matt Derrick
8
Dies ist genau das, wonach ich gesucht habe und um es noch weiter hinzuzufügen, für Lader können Sie es auch in einer Zeile tun:{test: /jquery\.js$/, loader: 'expose?jQuery!expose?$'}
Fernando
8
Können Sie nicht einfach ein erstes Skript hinzufügen, das dies tut $ = require('jquery'); window.jQuery = $; window.$ = $;? (nicht nötig expose-loader)
Hermann
1
Laut der GitHub-Seite des Expose-Loaders lautet die Syntax von Webpack 2 wie folgt : module: { rules: [{ test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' },{ loader: 'expose-loader', options: '$' }] }] }. Dies ist die einzige Möglichkeit, jQuery verfügbar zu machen, und es wird die neue Syntax module.rules verwendet .
Gavin Sutherland
84

Das ProvidePlugin ersetzt durch den jeweiligen Import ein Symbol in einer anderen Quelle, macht das Symbol jedoch nicht im globalen Namespace verfügbar. Ein klassisches Beispiel sind jQuery-Plugins. Die meisten von ihnen erwarten lediglich eine jQueryglobale Definition. Mit dem ProvidePluginwürden Sie sicherstellen, dass jQuery eine Abhängigkeit ist (z. B. zuvor geladen) und das Auftreten jQueryin ihrem Code durch das Webpack-Raw-Äquivalent von ersetzt wird require('jquery').

Wenn Sie externe Skripte haben, die sich darauf verlassen, dass sich das Symbol im globalen Namespace befindet (z. B. ein extern gehostetes JS, Javascript ruft Selen auf oder einfach auf das Symbol in der Browserkonsole zugreift), möchten Sie expose-loaderstattdessen das verwenden.

Kurz gesagt: ProvidePlugin verwaltet Build-Time-Abhängigkeiten zu globalen Symbolen, während das zur expose-loaderLaufzeit Abhängigkeiten zu globalen Symbolen verwaltet.

Joscha
quelle
2
Vielen Dank für die Erklärung
Foton
ProvidePlugin Beispiel mit Webpack aus offiziellen Dokumenten: webpack.js.org/plugins/provide-plugin/#usage-jquery
James Gentes
33

Es sieht so aus, als ob das windowObjekt in allen Modulen verfügbar ist.

Warum nicht einfach importieren / benötigen JQueryund setzen:

window.$ = window.JQuery = JQuery;

Sie müssen sicherstellen, dass dies geschieht, bevor Sie ein Modul benötigen / importieren, das verwendet wird window.JQuery, entweder in einem erforderlichen Modul oder in dem Modul, in dem es verwendet wird.

mhess
quelle
Einfachste Lösung ohne Hinzufügen einer neuen Abhängigkeit. Vielen Dank!
Fatihpense
Das wird nicht funktionieren, wenn andere verschachtelte Module die Variable verwenden, nur 'nicht definiert'
ungefähr am
4
Nun, es funktioniert, wenn es requirenicht verwendet wirdimport
ungefähr am
@aboutqx Nicht sicher, was du meinst. Meine Antwort ging davon aus, dass JQuery bereits importiert / benötigt und einer Variablen mit dem Namen zugewiesen wurde JQuery.
mhess
2
@mhess Wenn Sie verwenden import, wird möglicherweise eine Fehlermeldung angezeigt, da imports oben in der Datei sortiert wird und dort requirebleibt, wo sie abgelegt wurden. Die Ausführungsreihenfolge ändert sich also nur, importwenn das Fenster varaivble nicht festgelegt ist.
ungefähr am
16

Das hat bei mir immer funktioniert. einschließlich für Webpack 3 window.$ = window.jQuery = require("jquery");

SharpCoder
quelle
2
beste Lösung ! 2018
waza123
6

Keines der oben genannten hat bei mir funktioniert. (und ich mag die Expose-Loader-Syntax wirklich nicht). Stattdessen,

Ich habe zu webpack.config.js hinzugefügt:

var webpack = require('webpack');
module.exports = {
   plugins: [
       new webpack.ProvidePlugin({
           $: 'jquery',
       })     
   ]
}

Dann haben alle Module Zugriff über jQuery über $.

Sie können es dem Fenster zugänglich machen, indem Sie jedem Ihrer im Webpack gebündelten Module Folgendes hinzufügen:

window.$ = window.jQuery = $
Antoine Vo
quelle
1
Dies funktionierte für mich mit Webpack-Stream hinter den Kulissen
klewis
1

Update für Webpack v2

Installieren Sie den Expose-Loader wie von Matt Derrick beschrieben:

npm install expose-loader --save-dev

Fügen Sie dann das folgende Snippet in Ihr ein webpack.config.js:

module.exports = {
    entry: {
        // ...
    },
    output: {
        // ...
    },
    module: {
        loaders: [
                { test: require.resolve("jquery"), loader: "expose-loader?$!expose-loader?jQuery" }
        ]
    }
};

(aus den Expose-Loader-Dokumenten )

Köln_Muc
quelle
Ich kann dies jetzt in keiner Version von Webpack mehr zum Laufen bringen. Ich bin mir nicht sicher, was sich geändert hat, aber der einzige Weg, wie ich jQuery oder $ erkennen kann, ist zu tunwindow.jQuery = require('jquery');
trpt4him
0

In meinem Fall funktioniert

{ test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" } 
FeDev
quelle