我想使用 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/