I was tasked to implement requireJS architecture in an existing project. The project is a single page app, though it has another page for order form. After some documentation lurking and experimentation I was able to get the ball rolling.
But my happines soon faded, as I realised it does not work as expected. When page is reloaded sometimes it works and other times throws an error:
Uncaught TypeError: $beforeafter.beforeAfter is not a function
I wrote my config file (also 'data-main' entry point in html script tag) as follows:
config.js:
// RequireJS configuration, see http://requirejs.org/docs/api.html#config
require.config({
// TODO: set the right path and clean up all the '../../' nonsense
baseUrl: '',
paths: {
// Vendor JavaScript
jquery: "../../node_modules/jquery/dist/jquery",
jqueryui: "../../src/vendor/jquery-ui/jquery-ui",
bootstrap: "../../node_modules/bootstrap/dist/js/bootstrap",
jquerycookie: "../../node_modules/jquery.cookie/jquery.cookie",
owlcarousel: "../../node_modules/owl.carousel/dist/owl.carousel",
jquerybrowser: "../../node_modules/jquery.browser/dist/jquery.browser",
beforeafter: "../../src/vendor/before-after/jquery.beforeafter-1.4",
upload: "../../src/vendor/requirejs-upload/upload",
touchpunch: "../../src/vendor/touch-punch/jquery.ui.touch-punch",
// Our custom modules
main: "../../src/js/modules/main",
gallery: "../../src/js/modules/gallery",
form: "../../src/js/modules/form"
},
shim: {
"jqueryui": {
exports: "ui",
deps: ["jquery"]
},
"bootstrap": {
deps: ["jquery"]
},
"owlcarousel": {
deps: ["jquery"]
},
"beforeafter": {
deps: ["jquery", "jqueryui"]
},
"touchpunch": {
deps: ["jquery", "jqueryui"]
}
}
});
// Start the application
require(['main']);
I think this error has something to do with AMD non-compatible scripts (beforeAfter) and shim settings, but it could as easily have something to do with the way I used require()
and define()
therefore I'm including the rest of the structure:
modules/main.js:
define(['jquery', 'jquerycookie', 'bootstrap', 'touchpunch', 'gallery',
'form', 'owlcarousel'],
function ($, jquerycookie, bootstrap, touchpunch, gallery, form, owlcarousel) {
var menuItems = undefined;
// + a lot of other variables
function setUsersDeviceWidth() {
// some code and a lot of other functions after this one
}
function resizeCarousel() {
// this is where I use my custom module (gallery.js) and this works normally
gallery.resizeCarousel($this);
}
// This file also holds and executes jQuery .ready function
$(document).ready(function(){
// I use my model again, it's working
gallery.initializeCarousel();
// + a lot of other code
});
});
And module that throws the error:
modules/gallery.js
define(['jquery', 'touchpunch', 'owlcarousel', 'beforeafter'],
function ($, touchpunch, owlcarousel, beforeafter) {
var carousel = $('#carousel');
// function for initialisation in main.js, part of return object
var initializeCarousel = function() {
// 'owlcarousel' modules 'owlCarousel()' function works like it should
carousel.owlCarousel(options);
// it also initialises beforeAfter, where the problem occurs
initializeBeforeAfter($item);
});
var initializeBeforeAfter = function($item) {
// Only do this once!
if (!$item.hasClass('already-done')) {
// Initalize the beforeAfter plugin
var $beforeafter = $item.find('.before-after');
// Root of my problem; cannot refer to beforeAfter() function
// of 'beforeafter' module, loading sequence gets messed up?
$beforeafter.beforeAfter({
showFullLinks: false,
imagePath: 'dist/images/before-after/'
});
resizeBeforeAfter($item);
$beforeafter.mousemove(function(e) {
var $this = $(this);
var $thishandle = $($this.find('.ui-draggable-handle'));
var $thisfirst_wrapper = $($beforeafter.find(
'> div:not(".ui-draggable-handle")')[0]);
var mouseX = e.pageX - $(this).offset().left;
$thishandle.stop().animate({'left': mouseX - 2}, 0, 'linear');
$thisfirst_wrapper.stop().animate({'width': mouseX - 2}, 0, 'linear');
});
$item.addClass('already-done');
}
}
return {
initializeCarousel: initializeCarousel,
resizeCarousel: resizeBeforeAfter
};
});
I would appreciate any help, would also ask for advice regarding require() and define() usage in this project. Should I apply different calling structure? I've read a lot on the subject, but I can effectively learn only from live case examples :(