Wystaw jQuery na rzeczywisty obiekt Window za pomocą Webpack

111

Chcę wystawić obiekt jQuery na globalny obiekt okna, który jest dostępny w konsoli programisty w przeglądarce. Teraz w mojej konfiguracji webpacka mam następujące linie:

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

Te wiersze dodają definicje jQuery do każdego pliku w moich modułach webpack. Ale kiedy buduję projekt i próbuję uzyskać dostęp do jQuery w konsoli programisty w następujący sposób:

window.$;
window.jQuery;

mówi, że te właściwości są niezdefiniowane ...

Czy jest sposób, aby to naprawić?

ferbolg
źródło
1
Czy mogę this: 'window'też ustawić ? Ponieważ wiele bibliotek przyjmuje, że thiszmienną jest obiekt Window
Abhinav Singi,

Odpowiedzi:

129

Musisz użyć expose-loader .

npm install expose-loader --save-dev

Możesz to zrobić, gdy tego potrzebujesz:

require("expose?$!jquery");

lub możesz to zrobić w swojej konfiguracji:

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

AKTUALIZACJA : Od webpacka 2 musisz użyć expose-loader zamiast expose :

module: {
    rules: [{
        test: require.resolve('jquery'),
        use: [{
            loader: 'expose-loader',
            options: '$'
        }]
    }]
}
Matt Derrick
źródło
11
ProvidePluginPowinny przede wszystkim stosować w sytuacjach, w których biblioteki innych firm opiera się na obecności zmiennej globalnej.
Johannes Ewald,
Zrobiłem nieprawidłowe założenie pytanie zostało używając zapewnić plugin dla celów „leniwe”, które widziałem dużo w Internecie, ale masz rację :)
Matt Derrick
8
To jest dokładnie to, czego szukałem i żeby dodać więcej, dla ładowarek też możesz to zrobić w jednej linii:{test: /jquery\.js$/, loader: 'expose?jQuery!expose?$'}
Fernando
8
Nie możesz po prostu dodać pierwszego skryptu, który to robi $ = require('jquery'); window.jQuery = $; window.$ = $;? (niepotrzebne expose-loader)
herman
1
Według strony odsłonięcia-ładowarka GitHub składnia WebPack 2 jest następująca: module: { rules: [{ test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' },{ loader: 'expose-loader', options: '$' }] }] }. Jest to jedyny sposób, w jaki mogłem ujawnić jQuery i używa nowej składni module.rules .
Gavin Sutherland,
84

ProvidePlugin zastępuje symbol w innym źródle poprzez odpowiedni import, ale nie uwidacznia symbolu w globalnej przestrzeni nazw. Klasycznym przykładem są wtyczki jQuery. Większość z nich oczekuje, jQueryże zostaną zdefiniowane globalnie. Dzięki temu ProvidePluginupewnisz się, że jQuery jest zależnością (np. Załadowana wcześniej), a występowanie jQueryw ich kodzie zostanie zastąpione surowym odpowiednikiem pakietu webpack require('jquery').

Jeśli masz zewnętrzne skrypty opierające się na tym, że symbol znajduje się w globalnej przestrzeni nazw (jak powiedzmy zewnętrznie hostowany JS, wywołania JavaScript w Selenium lub po prostu uzyskując dostęp do symbolu w konsoli przeglądarki), chcesz użyć expose-loaderzamiast tego.

W skrócie: ProvidePlugin zarządza zależnościami czasu kompilacji od symboli globalnych, podczas gdy expose-loaderzarządza zależnościami czasu wykonywania od symboli globalnych.

Joscha
źródło
2
Dzięki za wyjaśnienie
Foton
Podaj przykład wtyczki z pakietem webpack z oficjalnych dokumentów: webpack.js.org/plugins/provide-plugin/#usage-jquery
James Gentes
33

Wygląda na to, że windowobiekt jest widoczny we wszystkich modułach.

Dlaczego nie po prostu zaimportować / wymagać JQueryi umieścić:

window.$ = window.JQuery = JQuery;

Będziesz musiał upewnić się, że dzieje się to przed zażądaniem / zaimportowaniem dowolnego modułu, który używa window.JQuery, w wymagającym module lub w module, w którym jest używany.

mhess
źródło
Najłatwiejsze rozwiązanie bez dodawania nowej zależności. Dzięki!
fatihpense
To nie zadziała, gdy inne zagnieżdżone moduły używają zmiennej, po prostu „nie zdefiniowano”
aboutqx
4
Cóż, działa, gdy używasz, requiregdy nieimport
aboutqx
@aboutqx Nie wiem, co masz na myśli. Moja odpowiedź zakładała, że ​​JQuery zostało już zaimportowane / wymagane i przypisane do zmiennej o nazwie JQuery.
szachy
2
@mhess, gdy używasz import, możesz otrzymać błąd, ponieważ imports są sortowane na początek pliku i requirepozostają tam, gdzie zostały umieszczone. Tak więc kolejność uruchamiania zmienia się tylko importwtedy, gdy zmienna okna nie jest ustawiona.
okołoqx
16

To zawsze działało dla mnie. w tym dla webpacka 3 window.$ = window.jQuery = require("jquery");

SharpCoder
źródło
2
najlepsze rozwiązanie! 2018
waza123
6

Żadne z powyższych nie działało dla mnie. (i naprawdę nie podoba mi się składnia expose-loader). Zamiast,

Dodałem do webpack.config.js:

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

Wszystkie moduły mają dostęp poprzez jQuery poprzez $.

Możesz wyświetlić go w oknie, dodając następujące elementy do dowolnego z modułów w pakiecie webpack:

window.$ = window.jQuery = $
Antoine Vo
źródło
1
To zadziałało dla mnie, używając strumienia
webpack
1

Aktualizacja dla Webpack v2

Zainstaluj program ładujący ekspozycję zgodnie z opisem Matta Derricka:

npm install expose-loader --save-dev

Następnie wstaw następujący fragment do swojego webpack.config.js:

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

(z dokumentacji expose-loader )

Cologne_Muc
źródło
Teraz nie mogę już uruchomić tego w żadnej wersji Webpack. Nie jestem pewien, co się zmieniło, ale jedynym sposobem na rozpoznanie jQuery lub $ jest zrobieniewindow.jQuery = require('jquery');
trpt4him
0

W moim przypadku działa

{ test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" } 
FeDev
źródło