Предоставьте jQuery реальному объекту Window с помощью Webpack


111

Я хочу предоставить объект jQuery глобальному объекту окна, который доступен внутри консоли разработчика в браузере. Теперь в моей конфигурации веб-пакета есть следующие строки:

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

Эти строки добавляют определения jQuery к каждому файлу в моих модулях webpack. Но когда я создаю проект и пытаюсь получить доступ к 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?$' }
]

ОБНОВЛЕНИЕ : Начиная с webpack 2, вам нужно использовать expose -loader вместо expose :

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)
Herman

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в их коде будет заменено необработанным эквивалентом веб-пакета require('jquery').

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

Вкратце: ProvidePlugin управляет зависимостями времени сборки от глобальных символов, тогда как expose-loaderуправление зависимостями времени выполнения от глобальных символов.


2
Спасибо за объяснение
Foton

Пример ProvidePlugin с веб-пакетом из официальных документов: 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, вы можете получить ошибку, потому что importони сортируются в начало файла и requireостаются там, где они были помещены. Таким образом, порядок выполнения изменяется только importтогда, когда переменная окна не установлена.
aboutqx

16

У меня это всегда срабатывало. в том числе для webpack 3 window.$ = window.jQuery = require("jquery");


2
лучшее решение ! 2018
waza123

6

У меня ничего из вышеперечисленного не сработало. (и мне действительно не нравится синтаксис expose-loader). Вместо,

Я добавил в webpack.config.js:

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

Чем все модули имеют доступ через jQuery через $.

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

window.$ = window.jQuery = $

1
Это сработало для меня, используя webpack-stream за кулисами
Клевис

1

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

Установите expose-loader, как описано Мэттом Дерриком:

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" }
        ]
    }
};

(из документов expose-loader )


Я больше не могу заставить это работать ни в одной версии 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.