我想使用Symfony的webpack-encore来包含ekko-lightbox。
我在这里创建了一个有效的jsFiddle演示:https://jsfiddle.net/92vq1z2b/。它和我一样使用相同版本的bootstrap,jQuery和ekko-lightbox。
在我当地的Symfony项目中,它并不起作用。当我点击" lightboxed"我在浏览器控制台中收到以下错误:
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中的&#39; main&#39;条目先前指向.min.js文件,现在指向非缩小文件版)。我认为&#39;主要&#39;条目应始终指向目标文件而没有任何文件扩展名(它是如何在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
答案 0 :(得分:0)
经过大量调试后我解决了。问题是我如何包含jQuery和bootstrap。在我的global.js中,我明确要求jQuery进行require()
调用。但是,这是由我的.autoProvidejQuery()
中的行webpack.config.js
由webpack-encore自动执行的。此外,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,因为它们已经包含在共享模块中。全局CSS定义只剩下一个require()。
// 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 %}