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

你如何组织整个网站的大型JS / jQuery代码库? 关于如何组织你的代码有很多很好的资源,但没有什么关于如何把它们放在一起,使每一块都适合:侧面广泛的代码组织,多个页面使用相同的代码,保持DRY与松耦合,等等

以下是我如何处理它。 我从来没有像我这样习惯于组织我的代码,因为我认为这是蛮横的,可能导致可维护性/扩展性问题,但是我并不知道更好。

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

我想我真的想要:

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

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

  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%的代码是require()一个小部件并启动它。

我使用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(){ } } }; 

为了帮助我回答您的具体问题,请允许我谈谈JavaScriptMVC的一些function:

控制器将改善你的jQuery小部件,照顾设置/拆卸,可扩展性。

查看添加可以内置到您的应用程序的客户端模板。

模型抽象服务/数据层,如果服务器发生变化,则最小化和本地化JS更改。

偷取依赖pipe理,压缩和代码清理。 它甚至会将所有的脚本放在所有页面上,找出共享的依赖关系,并将脚本合并到一个最佳的有效载荷中。

FuncUnit使testing您的应用程序尽可能简单。

DocumentJS …呃…logging你的代码

现在就您的具体问题:

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

我使用StealJS的依赖pipe理系统将我需要的function加载到我的页面中。 在一定规模的应用程序中依赖pipe理是绝对必要的。 如果您能够轻松构build它,RequireJS是一个不错的select。

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

页面特定的代码应尽可能小。 它通常涉及加载依赖和一个“MainController”。 主控制器将页面configuration为服从该页面的function/业务需求。 通常命名空间是这样的:

 App.Controllers.Main 

你怎么停止写相同的模式

那么,我build议使用一个稳定的发展模式的框架。 此外,保持你的模块/插件/小部件尽可能小(和可testing)。 这将使这些部件更不可能改变。

最后….

看来你最大的争斗之间的紧张:

  • 共享function
  • 多个页面
  • 及时加载时间

所以select一个可靠的依赖pipe理工具是非常关键的。 StealJS可以帮助您获得最佳的加载时间,但由于页面数量较多,您必须偏离JavaScriptMVC的标准文件夹组织。

RequireJS更灵活,但你将不得不加载大量的文件。 这不仅会很慢,这将开始让你创build大量的不是很有组织的大JS文件。

如果您对加载时间感到满意,并且觉得他们不会让您将代码压缩到不属于的文件中,那么您现在的解决scheme似乎可以工作。

我认为可维护开发的秘诀是你的系统/框架如何轻松地隔离问题。 将应用分解成尽可能最小的部分非常重要。 另外,你应该testing这些部分。 人们通过思考他们的页面function而受到追踪。 但是为了真正扩展开发,你真的需要一些东西,让你把应用程序分解成小部分,轻松加载这些部分,并且让应用程序在生产中运行得更快。