代码之家  ›  专栏  ›  技术社区  ›  ehynds

如何在整个网站上组织大型JS/JQuery代码库?

  •  42
  • ehynds  · 技术社区  · 16 年前

    如何在整个网站上组织大型JS/JQuery代码库?关于如何组织代码片段,有很多很好的资源,但是对于如何将它们全部拉到一起并将每一个片段放在适当的位置却没有真正的帮助:横向代码组织、使用同一代码的多个页面、使用松耦合保持干燥等等。

    下面是我如何处理它。我从来没有像这样舒适地组织我的代码,因为我认为它是草率的,可能会导致可维护性/可伸缩性问题,但我真的不太清楚。

    我意识到我每个人都有自己的要求,而且没有交钥匙解决方案,但是我想听听关于我做错了什么,为什么我做错了,以及关于如何编写更易于维护的代码的建议。

    我想我真正想了解的是:

    1. 你如何处理你的逻辑 需要在多个地方使用,打开 多页?

    2. 如何组织特定页面 代码?每一页的名称间距 全局对象是个好主意?1。

    3. 你从一开始做什么 确保您不经常 重新编写组织 应用程序变大时的模式 更大?我可能在第四天 迭代写这个东西。

    每个页面接收主application.js文件。每增加一页都有自己的 application.pagename.js文件。我使用服务器端逻辑来包含文件(首先检查 如果页面中甚至存在一个页面-有些页面不需要JS),然后按顺序初始化它们。

    所以我的主页看起来像:

    <script src="js/application.js"></script>
    <script src="js/application.index.js"></script>
    <script>
        MyApp.init();
        MyApp.index.init();
    </script>
    

    我的URL约定是/page/subpage/id/。我有大约10页和一大堆子页,每个子页都需要自己的逻辑。请参阅本文中的最后一个示例。

    我的大部分代码已经模块化为jquery ui小部件或jquery插件,所以我想说这些文件中75%的代码都需要()创建一个小部件并初始化它。

    我使用RequireJS根据需要拉入小部件。

    // application.js
    var MyApp = {
        init: function(){
            var self = this;
    
            // these widgets are available on every single page
            // notice the call to jquery.deparam.js - i'll use this later to init subpage logic.
            require(['js/widget1.js', 'js/widget2.js', 'js/widget3.js', 'js/jquery.deparam.js'], function(){
    
                // deparam the query string.  I'll use this later.
                self.querystring = $.deparam.querystring();
    
                // init widgets once the document is ready
                $(function(){
                    $("#widget1").widget1();
                    $("#widget2").widget2();
    
                    // make these bindings available immediately as well.
                    self.rebindable();
                });
            });
        },
    
        // I use jQuery UI Dialog extensively as a window manager, and each dialog is loaded
        // via an AJAX request.  I'll call this method after each AJAX request to
        // rebind some key widgets.
        rebindable: function(){
            $("#widget3").widget3();
        }
    };
    
    // application.index.js
    // home page specific stuff.  this file is only included on the home page.
    MyApp.index = {
    
        // my convention is that init is automatically called after the script
        // is included in a page, outside of a doc.ready statement.
        init: function(){
            var self = this;
    
            require(['js/widget4.js'], function(){
                $(function(){
                    self.widget4( $("#foo") );
                });
            });
        },
    
        // passing elements to each method allows me to call this init code
        // outside of the index page.  I can require() this file, and only init
        // widget4, and even use a different element.
        widget4: function( element ){
            var config = {
                something: "custom to the home page"
            };
    
            element.widget4( config );
        }
    };
    
    
    // application.foo.js
    // page "foo" stuff
    MyApp.foo = {
    
        init: function(){
            var self = this;
    
            // this page happens to use the same widget3 and configuration present 
            // in MyApp.index.  this is where things can get sloppy and unmaintainable
            // really quickly.
            require(['js/application.index.js'], function(){
                $(function(){
                    MyApp.index.widget3( $("#bar") );
                });
            });
    
            // page "foo" has three subpages (or actions) and require
            // their own logic.  url convention:  /foo/subpage1/
            // init whichever page we're on...
            switch( self.querystring.subpage ){
                case "subpage1":
                    self.subpage1.init();
                    break;
                case "subpage2":
                    self.subpage2.init();
                    break;
                case "subpage3":
                    self.subpage3.init();
                    break;
            }
        },
    
        subpage1: function(){
            init: function(){
                var self = this;
    
                // once the DOM is ready init dialog.
                $(function(){
                    self.dialog( $("#openDialog") );
                });
            },
    
            dialog: function( element ){
                element.bind("click", function(){
                    $('<div></div>').dialog({
                        open: function(){
    
                            // see what i'm doing here?
                            MyApp.rebindable();
    
                            // maybe more bindings specific to this
                            // dialog here
                        }
                    });
                });
            }
        },
    
        subpage2: function(){
            init: function(){
            }
        },
    
        subpage3: function(){
            init: function(){
            }
        }
    };
    
    1 回复  |  直到 14 年前
        1
  •  12
  •   Justin Meyer    16 年前

    为了帮助我回答你的具体问题,请允许我谈谈 JavaScriptMVC 特点:

    控制器 将改进jquery小部件,注意设置/拆卸和可扩展性。

    视图 添加可内置到应用程序中的客户端模板。

    模型 抽象服务/数据层,在服务器更改时最小化和本地化JS更改。

    Steal 执行依赖项管理、压缩和代码清理。它甚至会将您的所有脚本跨越所有页面,找出共享的依赖项,并将脚本组合成一个最佳的负载。

    FuncUnit 使测试应用程序尽可能简单。

    文档JS …好。。。记录您的代码

    .

    现在,关于您的具体问题:

    如何处理多处使用的逻辑?

    我使用stealjs的依赖关系管理系统将我需要的功能加载到我的页面中。在一定规模的应用上,依赖性管理是绝对必要的。如果您能够轻松构建,那么RequireJS是一个不错的选择。

    如何组织特定于页面的代码

    页面特定代码应尽可能小。它通常包括加载依赖项和“主控制器”。主控制器将页面配置为遵守该页面的功能/业务要求。它的名称空间通常如下所示:

    App.Controllers.Main
    

    你怎么停止写同样的模式?

    我建议使用一个具有稳定开发模式的框架。此外,尽可能保持您的模块/插件/小部件小(并且可以测试)。这将使这些部件更不可能发生变化。

    最后…

    似乎你最大的斗争压力是:

    • 共享功能
    • 多页
    • 及时加载次数

    因此,选择一个可靠的依赖性管理工具是非常关键的。stealjs可以帮助您获得非常理想的加载时间,但是由于页面数量较大,您必须偏离javascriptmvc的标准文件夹组织。

    RequireJS更加灵活,但是您需要加载很多文件。这不仅会很慢,而且会让您创建许多不太有组织的大型JS文件。

    如果您对加载时间感到满意,并且认为它们不会导致您将代码压缩到不属于它的文件中,那么您当前的解决方案似乎可以工作。

    我认为可维护开发的秘密在于您的系统/框架允许您隔离关注点的容易程度。把你的应用程序分成尽可能小的部分是很重要的。另外,您应该测试这些部件。人们通过思考他们的页面功能而得到侧线跟踪。但是要真正扩展开发,你真的需要一些东西,可以让你把你的应用分成几个小部分,轻松地加载这些部分,并且以某种方式让应用在生产中仍然运行得很快。