我是Angular.js的新手,试图了解它与Backbone.js的区别...我们以前在使用Backbone时使用Require.js管理我们的软件包依赖项。用Angular.js做同样的事情有意义吗?
我是Angular.js的新手,试图了解它与Backbone.js的区别...我们以前在使用Backbone时使用Require.js管理我们的软件包依赖项。用Angular.js做同样的事情有意义吗?
Answers:
是的,angular.js
与require.js
将require.js
组件模块化一起使用时,这是有意义的。
有一个使用的种子项目both angular.js and require.js
。
重申一下,我认为OP的问题实际上是:
如果我主要是在Angular 1.x中构建应用程序,并且(隐式地)在Grunt / Gulp / Broccoli和Bower / NPM时代这样做,并且我可能还有其他一些库依赖项,是否需要添加明确,具体的信息是否超出了使用Angular而无需Require所获得的价值?
或者,换一种说法:
“ 如果我还有其他处理基本脚本加载的方法,香草Angular是否需要有效管理基本Angular组件加载? ”
我相信对此的基本答案是:“除非您正在做其他事情,并且/或者您无法使用更新,更现代的工具,否则不可以。”
首先,我们要弄清楚:RequireJS是一个出色的工具,它解决了一些非常重要的问题,使我们踏上了通往更可扩展,更专业的Javascript应用程序的道路。重要的是,这是许多人第一次遇到模块化的概念,并使事情脱离全球范围。因此,如果您要构建需要扩展的Javascript应用程序,那么Require和AMD模式并不是执行此操作的好工具。
但是,关于Angular有什么特别之处使Require / AMD非常合适?不会。事实上,Angular为您提供了自己的模块化和封装模式,这在许多方面都使AMD的基本模块化功能变得多余。而且,将Angular模块集成到AMD模式并不是没有可能,但这有点...有点挑剔。您肯定会花时间使这两种模式很好地集成。
从Angular团队本身的角度来看,这是Angular Batarang的作者,现在Angular核心团队的成员Brian Ford的:
我不建议将RequireJS与AngularJS一起使用。尽管确实有可能,但我还没有看到RequireJS在实践中有益的任何实例。
因此,在AngularJS的一个非常具体的问题上:Angular和Require / AMD是正交的,并且在某些地方重叠。您可以将它们一起使用,但是没有理由与Angular本身的性质/图案特别相关。
我建议检查Bower和NPM,尤其是NPM。我并不是要就这些工具的相对优势发动一场圣战。我只想说:还有其他方法可以使猫咪皮肤,并且这些方法甚至可能比AMD / Required更好。(在2015年末,它们无疑具有更受欢迎的势头,尤其是与ES6或CommonJS模块结合的NPM。请参见相关的SO问题。)
请注意,延迟加载和延迟下载是不同的。Angular的延迟加载并不意味着您直接将它们从服务器中拉出。在具有javascript自动化功能的Yeoman风格应用程序中,您将整个shebang串联在一起并缩小到一个文件中。它们存在,但是直到需要时才执行/实例化。通过这样做,您获得的速度和带宽改进大大超过了延迟下载特定20行控制器的任何所谓的改进。实际上,该控制器所浪费的网络等待时间和传输开销将比控制器本身的大小大一个数量级。
但是,假设您确实确实需要延迟下载,也许是对于不经常使用的应用程序部分(例如管理界面)。那是一个非常合理的情况。确实可以为您做到这一点。但是,还有 许多 其他的,可能 更 灵活的 选项可以完成相同的任务。Angular 2.0显然会为我们解决这个问题,它是路由器内置的。(详细信息。)
我如何才能加载所有数十个/数百个脚本文件,而无需将它们全部手动附加到index.html?
看一下Yeoman的generator-angular中的子生成器,或generator- gulp -angular中体现的自动化模式,或React的标准Webpack自动化。这些为您提供了一种干净,可扩展的方法,可以:在搭建脚手架时自动附加文件,或者在某些文件夹中存在某些文件/匹配某些glob模式时简单地自动抓取它们。一旦有了后一种选择,您就不再需要考虑自己的脚本加载。
对于某些事情,Require是一个很棒的工具。但是,只要有可能就顺其自然,并尽可能将您的关注点分开。让Angular担心Angular自己的模块化模式,并考虑使用ES6模块或CommonJS作为通用模块化模式。让现代自动化工具担心脚本加载和依赖关系管理。并且以细粒度的方式照顾异步延迟加载,而不是将其与其他两个问题缠在一起。
就是说,如果您正在开发Angular应用程序,但由于某种原因而无法在计算机上安装Node以使用Javascript自动化工具,那么Require可能是一个不错的替代解决方案。我已经看到了非常复杂的设置,人们想要动态加载每个Angular组件,每个组件声明自己的依赖关系或其他内容。尽管我可能会尝试以另一种方式解决该问题,但对于那种非常特殊的情况,我可以看到这个想法的优点。
但是否则,当从头开始使用新的Angular应用程序以及创建现代自动化环境的灵活性时,您还有许多其他更灵活,更现代的选择。
(反复更新以适应不断发展的JS场景。)
是的,这很有道理。
Angular模块不会尝试解决脚本加载顺序或延迟脚本获取的问题。这些目标是正交的,并且两个模块系统都可以并存并实现其目标。
资料来源:Angular JS官方网站
我认为这是一个主观问题,因此我将提供我的主观意见。
Angular具有内置的模块化机制。创建应用程序时,要做的第一件事是
var app = angular.module("myApp");
然后
app.directive(...);
app.controller(...);
app.service(...);
如果您看一下角度种子,它是用于角度的整洁的入门应用程序,则他们将指令,服务,控制器等分离到不同的模块中,然后将这些模块作为依赖项加载到您的主应用程序中。
就像是 :
var app = angular.module("myApp",["Directives","Controllers","Services"];
Angular也会延迟将这些模块(而不是脚本文件)加载到内存中。
对于延迟加载脚本文件而言,坦率地说,除非您要编写非常大的内容,否则这将是多余的,因为从本质上讲,角度化会减少您编写的代码量。如果使用角度编写,则在大多数其他框架中编写的典型应用程序的LOC可能会降低约30-50%。
将RequireJS与AngularJS结合使用是有意义的,但前提是您了解它们各自在依赖注入方面的工作方式,就像它们都注入依赖项一样,它们注入的东西也非常不同。
AngularJS拥有自己的依赖系统,可让您将AngularJS模块注入到新创建的模块中以重用实现。假设您创建了一个实现AngularJS过滤器“ greet”的“第一个”模块:
angular
.module('first', [])
.filter('greet', function() {
return function(name) {
return 'Hello, ' + name + '!';
}
});
现在,假设您要在另一个名为“ second”的模块中使用“ greet”过滤器,该模块实现了“再见”过滤器。您可以这样做,将“第一个”模块注入“第二个”模块:
angular
.module('second', ['first'])
.filter('goodbye', function() {
return function(name) {
return 'Good bye, ' + name + '!';
}
});
事实是,为了在没有RequireJS的情况下正常工作,您必须确保在创建“第二” AngularJS模块之前在页面上加载了“第一个” AngularJS模块。报价文件:
取决于模块意味着需要在加载需求模块之前先加载需求模块。
从这种意义上说,RequireJS可以在这里为您提供帮助,因为RequireJS提供了一种将脚本注入页面的干净方法,以帮助您组织彼此之间的脚本依赖关系。
回到“第一个”和“第二个” AngularJS模块,这是使用RequireJS将不同文件上的模块分开以利用脚本依赖项加载的方法:
// firstModule.js file
define(['angular'], function(angular) {
angular
.module('first', [])
.filter('greet', function() {
return function(name) {
return 'Hello, ' + name + '!';
}
});
});
// secondModule.js file
define(['angular', 'firstModule'], function(angular) {
angular
.module('second', ['first'])
.filter('goodbye', function() {
return function(name) {
return 'Good bye, ' + name + '!';
}
});
});
可以看到,在执行RequireJS回调的内容之前,我们依赖于要插入的“ firstModule”文件,该文件需要加载“第一个” AngularJS模块以创建“第二个” AngularJS模块。
旁注:为了在RequireJS回调函数中使用AngularJS,需要在“ firstModule”和“ secondModule”文件上注入“ Angular”作为依赖项,并且必须在RequireJS config上对其进行配置以将“ angular”映射到库代码。您可能也会以传统方式(脚本标记)将AngularJS加载到页面上(尽管失败了RequireJS的好处)。
在我的博客文章中,有关从2.0版本的AngularJS core获得RequireJS支持的更多详细信息。
根据我的博客文章“使用AngularJS感知RequireJS”,此处是链接。
正如@ganaraj提到的那样,AngularJS的核心是依赖注入。在使用和不使用RequireJS的情况下构建玩具种子应用程序时,我个人发现RequireJS对于大多数用例而言可能是过大的。
这并不意味着RequireJS对它的脚本加载功能以及在开发过程中保持代码库干净无用。将r.js优化器(https://github.com/jrburke/r.js)与杏仁(https://github.com/jrburke/almond)结合可以创建一个非常苗条的脚本加载故事。但是,由于它的依赖性管理功能对于应用程序核心中的angular并不那么重要,因此您还可以评估其他客户端(HeadJS,LABjs等),甚至服务器端(MVC4 Bundler等)脚本加载解决方案针对您的特定应用。
是的,它确实适用于大型SPA。
在某些情况下,RequireJS是必须的。例如,我使用AngularJS开发PhoneGap应用程序,该应用程序也使用Google Map API。如果没有像RequireJS这样的AMD加载程序,该应用程序将在离线时启动时崩溃,因为它无法获取Google Map API脚本。AMD加载程序使我有机会向用户显示错误消息。
但是,AngularJS和RequireJS之间的集成有些棘手。我创建了angularAMD来简化此过程:
简短的答案是,这很有意义。最近,在ng-conf 2014中对此进行了讨论。这是关于此主题的演讲:
如果计划延迟加载控制器和指令等,则可以将requirejs与angularjs结合使用,同时还将多个延迟依赖项组合到单个脚本文件中,以实现更快的延迟加载。RequireJS有一个优化工具,可以使合并变得容易。参见http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/
是的,将requireJS与Angular一起使用是有意义的,我花了几天时间测试了几种技术解决方案。
我在服务器端使用RequireJS制作了一个Angular Seed。很简单的一个。我将SHIM表示法用于没有AMD模块而不是AMD的原因,因为我认为处理两种不同的依赖注入系统非常困难。
我使用grunt和r.js在服务器上串联js文件,这取决于SHIM配置(依赖项)文件。所以我只在我的应用程序中引用一个js文件。
有关更多信息,请访问我的github Angular Seed:https : //github.com/matohawk/angular-seed-requirejs
我会避免使用Require.js。我所见过的应用程序可以完成多种类型的模块模式架构。AMD,Revealing,IIFE的不同口味等。还有其他按需加载的方法,例如loadOnDemand Angular mod。添加其他内容只会使您的代码充满混乱,并产生低信噪比,并使您的代码难以阅读。
这是我使用的方法:http : //thaiat.github.io/blog/2014/02/26/angularjs-and-requirejs-for-very-large-applications/
该页面显示了AngularJS + RequireJS的可能实现,其中代码按功能和组件类型划分。
布莱恩·福特的回答
AngularJS拥有自己的模块系统,通常不需要RJS之类的东西。