In recent years, my approach to JavaScript development has involved using the global import method. Typically, I work with a set of utility functions packaged and passed to a separate site module containing individual functions for each web functionality:
(function(m, u, ui, w, a, $){
// Sample Module
m.example = function(){
// Perform actions, the m.example module is automatically initialized.
};
})(Site.modules = Site.modules || {}, Site.utils, Site.ui, Site.w, Site.anim, jQuery);
In this scenario, I pass on various modules that we extend, utilities, user interface object (often aliased gsap), and other dependencies like jQuery.
However, as these projects grow in size, the process can become cumbersome and messy.
I am now considering transitioning to ES6 and using NPM. While there are numerous resources available on creating and importing modules, as well as utilizing NPM, I have yet to find detailed guidance on bringing everything together.
For instance, if I import slick-carousel via NPM and want to incorporate two distinct carousels on a single-page website - a banner carousel and a tweet carousel - how should I verify the existence of these elements and initialize the carousels separately?
In the past, using an anonymous closure, I would create auto-initialized functions individually looking up DOM elements and initializing carousels with unique options.
Edit
To illustrate my current workflow, I establish a site object with reusable static variables and shared items across the project such as animation variables, window references, and auto-updating variables for viewport properties access.
Subsequently, within a dedicated file specific to each developed website, I define the main structure where distinct 'modules' are created for each functional aspect implemented on the site. This involves employing jQuery alongside plain JavaScript plugins embedded on the page, along with utility and primary JS files.
utils.js
jQuery(document).ready(function($) {
Site.init();
});
var Site = (function($) {
// DOM caching
var win = window;
// Global items
var w = {
width: win.innerWidth,
height: win.innerHeight,
scroll: win.pageYOffset
};
var ui = {
fast: 0.2,
slow: 0.4,
step: 0.03,
easeout: Power4.easeOut,
easein: Power4.easeIn
};
function updateGlobals(){
w.width = win.innerWidth;
w.height = win.innerHeight;
w.scroll = win.pageYOffset;
}
win.addEventListener('resize', updateGlobals, true);
win.addEventListener('scroll', updateGlobals, true);
win.addEventListener('load', updateGlobals, true);
return {
init: function(){
for (var prop in this.modules) {
if ( this.modules.hasOwnProperty(prop) ) {
this.modules[prop]();
}
}
for (var props in this.autoInits) {
if ( this.autoInits.hasOwnProperty(props) ) {
var $selector = $(props);
if ($selector.length) {
this.autoInits[props]($selector);
}
}
}
},
ui: ui,
w: w
};
})(jQuery);
main.js
(function(m, $){
m.homepageCarousel = function(){
var element = $('.js-homepage-carouel');
$(element).slick({
dots: true,
speed: 500,
arrows: false
});
};
m.productsCarousel = function(){
var element = $('.js-products-carouel');
$(element).slick({
dots: false,
speed: 500,
arrows: true
});
};
m.showcookieNotice = function(){
... logic to check cookies for a marker and display cookie notice if not present.
}
... handling additional website functionalities like maps, menus, custom elements, etc.
})(Site.modules = Site.modules || {}, jQuery);