Javascript 将 Require.js 与 Angular.js 一起使用是否有意义?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12529083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 10:37:57  来源:igfitidea点击:

Does it make sense to use Require.js with Angular.js?

javascriptrequirejsangularjs

提问by Franck

I'm a newbie to Angular.js and trying to understand how it's different from Backbone.js... We used to manage our packages dependencies with Require.js while using Backbone. Does it make sense to do the same with Angular.js?

我是 Angular.js 的新手,并试图了解它与 Backbone.js 的不同之处……我们曾经在使用 Backbone 时使用 Require.js 管理我们的包依赖项。用 Angular.js 做同样的事情有意义吗?

回答by Anshu

Yes it makes sense to use angular.jsalong with require.jswherein you can use require.jsfor modularizing components.

是的,angular.jsrequire.js其中可以require.js用于模块化组件的一起使用是有意义的。

There is a seed projectwhich uses both angular.js and require.js.

有一个种子项目使用both angular.js and require.js.

回答by XML

To restate what I think the OP's question really is:

重申我认为 OP 的真正问题是:

If I'm building an application principally in Angular 1.x, and (implicitly) doing so in the era of Grunt/Gulp/Broccoli and Bower/NPM, and I maybe have a couple additional library dependencies, does Require add clear, specific value beyond what I get by using Angular without Require?

如果我主要在 Angular 1.x 中构建应用程序,并且(隐式)在 Grunt/Gulp/Broccoli 和 Bower/NPM 时代这样做,并且我可能有几个额外的库依赖项,是否需要添加明确的、特定的超出我通过使用 Angular 而没有 Require 获得的价值?

Or, put another way:

或者,换一种方式:

"Does vanilla Angular need Require to manage basic Angular component-loading effectively, if I have other ways of handling basic script-loading?"

如果我有其他处理基本脚本加载的方法,vanilla Angular 是否需要 Require 有效管理基本的 Angular 组件加载?

And I believe the basic answer to that is: "not unless you've got something else going on, and/or you're unable to use newer, more modern tools."

我相信对此的基本答案是:“除非您有其他事情要做,和/或您无法使用更新、更现代的工具,否则不会。”

Let's be clear at the outset: RequireJS is a great tool that solved some very important problems, and started us down the road that we're on, toward more scalable, more professional Javascript applications. Importantly, it was the first time many people encountered the concept of modularization and of getting things out of global scope. So, if you're going to build a Javascript application that needs to scale, then Require and the AMD pattern are not bad tools for doing that.

让我们从一开始就明确:RequireJS 是一个很好的工具,它解决了一些非常重要的问题,并让我们开始了我们所走的道路,朝着更具可扩展性、更专业的 Javascript 应用程序迈进。重要的是,这是许多人第一次遇到模块化和让事物脱离全局范围的概念。因此,如果您要构建一个需要扩展的 Javascript 应用程序,那么 Require 和 AMD 模式就不是做这件事的坏工具。

But, is there anything particular about Angular that makes Require/AMD a particularly good fit?No. In fact, Angular provides you with its own modularization and encapsulation pattern, which in many ways renders redundant the basic modularization features of AMD. And, integrating Angular modules into the AMD pattern is not impossible, but it's a bit... finicky. You'll definitely be spending time getting the two patterns to integrate nicely.

但是,Angular 有什么特别之处让 Require/AMD 成为特别合适的选择吗?不。事实上,Angular 为您提供了自己的模块化和封装模式,这在许多方面使 AMD 的基本模块化特性变得多余。而且,将 Angular 模块集成到 AMD 模式中并非不可能,但它有点......挑剔。您肯定会花时间让这两种模式很好地集成。

For some perspective from the Angular team itself, there's this, from Brian Ford, author of the Angular Batarang and now a member of the Angular core team:

对于 Angular 团队本身的一些观点,有这个来自 Brian Ford,Angular Batarang 的作者,现在是 Angular 核心团队的成员:

I don't recommend using RequireJS with AngularJS. Although it's certainly possible, I haven't seen any instance where RequireJS was beneficial in practice.

我不建议在 AngularJS 中使用 RequireJS。虽然这当然是可能的,但我还没有看到 RequireJS 在实践中有益的任何实例。

So, on the very specific question of AngularJS: Angular and Require/AMD are orthogonal, and in places overlapping. You canuse them together, but there's no reason specifically related to the nature/patterns of Angular itself.

因此,关于 AngularJS 的一个非常具体的问题:Angular 和 Require/AMD 是正交的,并且在某些地方重叠。您可以一起使用它们,但没有理由与 Angular 本身的性质/模式特别相关。

But what about basic management of internal and external dependencies for scalable Javascript applications? Doesn't Require do something really critical for me there?

但是对于可扩展的 Javascript 应用程序的内部和外部依赖项的基本管理呢?不需要在那里为我做一些真正重要的事情吗?

I recommend checking out Bower and NPM, and particularly NPM. I'm not trying to start a holy war about the comparative benefits of these tools. I merely want to say: there are other ways to skin that cat, and those ways maybe even better than AMD/Require. (They certainly have much more popular momentum in late-2015, particularly NPM, combined with ES6 or CommonJS modules. See related SO question.)

我建议查看 Bower 和 NPM,尤其是 NPM。我并不是要就这些工具的相对优势展开一场圣战。我只想说:还有其他方法可以给那只猫剥皮,这些方法可能比 AMD/Require 还要好。(它们在 2015 年末肯定有更受欢迎的势头,尤其是 NPM,结合 ES6 或 CommonJS 模块。请参阅相关的 SO 问题。)

What about lazy-loading?

延迟加载呢?

Note that lazy-loading and lazy-downloading are different. Angular's lazy-loading doesn't mean you're pulling them direct from the server. In a Yeoman-style application with javascript automation, you're concatenating and minifying the whole shebang together into a single file. They're present, but not executed/instantiated until needed. The speed and bandwidth improvements you get from doing this vastly, vastly outweigh any alleged improvements from lazy-downloading a particular 20-line controller. In fact, the wasted network latency and transmission overhead for that controller is going to be an order of magnitude greater than the size of the controller itself.

请注意,延迟加载和延迟下载是不同的。Angular 的延迟加载并不意味着您直接从服务器中拉取它们。在带有 javascript 自动化的 Yeoman 风格的应用程序中,您将整个 shebang 连接并缩小到一个文件中。它们存在,但在需要之前不会执行/实例化。您通过这样做获得的速度和带宽改进大大超过了延迟下载特定 20 线控制器所带来的任何所谓的改进。事实上,该控制器浪费的网络延迟和传输开销将比控制器本身的大小大一个数量级。

But let's say you really do need lazy-downloading, perhaps for infrequently-used pieces of your application, such as an admin interface. That's a very legitimate case. Require can indeed do that for you. But there are alsomanyother, potentiallymoreflexibleoptionsthat accomplish the same thing. And Angular 2.0 will apparently take care of this for us, built-in to the router. (Details.)

但是,假设您确实需要延迟下载,可能用于应用程序中不常使用的部分,例如管理界面。这是一个非常合法的案例。Require 确实可以为您做到这一点。但也有很多其他的可能灵活的选择是完成同样的事情。Angular 2.0 显然会为我们解决这个问题,内置在路由器中。(详情。)

But what about during development on my local dev boxen?

但是在我本地开发箱的开发过程中呢?

How can I get all my dozens/hundreds of script files loaded without needing to attach them all to index.html manually?

如何在无需手动将它们全部附加到 index.html 的情况下加载所有数十/数百个脚本文件?

Have a look at the sub-generators in Yeoman's generator-angular, or at the automation patterns embodied in generator-gulp-angular, or at the standard Webpack automation for React. These provide you a clean, scalable way to either: automatically attach the files at the time that components are scaffolded, or to simply grab them all automatically if they are present in certain folders/match certain glob-patterns. You never again need to think about your own script-loading once you've got the latter options.

查看 Yeoman 的 generator-angular 中的子生成器,或者generator-gulp -angular 中包含的自动化模式,或者 React 的标准 Webpack 自动化。这些为您提供了一种干净、可扩展的方式:在构建组件时自动附加文件,或者如果它们存在于某些文件夹中/匹配某些全局模式,则简单地自动抓取它们。一旦你有了后面的选项,你就再也不需要考虑自己的脚本加载了。

Bottom-line?

底线?

Require is a great tool, for certain things. But go with the grain whenever possible, and separate your concerns whenever possible. Let Angular worry about Angular's own modularization pattern, and consider using ES6 modules or CommonJS as a general modularization pattern. Let modern automation tools worry about script-loading and dependency-management. And take care of async lazy-loading in a granular way, rather than by tangling it up with the other two concerns.

对于某些事情,Require 是一个很好的工具。但是,只要有可能,就顺其自然,并尽可能将您的顾虑分开。让 Angular 担心 Angular 自身的模块化模式,考虑使用 ES6 模块或 CommonJS 作为通用的模块化模式。让现代自动化工具担心脚本加载和依赖项管理。并以细粒度的方式处理异步延迟加载,而不是将其与其他两个问题纠缠在一起。

That said, if you're developing Angular apps but can't install Node on your machine to use Javascript automation tools for some reason, then Require may be a good alternate solution. And I've seen really elaborate setups where people want to dynamically load Angular components that each declare their own dependencies or something. And while I'd probably try to solve that problem another way, I can see the merits of the idea, for that very particular situation.

也就是说,如果您正在开发 Angular 应用程序,但由于某种原因无法在您的机器上安装 Node 以使用 Javascript 自动化工具,那么 Require 可能是一个很好的替代解决方案。我见过非常精细的设置,人们希望动态加载 Angular 组件,每个组件都声明自己的依赖项或其他东西。虽然我可能会尝试以另一种方式解决这个问题,但我可以看到这个想法的优点,对于那个非常特殊的情况。

But otherwise... when starting from scratch with a new Angular application and flexibility to create a modern automation environment... you've got a lot of other, more flexible, more modern options.

但除此之外……当从头开始使用新的 Angular 应用程序和创建现代自动化环境的灵活性时……您有很多其他更灵活、更现代的选择。

(Updated repeatedly to keep up with the evolving JS scene.)

(反复更新以跟上不断发展的 JS 场景。)

回答by Tiago Reis

Yes, it makes sense.

是的,这是有道理的。

Angular modules don't try to solve the problem of script load ordering or lazy script fetching. These goals are orthogonal and both module systems can live side by side and fulfil their goals.

Source: Angular JS official website

Angular 模块不会尝试解决脚本加载顺序或延迟脚本获取的问题。这些目标是正交的,两个模块系统可以并存并实现它们的目标。

来源:Angular JS 官网

回答by ganaraj

This I believe is a subjective question, so I will provide my subjective opinion.

我认为这是一个主观问题,因此我将提供我的主观意见。

Angular has a modularization mechanism built in. When you create your app, the first thing you would do is

Angular 内置了模块化机制。当你创建你的应用程序时,你要做的第一件事是

var app = angular.module("myApp");

and then

进而

app.directive(...);

app.controller(...);

app.service(...);

If you have a look at the angular-seed which is neat starter app for angular, they have separated out the directives, services, controllers etc into different modules and then loaded those modules as dependancies on your main app.

如果您查看 angular-seed,它是 angular 的简洁入门应用程序,它们已将指令、服务、控制器等分离到不同的模块中,然后将这些模块作为依赖项加载到您的主应用程序上。

Something like :

就像是 :

var app = angular.module("myApp",["Directives","Controllers","Services"];

Angular also lazy loads these modules ( into memory) not their script files.

Angular 也会延迟加载这些模块(到内存中)而不是它们的脚本文件。

In terms of lazy loading script files, to be frank unless you are writing something extremely large it would be an overkill because angular by its very nature reduces the amount of code you write. A typical app written in most other frameworks could expect a reduction in around 30-50% in LOC if written in angular.

在延迟加载脚本文件方面,坦率地说,除非您正在编写非常大的内容,否则这将是一种矫枉过正,因为 angular 本质上会减少您编写的代码量。如果用 angular 编写,用大多数其他框架编写的典型应用程序的 LOC 可能会减少约 30-50%。

回答by leog

Using RequireJS with AngularJS makes sense but only if you understand how each of them works regarding dependency injection, as although both of them injects dependencies, they inject very different things.

将 RequireJS 与 AngularJS 一起使用是有道理的,但前提是您了解它们中的每一个是如何在依赖注入方面工作的,因为尽管它们都注入了依赖项,但它们注入的东西却截然不同。

AngularJS has its own dependency system that let you inject AngularJS modules to a newly created module in order to reuse implementations. Let's say you created a "first" module that implements an AngularJS filter "greet":

AngularJS 有自己的依赖系统,可以让你将 AngularJS 模块注入到新创建的模块中,以便重用实现。假设您创建了一个实现 AngularJS 过滤器“greet”的“第一个”模块:

angular
  .module('first', [])
  .filter('greet', function() {
    return function(name) {
      return 'Hello, ' + name + '!';
    }
  });

And now let's say you want to use the "greet" filter in another module called "second" that implements a "goodbye" filter. You may do that injecting the "first" module to the "second" module:

现在假设您想在另一个名为“second”的模块中使用“greet”过滤器,该模块实现了“goodbye”过滤器。您可以将“第一个”模块注入“第二个”模块:

angular
  .module('second', ['first'])
  .filter('goodbye', function() {
    return function(name) {
      return 'Good bye, ' + name + '!';
    }
  });

The thing is that in order to make this work correctly without RequireJS, you have to make sure that the "first" AngularJS module is loaded on the page before you create the "second" AngularJS module. Quoting documentation:

问题是,为了在没有 RequireJS 的情况下正常工作,您必须确保在创建“第二个”AngularJS 模块之前在页面上加载了“第一个”AngularJS 模块。引用文档:

Depending on a module implies that required module needs to be loaded before the requiring module is loaded.

依赖于模块意味着需要在加载需要的模块之前加载所需的模块。

In that sense, here is where RequireJS can help you as RequireJS provides a clean way to inject scripts to the page helping you organize script dependencies between each other.

从这个意义上说,这里是 RequireJS 可以帮助您的地方,因为 RequireJS 提供了一种将脚本注入页面的干净方法,帮助您组织彼此之间的脚本依赖关系。

Going back to the "first" and "second" AngularJS modules, here is how you can do it using RequireJS separating the modules on different files to leverage script dependencies loading:

回到“第一个”和“第二个”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 + '!';
      }
    });
});

You can see that we are depending on "firstModule" file to be injected before the content of the RequireJS callback can be executed which needs "first" AngularJS module to be loaded to create "second" AngularJS module.

你可以看到我们依赖于“firstModule”文件在RequireJS回调的内容被执行之前被注入,这需要加载“第一个”AngularJS模块来创建“第二个”AngularJS模块。

Side note: Injecting "angular" on the "firstModule" and "secondModule" files as dependency is required in order to use AngularJS inside the RequireJS callback function and it have to be configured on RequireJS config to map "angular" to the library code. You may have AngularJS loaded to the page in a traditional manner too (script tag) although defeats RequireJS benefits.

旁注:为了在 RequireJS 回调函数中使用 AngularJS,需要在“firstModule”和“secondModule”文件中注入“angular”作为依赖项,并且必须在 RequireJS 配置中配置它以将“angular”映射到库代码。您也可以以传统方式(脚本标记)将 AngularJS 加载到页面中,尽管会失去 RequireJS 的好处。

More details on having RequireJS support from AngularJS core from 2.0 version on my blog post.

有关从 2.0 版本的 AngularJS 核心获得 RequireJS 支持的更多详细信息,请参阅我的博客文章。

Based on my blog post "Making sense of RequireJS with AngularJS", here is the link.

根据我的博客文章“使用 AngularJS 理解 RequireJS”,这里是链接

回答by johlrich

As @ganaraj mentioned AngularJS has dependency injection at its core. When building toy seed applications with and without RequireJS, I personally found RequireJS was probably overkill for most use cases.

正如@ganaraj 提到的,AngularJS 的核心是依赖注入。在使用和不使用 RequireJS 构建玩具种子应用程序时,我个人发现 RequireJS 对于大多数用例来说可能是过度的。

That doesn't mean RequireJS is not useful for it's script loading capabilities and keeping your codebase clean during development. Combining the r.js optimizer (https://github.com/jrburke/r.js) with almond (https://github.com/jrburke/almond) can create a very slim script loading story. However since its dependency management features are not as important with angular at the core of your application, you can also evaluate other client side (HeadJS, LABjs, ...) or even server side (MVC4 Bundler, ...) script loading solutions for your particular application.

这并不意味着 RequireJS 对它的脚本加载功能和在开发过程中保持代码库干净没有用处。将 r.js 优化器 ( https://github.com/jrburke/r.js) 与杏仁 ( https://github.com/jrburke/almond)相结合可以创建一个非常小的脚本加载故事。然而,由于它的依赖管理功能对于应用程序核心的 angular 来说并不重要,您还可以评估其他客户端(HeadJS、LABjs 等)甚至服务器端(MVC4 Bundler 等)脚本加载解决方案适合您的特定应用。

回答by marcoseu

Yes, it does, specially for very large SPA.

是的,确实如此,特别适用于非常大的 SPA。

In some scenario, RequireJS is a must. For example, I develop PhoneGap applications using AngularJS that also uses Google Map API. Without AMD loader like RequireJS, the app would simply crash upon launch when offline as it cannot source the Google Map API scripts. An AMD loader gives me a chance to display an error message to the user.

在某些情况下,RequireJS 是必须的。例如,我使用 AngularJS 开发 PhoneGap 应用程序,同时也使用 Google Map API。如果没有像 RequireJS 这样的 AMD 加载器,应用程序在离线时会在启动时崩溃,因为它无法获取 Google Map API 脚本。AMD 加载程序让我有机会向用户显示错误消息。

However, integration between AngularJS and RequireJS is a bit tricky. I created angularAMD to make this a less painful process:

然而,AngularJS 和 RequireJS 之间的集成有点棘手。我创建了 angularAMD 来使这个过程不那么痛苦:

http://marcoslin.github.io/angularAMD/

http://marcoslin.github.io/angularAMD/

回答by Dalorzo

Short answer is, it make sense. Recently this was discussed in ng-conf 2014. Here is the talk on this topic:

简短的回答是,这是有道理的。最近在 ng-conf 2014 中讨论了这个问题。这是关于这个话题的讨论:

http://www.youtube.com/watch?v=4yulGISBF8w

http://www.youtube.com/watch?v=4yulGISBF8w

回答by Matohawk

Yes it makes sense to use requireJS with Angular, I spent several days to test several technical solutions.

是的,在 Angular 中使用 requireJS 是有意义的,我花了几天时间测试了几个技术解决方案。

I made an Angular Seed with RequireJS on Server Side. Very simple one. I use SHIM notation for no AMD module and not AMD because I think it's very difficult to deal with two different Dependency injection system.

我在服务器端用 RequireJS 制作了一个 Angular Seed。很简单的一个。我对没有 AMD 模块而不是 AMD 使用 SHIM 表示法,因为我认为处理两个不同的依赖注入系统非常困难。

I use grunt and r.js to concatenate js files on server depends on the SHIM configuration (dependency) file. So I refer only one js file in my app.

我使用 grunt 和 r.js 连接服务器上的 js 文件,这取决于 SHIM 配置(依赖项)文件。所以我在我的应用程序中只引用了一个 js 文件。

For more information go on my github Angular Seed : https://github.com/matohawk/angular-seed-requirejs

有关更多信息,请访问我的 github Angular Seed:https: //github.com/matohawk/angular-seed-requirejs

回答by ify.io

It makes sense to use requirejs with angularjs if you plan on lazy loading controllers and directives etc, while also combining multiple lazy dependencies into single script files for much faster lazy loading. RequireJS has an optimisation toolthat makes the combining easy. See http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/

如果您计划延迟加载控制器和指令等,将 requirejs 与 angularjs 结合使用是有意义的,同时还将多个延迟依赖项组合到单个脚本文件中以加快延迟加载速度。RequireJS 有一个优化工具,可以让组合变得容易。请参阅http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/