您如何在整个网站上组织大型JS/jQuery代码库? [英] How do you organize large JS/jQuery code bases across your entire website?

查看:61
本文介绍了您如何在整个网站上组织大型JS/jQuery代码库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您如何在整个网站上组织大型JS/jQuery代码库?关于如何组织代码段,有很多不错的资源,但是关于如何将它们全部组合到一起并适合每个部分的内容,并没有真正的意义:侧边的代码组织,使用同一代码的多个页面,保持松散耦合的DRY,等

How do you organize large JS/jQuery codebases across your entire website? There are plenty of good resources on how to organize pieces of your code, but nothing really about how to pull it all together and fit each piece into place: side wide code organization, multiple pages using the same code, staying DRY with loose coupling, etc.

下面是我的处理方式.我从来没有像这样组织过我的代码,因为我认为它太草率并且可能导致可维护性/扩展性问题,但是我真的不知道更好.

Below is how I deal with it. I've never been comfortable organizing my code like this, because I think it's sloppy and can lead to maintainability/scaling problems, but I don't really know any better.

我意识到我每个人都有自己的一套要求,也没有交钥匙的解决方案,但是我很乐意听到一些关于我做错了什么,为什么做错了为什么的意见以及关于如何做的建议编写更多可维护的代码.

I realize I everyone has their own set of requirements and there’s no turn-key solutions, but I’d love to hear some opinions about what I’m doing wrong, WHY I’m doing it wrong, and suggestions on how to write more maintainable code.

我认为我真正想得到的是:

What I think I’m really trying to get at:

  1. 您如何处理自己的逻辑 需要在多个地方使用 多页?

  1. How do you deal with logic that you need to use in multiple places, on multiple pages?

如何组织特定页面 代码?将每个页面命名为 一个全局对象是一个好主意吗?1.

How do you organize page-specific code? Is namespacing each page into a global object a good idea?1.

从一开始到现在你做什么? 确保您不经常 重新编写您的组织 随着您的应用程序变大的模式 和更大?我大概是四号 反复写这个东西2.

What do you do from the start to ensure you’re not constantly re-writing your organization patterns as your app grows larger and larger? I’m probably on my 4th iteration writing this thing.2.

每个页面都会收到主要的application.js文件.每个其他页面都有自己的页面 application.pagename.js文件.我使用服务器端逻辑来包含文件(首先检查以查看 如果该页面甚至存在一个页面-有些页面不需要JS),然后按顺序对其进行初始化.

Each page receives the main application.js file. Each additional page has it's own application.pagename.js file. I use server side logic to include the files (first checking to see if one even exists for the page - some pages don't need JS), and then init them in order.

所以我的主页看起来像:

So my home page looks like:

<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页,还有很多子页面,每个子页面都需要自己的逻辑.请参阅本文中的最后一个示例.

my URL convention is /page/subpage/id/. I have about 10 pages and a whole slew of subpages, each subpage requiring their own logic. see the last example in this post.

我的大多数代码已经模块化到jQuery UI小部件或jQuery插件中,因此我想说这些文件中的代码中有75%是require()'小部件并初始化它.

Most of my code is already modularized into either jQuery UI widgets or jQuery plugins, so I'd say 75% of the code in these files is require()'ing a widget and initing it.

我根据需要使用requireJS插入小部件.

I use requireJS to pull in widgets as necessary.

// 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(){
        }
    }
};

推荐答案

为帮助我回答您的特定问题,请允许我稍微介绍一下

To help me answer your specific questions, please allow me talk a little about JavaScriptMVC's features:

控制器将改善您的jQuery小部件,并注意设置/拆卸,可扩展性.

Controller will improve your jQuery widgets, taking care of setup / teardown, extensibility.

视图添加了可以内置到您的应用中的客户端模板.

View adds client side templates that can be built into your app.

模型对服务/数据层进行抽象,以在服务器发生更改时将JS更改最小化和本地化.

Model abstracts the service / data layer minimizing and localizing JS changes if your server changes.

隐藏 进行依赖项管理,压缩和代码打扫.甚至可以将您所有页面上的所有脚本都带走,找出共享的依存关系,并将脚本组合成最佳的有效负载.

Steal does dependency management, compression, and code cleaning. It will even take all your scripts across all your pages, figure out shared dependencies, and combine scripts into an optimal payload.

FuncUnit 可以测试您的应用尽可能简单.

FuncUnit makes testing your apps as easy as possible.

DocumentJS ... ... ... ...记录您的代码

DocumentJS ... well ... documents your code

.

现在就您的具体问题:

如何处理多个地方使用的逻辑?

我使用StealJS的依赖关系管理系统将所需的功能加载到页面中.依赖管理对于一定大小的应用程序是绝对必要的.如果您能够轻松构建它,那么RequireJS是一个不错的选择.

I use StealJS's dependency management system to load the functionality I need into my page. Dependency management is absolutely necessary on apps of a certain size. RequireJS is a good choice if you are able to build it easily.

如何组织页面特定代码

页面特定代码应尽可能小.它通常涉及加载依赖项和"MainController".该主控制器将页面配置为服从该页面的功能/业务要求.通常将其命名为:

Page specific code should be as small as possible. It typically involves loading dependencies and a "MainController". That main controller configures the page to obey the functional / business requirements of that page. It's typically namespaced as something like:

App.Controllers.Main

如何停止编写相同的模式

嗯,我建议使用一个具有稳定开发模式的框架.另外,请保持模块/插件/小部件尽可能的小(可测试).这将使这些零件的更改可能性降低.

Well, I suggest using a framework that has stable patterns for development. Also, keep your modules / plugins / widgets as small (and testable) as possible. This will make these parts much less likely to change.

最后....

您之间最大的矛盾似乎是

It seems your biggest struggle tension between:

  • 共享功能
  • 多页
  • 及时加载时间

因此,选择可靠的依赖性管理工具至关重要. StealJS可以帮助您获得非常理想的加载时间,但是由于页面数量较多,您不得不偏离JavaScriptMVC的标准文件夹组织.

So picking a solid dependency management tool is super critical. StealJS could help you get very optimal loading times, but you'd have to stray from JavaScriptMVC's standard folder organization due to your larger number of pages.

RequireJS更加灵活,但是您将不得不加载很多文件.这不仅会很慢,而且这将开始使您创建很多不是非常有条理的大型JS文件.

RequireJS is more flexible, but you're going to have to load a lot of files. Not only will this be slow, this is going to start making you create lots of big JS files that aren't very organized.

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

If you are happy with the loading times and feel like they won't cause you to squeeze code into files it doesn't belong, your current solution seems like it will work.

我认为可维护开发的秘诀是您的系统/框架使您能够轻松地隔离问题.将您的应用分解成尽可能小的部分非常重要.另外,您应该测试这些零件.人们会因为考虑其页面功能而陷入困境.但是要真正扩展开发规模,您确实需要一些东西,使您可以将您的应用程序分解成小部分,轻松地加载这些部分,并以某种方式使该应用程序在生产中仍能快速运行.

I think the secret to maintainable development is how easy your system/framework allows you to isolate concerns. It's important to break up your app into the smallest parts possible. Plus, you should be testing these parts. People get side-tracked by thinking about their pages functionality. But to really scale development you really need something that allows you to break up your app into little parts, load those parts easily, and somehow get the app to still run fast in production.

这篇关于您如何在整个网站上组织大型JS/jQuery代码库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆