Ekspos jQuery ke objek Window nyata dengan Webpack


111

Saya ingin mengekspos objek jQuery ke objek jendela global yang dapat diakses di dalam konsol pengembang di browser. Sekarang di konfigurasi webpack saya, saya memiliki baris berikut:

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

Baris-baris ini menambahkan definisi jQuery ke setiap file di modul webpack saya. Tetapi ketika saya membangun proyek dan mencoba mengakses jQuery di konsol pengembang seperti ini:

window.$;
window.jQuery;

dikatakan bahwa properti ini tidak ditentukan ...

Apakah ada cara untuk memperbaikinya?


1
Bisakah saya mengatur this: 'window'juga? Karena banyak perpustakaan menganggap thisvariabel sebagai objek Jendela
Abhinav Singi

Jawaban:


129

Anda perlu menggunakan expose-loader .

npm install expose-loader --save-dev

Anda dapat melakukan ini saat Anda membutuhkannya:

require("expose?$!jquery");

atau Anda dapat melakukan ini di konfigurasi Anda:

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

UPDATE : Pada webpack 2, Anda perlu menggunakan expose-loader daripada expose :

module: {
    rules: [{
        test: require.resolve('jquery'),
        use: [{
            loader: 'expose-loader',
            options: '$'
        }]
    }]
}

11
Ini ProvidePluginterutama harus digunakan dalam situasi di mana pustaka pihak ketiga bergantung pada keberadaan variabel global.
Johannes Ewald

Saya membuat asumsi yang salah, pertanyaannya adalah menggunakan plugin penyedia untuk tujuan 'malas' yang telah saya lihat banyak secara online tetapi Anda benar :)
Matt Derrick

8
Ini persis seperti yang saya cari dan hanya untuk menambahkan lebih lanjut, untuk loader, Anda juga dapat melakukannya dalam satu baris:{test: /jquery\.js$/, loader: 'expose?jQuery!expose?$'}
Fernando

8
Tidak bisakah Anda menambahkan skrip pertama yang melakukannya $ = require('jquery'); window.jQuery = $; window.$ = $;? (tidak perlu expose-loader)
herman

1
Menurut halaman GitHub mengekspos-loader yang Webpack 2 sintaks adalah sebagai berikut: module: { rules: [{ test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' },{ loader: 'expose-loader', options: '$' }] }] }. Ini adalah satu-satunya cara agar jQuery terekspos dan menggunakan sintaks module.rules yang baru .
Gavin Sutherland

84

ProvidPlugin menggantikan simbol di sumber lain melalui impor masing-masing, tetapi tidak mengekspos simbol di namespace global. Contoh klasik adalah plugin jQuery. Kebanyakan dari mereka hanya berharap jQueryuntuk didefinisikan secara global. Dengan ProvidePluginAnda akan memastikan bahwa jQuery adalah dependensi (misalnya dimuat sebelumnya) dan kemunculan jQuerydalam kode mereka akan diganti dengan webpack mentah yang setara require('jquery').

Jika Anda memiliki skrip eksternal yang mengandalkan simbol untuk berada di namespace global (seperti misalnya JS yang dihosting secara eksternal, panggilan Javascript di Selenium atau hanya mengakses simbol di konsol browser), Anda ingin menggunakan expose-loader gantinya.

Singkatnya: ProvidPlugin mengelola dependensi waktu build ke simbol global, sedangkan dependensi waktu proses ke simbol global expose-loaderdikelola.


2
Terima kasih atas penjelasannya
Foton

Contoh ProvidPlugin dengan paket web dari dokumen resmi: webpack.js.org/plugins/provide-plugin/#usage-jquery
James Gentes

33

Sepertinya windowobjek diekspos di semua modul.

Mengapa tidak hanya mengimpor / membutuhkan JQuerydan memasukkan:

window.$ = window.JQuery = JQuery;

Anda perlu memastikan bahwa ini terjadi sebelum meminta / mengimpor modul apa pun yang digunakan window.JQuery, baik di modul yang memerlukan atau di modul tempat modul itu digunakan.


Solusi termudah tanpa menambahkan ketergantungan baru. Terima kasih!
fatihpense

Itu tidak akan berfungsi saat modul bersarang lainnya menggunakan variabel, hanya 'tidak ditentukan'
aboutqx

4
Ini berfungsi saat menggunakan requiresaat tidakimport
aboutqx

@aboutqx Tidak yakin apa yang Anda maksud. Jawaban saya berasumsi bahwa JQuery telah diimpor / diperlukan dan ditetapkan ke variabel bernama JQuery.
mhess

2
@mhess ketika Anda menggunakan import, Anda mungkin mendapatkan kesalahan, karena imports disortir ke atas file, dan requiretetap di tempat mereka diletakkan. Jadi run-order hanya berubah importjika jendela varaivble tidak disetel.
aboutqx

16

Ini selalu berhasil untuk saya. termasuk untuk webpack 3 window.$ = window.jQuery = require("jquery");


2
solusi terbaik ! 2018
waza123

6

Semua hal di atas tidak berhasil untuk saya. (dan saya benar-benar tidak suka sintaks expose-loader). Sebagai gantinya,

Saya menambahkan ke webpack.config.js:

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

Dari semua modul memiliki akses melalui jQuery melalui $.

Anda dapat mengeksposnya ke jendela dengan menambahkan berikut ini ke salah satu modul Anda yang dipaketkan oleh webpack:

window.$ = window.jQuery = $

1
Ini bekerja untuk saya menggunakan aliran webpack di belakang layar
klewis

1

Pembaruan untuk Webpack v2

Instal expose-loader seperti yang dijelaskan oleh Matt Derrick:

npm install expose-loader --save-dev

Kemudian masukkan cuplikan berikut di Anda webpack.config.js:

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

(dari dokumen expose-loader )


Sekarang saya tidak bisa lagi menggunakan ini di versi Webpack mana pun. Tidak yakin apa yang telah berubah tetapi satu-satunya cara agar saya bisa mendapatkan jQuery atau $ agar dikenali adalah dengan melakukannyawindow.jQuery = require('jquery');
trpt4him

0

Dalam kasus saya berhasil

{ test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" } 
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.