6

我目前正面临关于 javascript 名称空间的争论,我需要社区意见。

场景: 负责这个项目的架构师不知何故致力于 RequireJS 并且真的想使用它。

我必须说,该应用程序是一个后台,布局为一个向导,所以你需要在 6 个页面上来回切换,其中包含一些复杂的业务逻辑,最后填写一些我可以在这里描述为流程请求的内容。

好的,没有单页应用程序对这些问题没有任何兴趣。普通的后台 Web 应用程序,多页面,具有非常复杂的 UI,其中每个页面都向服务器请求,并且所有资源(css、javascript 等)都必须在页面加载时加载。

主要问题:了解我们正在谈论的应用程序类型,为什么首先需要 RequireJS?

第二个问题:为什么要说服 javacript 中命名空间的最佳方法是使用 RequireJS?我错过了什么吗?

我的观点: 对我来说这根本没有意义。在这里使用RequireJS很麻烦,因为没有资源是按需加载的,它们都是在页面加载时加载的(只是因为我们在页面加载时都需要它们)。我们至少需要支持 IE8、Chrome、Firefox 和 Opera,而且我们已经在所有这些浏览器上加载资源时遇到了很多麻烦。已经有很多技巧可以确保通过 Require 加载所有内容。

对于命名空间来说,情况更糟。当然可以,但同样,对我来说似乎很麻烦,而且在这件事上实际上非常有限。

所以我错过了什么吗?我需要第三种(或第 100 种)意见。

  • 你觉得这怎么样?
  • 你用什么?
  • 为什么?

提前致谢

4

4 回答 4

4

AMD 加载程序(RequireJS 就是其中之一)解决了不同的问题:

  • 适当的模块化,关注点分离
  • 无全球污染
  • 没有名字冲突
  • 按需加载或部署前优化
  • 取决于加载器,用于解决高级问题的插件,例如本地化资源或加载时编译

我是此类加载器的忠实拥护者,发现它们对除非常小的单页应用程序之外的所有应用程序都很有用。

于 2012-12-17T20:42:47.307 回答
3

无论它是否是“单页应用程序”,RequireJS 在开发客户端 JavaScript 时有助于解决两件在没有大量开发人员纪律的情况下不容易做到的事情:

生产与开发环境

到目前为止,将 JavaScript 应用程序拆分为逻辑上类似于应用程序不同部分的文件是常识。更容易调试和维护。然而,在生产中,传送许多未压缩的文件对性能不利。因此,您将所有文件连接成一个文件,将其缩小(例如,使用 Google 闭包编译器),然后将其作为单个 gzip 压缩文件发送。使用命令行工具(例如使用GruntJS )有许多不同的方法可以做到这一点,但是如果没有像 RequireJS 这样的脚本加载器,您必须以某种方式为两个不同的用例设置页面(将所有开发文件引用为脚本标签或单个生产.js) 你自己。RequireJS 有一个 NodeJS 构建工具,可以为您完成所有这些工作。

模块化

现在将代码保存在单独的文件中就很好了。但是由于 JavaScript 的性质和一切都是全局的,这意味着您仍然可能会遇到奇怪的事情,例如名称冲突。这就是命名空间派上用场的地方。但更好的选择是将所有内容包装到它自己的函数中(它引入了自己的范围)。这就是为什么大多数 JavaScript 代码都采用自执行匿名函数的原因。如果这个函数现在返回一个 API,它想公开你有 web 模块。您可以独立于应用程序测试您的模块 API,并在其他地方重新使用它。

还可以阅读 RequireJS 文档的Why Web Modules部分。

于 2012-12-17T20:44:34.763 回答
2

在我个人看来,使用 javascript 模块系统几乎从来都不是一个坏主意。Requirejs 也不是唯一可能的 javascript 模块加载器(但可能是最流行的一个)。一些替代品是 LABjs 或 HeadJS。

这些加载程序通常很容易使用(一开始并没有太多麻烦),但是当项目变得越来越大时会很有帮助。它们避免了全局空间中的命名冲突,还可以通过最小化/优化模块来支持您的部署步骤。最重要的事实是它们允许您编写更模块化的 JavaScript 代码。

  • 你有一些实用功能吗?只需创建一个实用程序模块。
  • 您在所有页面上都有一些您需要的功能?将它们放在一个公共模块中。
  • 有些页面需要很多特定的 javascript 代码?为这些页面创建一个额外的模块,这样您就不必在其他页面上加载此代码。
于 2012-12-17T20:44:10.800 回答
0

我目前防止污染全球环境和名称冲突的解决方案是使用$.extend.

文件系统树如下所示:

RootFolder
  +-> js
  global.js
  ...
   +-> views
       index.js
       page1.js
       page2.js
       ...
index.html
page1.html
page2.html

所以它通常是一个 global.js 文件,其中包含所有应用程序共享代码和每个页面的另一个特定代码。

对于命名空间,我喜欢 $.extend 所以在每个 js 文件上我都有类似的东西:

var app = app || {};  

/* only one document ready block per view if needed */
$(document).ready(function(){
    /* initialization code */
});

/* extend the app namespace with the Page1 code */
$.extend(app, {
    page1: {
        SayHi: function SayHi(name){
            alert('Hi ' + name);
        }
    }
});

因此,您可以通过调用以下方式访问您的代码:

app.page1.SayHi("Alex");

使用这种技术,您:

  • 完全控制您的代码。没有您无法完全控制的神奇资源加载和花哨的东西。
  • 无全球环境污染
  • 没有命名冲突
  • 命名空间树可以任意深,您是自己复杂性的所有者。
  • 你可以有几个 js 文件,它们实际上贡献于同一个命名空间级别。这对辅助工具特别有用。
  • 根据您在页面上包含的 javascript 文件,您可以拥有更大或更小的应用名称空间。

结论:

Web 环境真的很简单,我们不应该把它复杂化。

我不是在使用 RequireJS,不要误会我的意思。它做了它的本意(本质上是纯粹的资源延迟加载)。其他一切都是包装随附的东西,但也可以以更清洁和透明的方式实现。

因此,如果我不需要主要功能,则使用它毫无意义。

干杯!

于 2012-12-18T09:07:12.213 回答