symfony - 带有 webpack-encore : Cannot read property 'Constructor' of undefined 的 ekko-lightbox

标签 symfony webpack-encore

我想使用 Symfony 的 webpack-encore 来包含 ekko-lightbox .

我在这里创建了一个有效的 jsFiddle 演示:https://jsfiddle.net/92vq1z2b/ .它和我一样使用相同版本的 bootstrap、jQuery 和 ekko-lightbox。

然而,在我本地的 Symfony 项目中,它不起作用。当我单击“灯箱”图像时,我在浏览器控制台中收到以下错误:

Uncaught TypeError: Cannot read property 'Constructor' of undefined
at new Lightbox (ekko-lightbox.js:97)
at HTMLAnchorElement.<anonymous> (ekko-lightbox.js:649)
at Function.each (jquery.js:362)
at jQuery.fn.init.each (jquery.js:157)
at jQuery.fn.init._jQueryInterface [as ekkoLightbox] (ekko-lightbox.js:645)
at HTMLAnchorElement.<anonymous> (members.js:8)
at HTMLDocument.dispatch (jquery.js:5206)
at HTMLDocument.elemData.handle (jquery.js:5014)

ekko-lightbox.js 的第 97 行内容如下:
this._isBootstrap3 = $.fn.modal.Constructor.VERSION[0] == 3;

不知何故,webpack-encore 似乎弄乱了 javascript 文件。但我找不到问题所在。

我的 webpack.config.js 看起来像这样:
// webpack.config.js
// ...
.addEntry('global', './assets/js/global.js')
.addEntry('public', './assets/js/public.js')
.addEntry('members', './assets/js/members.js')
// ...

global.js 文件包括 bootstrap、jQuery 等:
// global.js
require('../css/global.scss');

var $ = require('jquery');
require('popper.js');
require('bootstrap');

members.js 文件包含 ekko-lightbox:
// members.js
require('../css/members.scss');

require('ekko-lightbox');

$(document).ready(function () {
    $(document).on('click', '[data-toggle="lightbox"]', function (event) {
        event.preventDefault();
        $(this).ekkoLightbox();
    });
});

在我的 HTML 代码中,global.js 在 members.js 之前加载:
// HTML code that loads the javascript files
<script src="/build/global.js"></script>    
<script src="/build/members.js"></script>

顺便说一句:出于某种原因,webpack-encore 使用了 ekko-lightbox 的缩小版本,即 ekko-lightbox.min.js。即使在开发模式下。我的期望是 webpack-encore 将始终在开发模式下使用非缩小版本。我不得不更改 ekko-lightbox package.json 文件以更改此行为(package.json 中的“main”条目以前指向 .min.js 文件,现在它指向非缩小版本)。我认为 'main' 条目应该始终指向没有任何文件扩展名的目标文件(这就是它在 bootstrap 的 package.json 中定义的方式)。也就是说,它应该看起来像 "main": "dist/ekko-lightbox"而不是 "main": "dist/ekko-lightbox.js""main": "dist/ekko-lightbox.min.js" .

版本信息:
Google Chrome 63
"@symfony/webpack-encore": "^0.17.1",
"bootstrap": "^4.0.0-beta.3",
"jquery": "^3.2.1",
"ekko-lightbox": "^5.3.0"

更新:我注意到 bootstrap v4 不再是测试版。但是运行npm update后问题依旧.我的新 npm 包版本如下(仅顶级):
+-- @symfony/webpack-encore@0.17.1
+-- bootstrap@4.0.0
+-- ekko-lightbox@5.3.0
+-- jquery@3.3.1
+-- node-sass@4.7.2
+-- popper.js@1.13.0
+-- sass-loader@6.0.6
`-- webpack-notifier@1.5.1

最佳答案

经过大量调试,我解决了它。问题是我如何包含 jQuery 和 bootstrap。在我的 global.js 中,我明确要求带有 require() 的 jQuery称呼。但是,这是由 webpack-encore 通过行 .autoProvidejQuery() 自动执行的。在我的 webpack.config.js .此外,对于 webpack.config.js 引用的每个 javascript 文件,似乎都会发生这种自动提供 jQuery 的情况。 .那就是:我的 global.js、public.js 和 members.js 每个都有一个单独的 jQuery 实例(顺便说一句:这也会减慢页面加载时间!)。

显然,这些单独的 jQuery 实例弄乱了引导模块注册(它们在 jQuery.fn[MODULE_NAME]$.fn[MODULE_NAME] 下注册)。

解决方案是创建一个所谓的 shared entry to your webpack.config.js .

我的 webpack.config.js 现在看起来像这样:

// ...
.addEntry('global', './assets/js/global.js')
.addEntry('public', './assets/js/public.js')
.addEntry('members', './assets/js/members.js')

.createSharedEntry('vendor', [
    'jquery',
    'popper.js',
    'bootstrap'
])

// allow sass/scss files to be processed
.enableSassLoader()

// allow legacy applications to use $/jQuery as a global variable
.autoProvidejQuery()
// ...

我的 global.js 不再需要 jQuery 或 bootstrap,因为它们已经包含在共享模块中。只剩下一个 require() 用于全局 CSS 定义。
// global.js
require('../css/global.scss');

我的 members.js 没有改变,只是我添加了行 require('ekko-lightbox/dist/ekko-lightbox.css');用于包含 ekko-lightbox 自己的 CSS 定义。

最后,我只需要扩展我的基本 HTML 模板以在任何其他 javascript 文件之前包含新的 vendor.js 和 manifest.js:
{% block javascripts %}
<script src="{{ asset('build/manifest.js') }}"></script>
<script src="{{ asset('build/vendor.js') }}"></script>
<script src="{{ asset('build/global.js') }}"></script>
{% endblock %}

关于symfony - 带有 webpack-encore : Cannot read property 'Constructor' of undefined 的 ekko-lightbox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48521773/

相关文章:

javascript - 如何在 Symfony Controller 中使用 ajax 正确获取参数发送(注释)?

symfony - 为什么我的 jwt token 永不过期?

symfony4 - 如何使用 Webpack Encore 将 Fontawesome 5 添加到 Symfony 4

symfony - 如何在 Symfony 4 中处理 Assets

javascript - Webpack copyFiles将文件从子目录复制到主目录

webpack - Symfony 4.1 项目中的 Yarn 和 Webpack Encore 配置

php - Symfony2 JSON 示例

symfony - Composer 和 mamp ssl 扩展不能一起工作

javascript - Webpack Encore - Vuejs 测试 Mocha

php - Symfony 错误 : Attribute "Symfony\Component\Routing\Annotation\Route" cannot target function (allowed targets: class, 方法)