首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将全局导入模块模式转换为ES6模块

将全局导入模块模式转换为ES6模块
EN

Stack Overflow用户
提问于 2017-11-29 12:13:14
回答 1查看 1.1K关注 0票数 3

在过去的几年里,我一直在使用JavaScript的全局导入方法。通常使用一组实用程序函数,这些实用函数被包装并传递给另一个站点模块,该模块包含针对每个web功能的单独功能:

代码语言:javascript
复制
(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

代码语言:javascript
复制
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

代码语言:javascript
复制
(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);
EN

回答 1

Stack Overflow用户

发布于 2017-11-29 12:57:14

不要以“一切都是全球性”的方式思考。全局范围是最大的js设计错误之一。例如:

代码语言:javascript
复制
    var name = 1;
    console.log(name + 1); // 2, right? No, try it ...

我不认为全球范围是完全无用的,但它的用途是非常有限的。您应该将其视为网页/服务器状态。这意味着在最好的情况下,它不应该包含任何代码(=函数)。您向全局范围公开的功能(代码)越多,您就越有可能在两个脚本之间产生错误的推断,而这些错误确实很难发现。相反,您的代码应该封装自己。它应尽可能少地暴露和改变全球范围。这意味着,如果您希望在页面的两个不同文件之间共享某个功能(例如,menu.js和slider.js都需要一个Button类),则该功能应该进入一个模块,然后由两个脚本导入该模块。因此,每个单独的文件都应该有顶部的导入和最后的导出,并且应该封装自己:

代码语言:javascript
复制
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这样做),仅仅从一个大模块中包含几个函数可能甚至不是加载整个大模块,而是加载其中的几个块。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47552610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档