使用Webpack将jQuery公开到真实的Window对象


111

我想将jQuery对象公开给可在浏览器的开发人员控制台内部访问的全局窗口对象。现在在我的webpack配置中,我有以下几行:

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

这些行将jQuery定义添加到我的webpack模块中的每个文件中。但是,当我构建项目并尝试像这样在开发人员控制台中访问jQuery时:

window.$;
window.jQuery;

它说这些属性是不确定的...

有没有办法解决这个问题?


1
this: 'window'也可以设置吗?由于许多库都假定this变量为Window对象
Abhinav Singi '16

Answers:


129

您需要使用暴露加载器

npm install expose-loader --save-dev

您可以在需要时执行以下操作:

require("expose?$!jquery");

或者您可以在配置中执行以下操作:

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

更新:从webpack 2开始,您需要使用暴露加载器而不是暴露

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

11
ProvidePlugin应该在的情况下,主要用在第三方库依靠一个全局变量的存在。
Johannes Ewald 2015年

我做出了错误的假设,问题是出于“懒惰”目的使用了Provide插件,我在网上已经看到了很多,但是您是正确的:)
Matt Derrick

8
这正是我一直在寻找的东西,只是为了进一步增加,对于装载机,您也可以在一行中完成:{test: /jquery\.js$/, loader: 'expose?jQuery!expose?$'}
Fernando

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在其代码中出现的将替换为webpack的RAW等效项require('jquery')

如果您有依赖于符号位于全局命名空间中的外部脚本(例如,假设是外部托管的JS,Selenium中的Javascript调用或只是在浏览器控制台中访问该符号),则要使用expose-loader替代符号。

简而言之:ProvidePlugin管理对全局符号的构建时依赖关系,而expose-loader管理对全局符号的运行时依赖关系。


2
感谢您的解释
-Foton

官方文档中包含webpack的ProvidePlugin示例:webpack.js.org/plugins/provide-plugin/#usage-jquery
James Gentes

33

看起来该window对象在所有模块中都是公开的。

为什么不只是导入/要求JQuery并放入:

window.$ = window.JQuery = JQuery;

您需要确保在要求/导入需求window.JQuery模块或使用该模块的模块中,需要/导入使用的任何模块之前发生这种情况。


无需添加新依赖性的最简单解决方案。谢谢!
fatihpense

如果使用变量“仅未定义”的其他嵌套模块,则该方法将不起作用
aboutqx

4
那么它使用时的工作require,而不是import
aboutqx

@aboutqx不确定您的意思。我的答案假设JQuery已被导入/需要,并已分配给名为的变量JQuery
17:03

2
@mhes使用时import,可能会出错,因为imports被排序到了文件的顶部,并require停留在放置它们的位置。因此,运行顺序仅import在未设置窗口可变性的情况下才会发生变化。
aboutqx

16

这一直对我有用。包括用于webpack 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通过$访问。

通过将以下内容添加到webpack捆绑的任何模块中,可以将其公开给窗口:

window.$ = window.jQuery = $

1
这对我在后台使用webpack-stream
起作用

1

Webpack v2的更新

按照Matt Derrick的说明安装暴露加载程序

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" } 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.