跳到内容

jQuery 插件和使用 Webpack Encore 的遗留应用

编辑此页

在 Webpack 内部,当你 require 一个模块时,它(通常)不会设置全局变量。相反,它只是返回一个值。

1
2
// this loads jquery, but does *not* set a global $ or jQuery variable
const $ = require('jquery');

在实践中,这将导致一些外部库出现问题,这些库依赖 jQuery 作为全局变量,或者如果你的 JavaScript 没有通过 Webpack 处理(例如,你的模板中有些 JavaScript),并且你需要 jQuery。两者都会导致类似的错误。

1
2
Uncaught ReferenceError: $ is not defined at [...]
Uncaught ReferenceError: jQuery is not defined at [...]

修复方法取决于哪个代码引起了问题。

修复期望 jQuery 为全局变量的 jQuery 插件

jQuery 插件通常期望 jQuery 已经通过 $jQuery 全局变量可用。要修复此问题,请从你的 webpack.config.js 文件中调用 autoProvidejQuery()

1
2
3
4
5
// webpack.config.js
  Encore
      // ...
+     .autoProvidejQuery()
  ;

重启 Encore 后,Webpack 将查找所有未初始化的 $jQuery 变量,并自动 require jquery 并为你设置这些变量。它“重写”了“错误”的代码,使其正确。

在内部,autoProvidejQuery() 方法调用 Encore 的 autoProvideVariables() 方法。在实践中,它等同于执行以下操作:

1
2
3
4
5
6
7
8
9
10
Encore
    // you can use this method to provide other common global variables,
    // such as '_' for the 'underscore' library
    .autoProvideVariables({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery',
    })
    // ...
;

从 Webpack JavaScript 文件外部访问 jQuery

如果你的代码需要访问 $jQuery,并且你位于 Webpack/Encore 处理的文件中,你应该通过 require jQuery 来删除任何“$ is not defined”错误:var $ = require('jquery')

但是,如果你还需要在 Webpack 处理的 JavaScript 文件之外(例如,仍然存在于你的模板中的 JavaScript)提供对 $jQuery 变量的访问,则需要在某些 JavaScript 文件中手动将这些变量设置为全局变量,该文件在你的遗留代码之前加载。

例如,在你的 app.js 文件中(该文件由 Webpack 处理并在每个页面上加载),添加:

1
2
3
4
5
6
7
// app.js

  // require jQuery normally
  const $ = require('jquery');

+ // create global $ and jQuery variables
+ global.$ = global.jQuery = $;

global 变量是在 window 变量中设置内容的特殊方式。在 Web 上下文中,使用 globalwindow 是等效的,除了在使用 autoProvidejQuery()window.jQuery 将不起作用。换句话说,使用 global

此外,请务必在你的 webpack_encore.yaml 文件中将 script_attributes.defer 选项设置为 false

1
2
3
4
5
# config/packages/webpack_encore.yaml
webpack_encore:
    # ...
    script_attributes:
        defer: false

这将确保你的 script 标签上没有 defer 属性。有关更多信息,请参阅 将 <script> 移动到 <head> 内和 "defer" 属性

本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本