Викрийте jQuery справжньому об'єкту Window за допомогою Webpack


111

Я хочу відкрити об’єкт jQuery глобальному об'єкту вікна, який доступний всередині консолі розробника у браузері. Тепер у моєму конфігурації веб-упаковки є такі рядки:

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

Ці рядки додають визначення jQuery до кожного файлу в моїх модулях веб-упаковки. Але коли я будую проект і намагаюся отримати доступ до jQuery на консолі розробника так:

window.$;
window.jQuery;

це говорить про те, що ці властивості не визначені ...

Чи є спосіб це виправити?


1
Чи можу я встановити this: 'window'теж? Оскільки багато бібліотек вважають, що thisзмінна є об'єктом Window
Абхінав Сінгі

Відповіді:


129

Вам потрібно використовувати експонатор-завантажувач .

npm install expose-loader --save-dev

Ви можете це зробити, коли цього вимагаєте:

require("expose?$!jquery");

або ви можете зробити це у своєму конфігурації:

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

ОНОВЛЕННЯ : Станом на веб-пакет 2, вам потрібно використовувати експонатор-завантажувач замість експозиції :

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

11
ProvidePluginПовинні в першу чергу використовується в ситуаціях , коли сторонні бібліотеки покладатися на наявність глобальної змінної.
Йоханнес Евальд

Я зробив неправильне припущення, що питання використовував плагін для забезпечення "ледачих" цілей, який я бачив багато в Інтернеті, але ви правильні :)
Метт Деррік

8
Це саме те, що я шукав, і просто додати, для навантажувачів ви також можете зробити це в один рядок:{test: /jquery\.js$/, loader: 'expose?jQuery!expose?$'}
Фернандо

8
Ви не можете просто додати перший сценарій, який це робиться $ = require('jquery'); window.jQuery = $; window.$ = $;? (не потребує expose-loader)
герман

1
Згідно сторінці викрити-навантажувач GitHub синтаксис WebPack 2 виглядає наступним чином : module: { rules: [{ test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' },{ loader: 'expose-loader', options: '$' }] }] }. Це єдиний спосіб, коли я міг би отримати jQuery, і він використовує новий синтаксис module.rules .
Гевін Сазерленд

84

Додаток ProvidePlugin замінює символ у іншому джерелі через відповідний імпорт, але не виставляє символ у глобальному просторі імен. Класичний приклад - плагіни jQuery. Більшість із них просто розраховують jQueryвизначитися глобально. За допомогою цього ProvidePluginви переконаєтесь, що jQuery - це залежність (наприклад, завантажена раніше), а виникнення jQueryїх коду буде замінено на еквівалент webpack require('jquery').

Якщо у вас є зовнішні скрипти, які покладаються на символ, що знаходиться у глобальній просторі імен (наприклад, скажімо, зовнішній розміщений JS, дзвінки Javascript у Selenium або просто доступ до символу на консолі браузера), ви хочете скористатися цим expose-loader.

Коротше кажучи: ProvidePlugin управляє залежностями часу побудови до глобальних символів, тоді як expose-loaderкерує залежністю від виконання глобальних символів.


2
Дякую за пояснення
Фотон

Наведіть приклад додавання веб-пакету з офіційних документів: webpack.js.org/plugins/provide-plugin/#usage-jquery
Джеймс

33

Схоже, windowоб’єкт виставлений у всіх модулях.

Чому б не просто імпортувати / вимагати JQueryта ставити:

window.$ = window.JQuery = JQuery;

Вам потрібно буде переконатися, що це відбувається перед тим, як вимагати / імпортувати будь-який модуль, який використовує window.JQuery, або в потрібному модулі, або в модулі, де він використовується.


Найпростіше рішення без додавання нової залежності. Дякую!
fatihpense

Це не буде працювати, якщо інші вкладені модулі використовують змінну, просто "не визначено"
aboutqx

4
Добре це працює при використанні, requireпоки немаєimport
aboutqx

@aboutqx Не впевнений, що ти маєш на увазі. Моя відповідь передбачала, що JQuery вже імпортували / вимагали та присвоювали змінній з назвою JQuery.
mhess

2
@mhess, коли ви використовуєте import, ви можете отримати помилку, тому що imports відсортується вгорі файлу і requireзалишиться там, де вони були поміщені. Таким чином, порядок виконання змінюється лише importтоді, коли вікно змінної не встановлено.
aboutqx

16

Це завжди працювало для мене. у тому числі для веб- пакета 3 window.$ = window.jQuery = require("jquery");


2
найкраще рішення! 2018
waza123

6

Ніщо з перерахованого вище не працювало для мене. (і мені дуже не подобається синтаксис експонатора-завантажувача). Натомість

Я додав до webpack.config.js:

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

Тоді всі модулі мають доступ через jQuery через $.

Ви можете відкрити його у вікні, додавши наступне до будь-якого з ваших модулів, що входять у веб-пакет:

window.$ = window.jQuery = $

1
Це працювало для мене, використовуючи webpack-stream за лаштунками
klewis

1

Оновлення для Webpack v2

Встановіть експозиційний завантажувач, як описано Меттом Дерріком:

npm install expose-loader --save-dev

Потім вставте такий фрагмент у свій webpack.config.js:

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

(з документів експозиційного завантажувача )


Зараз я більше не можу це працювати в будь-якій версії Webpack. Не впевнений, що змінилося, але єдиний спосіб, коли я можу отримати jQuery або $ бути визнаним - це зробитиwindow.jQuery = require('jquery');
trpt4him

0

У моєму випадку працює

{ test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" } 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.