在过去的几年里,我一直在使用JavaScript的全局导入方法。通常使用一组实用程序函数,这些实用函数被包装并传递给另一个站点模块,该模块包含针对每个web功能的单独功能:
(function(m, u, ui, w, a, $){
// Example Module
m.example = function(){
// Do stuff, the m.example module gets auto initialized.
};
})(Site.modules = Site.modules || {}, Site.utils, Site.ui, Site.w, Site.anim, jQuery);在这个示例中,我传递了我们添加的模块、实用程序、用户界面对象(主要是别名gsap )和其他东西,如jQuery。
正如你所看到的,它可能变得很大,很混乱,特别是在那些有很多功能的大型网站上。
我想转到ES6和NPM,虽然我看到了几十篇关于如何制作模块、如何导入模块、引入带有NPM的模块的文章和示例,但我找不到一个实际将所有模块整合在一起的示例或文章。
一个简单的例子。我用NPM进口光滑的旋转木马。我有一个单一的网页网站,一个横幅旋转木马和一个推特。我应该如何检查这些元素的存在,并初始化两个单独的旋转木马?
使用匿名闭包,我将有一个单独的自动启动函数,它查找一个DOM元素,然后用不同的选项初始化一个旋转木马。
编辑
对于当前工作流的一个示例,我定义了一个站点对象,该对象具有多个重用的静态变量和在站点中重用的一些项,例如动画变量、对窗口的引用、访问视图属性的自动更新变量等。
然后,在一个单独的文件中,对于每个构建的网站,我有一个主文件,在这个文件中,我为站点上实现的每个功能块创建了单独的“模块”。利用页面中包含的jQuery和普通JavaScript插件以及utils和主js文件。
utils.js
jQuery(document).ready(function($) {
Site.init();
});
var Site = (function($) {
// DOM caching
var win = window;
// Globals
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(){
... example check cookies for marker and show cookie notice if not present.
}
... rest of the websites js, maps, menus, custom reused items etc
})(Site.modules = Site.modules || {}, jQuery);发布于 2017-11-29 12:57:14
不要以“一切都是全球性”的方式思考。全局范围是最大的js设计错误之一。例如:
var name = 1;
console.log(name + 1); // 2, right? No, try it ...
我不认为全球范围是完全无用的,但它的用途是非常有限的。您应该将其视为网页/服务器状态。这意味着在最好的情况下,它不应该包含任何代码(=函数)。您向全局范围公开的功能(代码)越多,您就越有可能在两个脚本之间产生错误的推断,而这些错误确实很难发现。相反,您的代码应该封装自己。它应尽可能少地暴露和改变全球范围。这意味着,如果您希望在页面的两个不同文件之间共享某个功能(例如,menu.js和slider.js都需要一个Button类),则该功能应该进入一个模块,然后由两个脚本导入该模块。因此,每个单独的文件都应该有顶部的导入和最后的导出,并且应该封装自己:
import {functionality1, functionality2} from "module";
let somevariable; // variables declared with let or const do not appear on the global scope, although they are "global"不要害怕在同一页的不同文件中多次导入相同的模块。模块只加载一次,并使用树抖动(大多数捆绑器,如Webpack这样做),仅仅从一个大模块中包含几个函数可能甚至不是加载整个大模块,而是加载其中的几个块。
https://stackoverflow.com/questions/47552610
复制相似问题