Does it make sense to use Require.js with Angular.js? [closed] - javascript

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
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?

Yes it makes sense to use angular.js along with require.js wherein you can use require.js for modularizing components.
There is a seed project which uses both angular.js and require.js.

To restate what I think the OP's question really is:
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?
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?"
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.
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.
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:
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.
So, on the very specific question of AngularJS: Angular and Require/AMD are orthogonal, and in places overlapping. You can use them together, but there's no reason specifically related to the nature/patterns of Angular itself.
But what about basic management of internal and external dependencies for scalable Javascript applications? Doesn't Require do something really critical for me there?
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 may be 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.)
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.
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 also many other, potentially more flexible options that accomplish the same thing. And Angular 2.0 will apparently take care of this for us, built-in to the router. (Details.)
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?
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.
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.
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.
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.
(Updated repeatedly to keep up with the evolving JS scene.)

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

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
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.
Something like :
var app = angular.module("myApp",["Directives","Controllers","Services"];
Angular also lazy loads these modules ( into memory) not their script files.
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.

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.
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":
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:
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:
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.
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:
// 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.
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.
More details on having RequireJS support from AngularJS core from 2.0 version on my blog post.
Based on my blog post "Making sense of RequireJS with AngularJS", here is the link.

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.
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.

Yes, it does, specially for very large 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.
However, integration between AngularJS and RequireJS is a bit tricky. I created angularAMD to make this a less painful process:
http://marcoslin.github.io/angularAMD/

Short answer is, it make sense. Recently this was discussed in ng-conf 2014. Here is the talk on this topic:
http://www.youtube.com/watch?v=4yulGISBF8w

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 tool that makes the combining easy. See http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/

Yes it makes sense to use requireJS with Angular, I spent several days to test several technical solutions.
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.
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.
For more information go on my github Angular Seed :
https://github.com/matohawk/angular-seed-requirejs

I would avoid using Require.js. Apps I've seen that do this wind up a mess of multiple types of module pattern architecture. AMD, Revealing, different flavors of IIFE, etc. There are other ways to load on demand like the loadOnDemand Angular mod. Adding other stuff just fills your code full of cruft and creates a low signal to noise ratio and makes your code hard to read.

Here is the approach I use: http://thaiat.github.io/blog/2014/02/26/angularjs-and-requirejs-for-very-large-applications/
The page shows a possible implementation of AngularJS + RequireJS, where the code is split by features and then component type.

Answer from Brian Ford
AngularJS has it's own module system an typically doesn't need something like RJS.
Reference: https://github.com/yeoman/generator-angular/issues/40

I think that it depends on your project complexity since angular is pretty much modularized.
Your controllers can be mapped and you can just import those JavaScript classes in your index.html page.
But in case your project get bigger. Or you anticipates such scenario, you should integrate angular with requirejs. In this article you can see a demo app for such integration.

Related

Load external modules (third party libs) in Angularjs

Until recently I used to develop my js applications with Backbone-js.
Now, I wish to start using Angular-js for the first time.
In my backbone-js apps I used requirejs to load any third party library, it let my app stay organized and clean.
Now, when playing around with angular, I see that in many examples they use <script> to load these modules.
Is there a clean way to load modules without using this <script> tag? and keep angular functioning as expected?
Is it common to use require-js for angularjs apps? or is there any alternative?
Thanks.
You don't need to use require since you have a built in dependency injection mechanism. In order to use 3rd party libraries you need to do 3 things:
Use libraries that are compatible with angular in order be synced with the digest cycle. Most of the common libraries have an angular module that encapsulates their code.
Add these modules to your app. You can explicitly add each library with its own script tag or you can create a bundle of all your libraries and include only it.
Declare the use of that module when you create your app and module.
Angular uses whats called dependency injection to handle modules. Here is the documentation: https://docs.angularjs.org/guide/module
You might want to look at https://github.com/substack/node-browserify#usage
The downside is you'll introduce a "compile phase" to your build process.
The plus is the npm integration.
You still need to follow the "angular way" to inject dependencies, using browserify you'll have little yet nice puses https://blog.codecentric.de/en/2014/08/angularjs-browserify/
Hope it helps.

Why use requireJS instead of an ordered include list?

I've been using a grunt file to concatenate all my JS into a single file which is then sent to the client. What advantage do I have in using require calls then? The dependencies are inherent from the concatenation order and I don't have to muddy all my JS with extra code and another third-party library.
Further, backbone models (for example) clearly state their inheritance in their definitions. Not to mention that they simply wouldn't work if their dependencies weren't included anyway.
Also, wouldn't maintenance be easier if all comments related to dependencies were in one place (the grunt file) to prevent human error and having to open every JS file to understand its dependencies?
EDIT
My (ordered) file list looks something like:
....
files: [
"js/somelib.js",
"js/somelib2.js",
"js/somelib3.js",
"js/models.js",
"js/views.js",
"js/controllers.js",
"js/main.js"
], ...
So perhaps requireJS isn't worth it for small projects anyway.
Using require.js allow you to break down each part of your application into reusable modules (AMD) and to manage those dependencies easily. It is not easy to manage dependencies in a javascript application with 100 classes, for example.
Also, if you don't want all the overhead of require, check this out (developed by the same guy who created require.js): https://github.com/jrburke/almond
The answer depends on the size of your app and the end use case..
A single site.min.js payload for the front end (client) generally aims for small file sizes and simple architectures (1 single file generated from maybe 10).
back end based (server) apps are usually much bigger and complicated and therefore may warrant the use of another tool to help with managing large code libraries and dependencies (50 files for example).
In general, RequireJS is worthwhile but only if you have many files and dependencies. An alternative for use in the client would be almond. Again, using a tool like this must warrant the need (many files and dependencies).
The answer from orourkedd is also worth reading.

Inheritance between controllers in sails.js with typescript (or not)

I want to write make my controller with inheritance using sails.js node module.
I use Typescript to write my javascript, object oriented.
I tried, few weeks/months ago to do it but I failed, I want to try again because I know more TS and nodejs/sails.js by now. But I'm wondering if it's possible, because I don't know sails.js by heart and it could not be possible depending on the way the controllers are loaded.
Is there any example of this? With or without typescript.
I also think that TS files have to be compiled in CommonJs and not with AMD, because at the time the controllers are loaded, the config/bootsrap.js is not loaded and the libraries such as requirejs are not loaded, so require AMD files will fail.
That's basically your own implementation. You could use typescript or (eww) coffeescript. Or, if your javascript foo is good enough write it yourself. Sails is just javascript, using express, which also is javascript. So inheritance is possible, but up to you to implement (most people don't need it). I'm not sure if everyone agrees with me on this, but it is what I think.
Besides that, you could use ES6-module-loader to write up your imports according to the current draft of the ES6 proposal. That way, once it's ready, you get to remove the dependency and already play around with imports (which you could then use in combination with classes to write up extended classes).
It doesn't matter in what order sails loads your controllers. At the end of the day it's just javascript, and you can just import your own abstract class.
Since I asked that question about a year ago, I've made my own implementation of Sails with TypeScript.
https://github.com/Vadorequest/sails-typescript

Backbone-RequireJs boilerplate for component based large web-projects

We have a large web project, where we need components which can talk to each other which can be put in a central repository of components for different projects.
Using reuirejs and Backbone for the modular development. Went through different boilerplate available for backbone and requirejs, but none matched my requirement. So I have created following directory structure. It can be explained as follows.
---resources
|---custom-components
|---mycomponent
|---js
|---views
|---models
|---collections
|---css
|---templates
|---mycomponent.js
|---mycomponent2
|---js
|---views
|---models
|---collections
|---css
|---templates
|---mycomponent2.js
|---libraries
|---backbone
|---underscore
|---jquery
|---jquery-ui
|---jqueryplugins
|---jcarouselite
|---thirdpartyplugins
|---page-js
|---mypage.js
|---mypage2.js
resources directory will contain all the resources. Under that we will have 4 directories as mentioned.
libraries, jqueryplugins and thirdpartyplugins are obviusly the directories for the name they say.
page-js directory will contain the actual main-js which will be used inside our html file as requirejs data-main attribute.
Custom-component is where all widgets created by us will reside, as you can see it has a js file with same name as that of the component, which will be entry point of this widget. This directory also has directories for js, css and templates. CSS and templates will be loaded by text plugin and CSS plugin respectively. Js directory will contain all the backbone code to make this widget work.
Custom components will be asked by main-js residing in page-js.
Coming to what I need.
1. I want experts to have review this directory structure in perspective of large web projects, where you will need to share your widgets with other teams. suggestions are welcome.
2. My each custom-component will define a module, which will have dependencies within package structure as well as outside package structure. I want to know, if there is any way to use r.js to optimize only my custom widget dependency within package structure and let the plugins and libraries optimized separately.
3. I am developing single page ajax application, so I will be asking modules on demand so I need to cleanup modules and widgets when I dont need them, is there any way for cleaning up I should be aware of?
About the directory structure
As a directory structure pattern, I highly recommend using directory structure of cakePHP. it's really robust as in words!! I'm running multiple apps (one of them is as big as Groupon) and it works just like a charm.
You may need to tweak it a little because, you know, cake is a PHP framework and yours is a javascript one.
Here is the cake's awesome MVC directory structure:
Please note that you may host thousands of apps on a single cake installation. so if you're interested, what are you waiting for? go to their site and read their docs.
About the cleaning up techniques
Well, here is one of the downsides of the Javascript which I don't like. there is no real way to destroy a OO module like in Java or C++. here we don't have such things like C++'s ~ destructors.
For many years, programmers use module = null to free up memory from un-used codes.
Take a look at these also:
Can dynamically loaded JavaScript be unloaded?
Loading/unloading Javascript dynamically
How to unload a javascript from an html?
Hope it helps and good luck on designing your app ;D
Probably I'm late in answering this, but anyway let me share my views here, incase someone else finds it useful.
Your directory structure looks alright. It is always a better design to keep your business components self contained in to a particular directory. I will not recommend Cake MVC structure which break the Open Close Principle. Also have a look at the directory structure recommended by http://boilerplatejs.org which is a reference architecture for large scale JavaScript development.
I do not get the question very clear. when r.js is run it will optimize all JS files it find in the directory (exclude possible) and then create a single script by going though the dependency tree. In production you only need that single script (plus locale files if i18n plugin is used)
Read my blog post below. It might give you some hints: http://blog.hasith.net/2012/11/how-much-multi-page-single-page.html

How can one create a reusable library structured as AMD module(s)?

We are creating a framework that we intend to use across multiple projects. All projects will use require.js to manage modules and dependencies.
Ideally I'd like to use the r.js optimizer to compile the framework into a single file that can be provided to the applications that use it. That file will contain all modules of the framework such that in my application I can write code like:
define(["framework/util/a", "framework/views/b"], function(A, B) {
var a = new A();
// etc...
});
But it appears there are two problems with this approach.
Depending on framework/util/a doesn't tell require.js that it needs to load framework.js in which it will find util/a
The optimize tool generates names for all modules included in framework.js such as define("util/a", function() { ... } ); Even if require.js loaded framework.js there is nothing that tells it that the defined module util/a is a relative module to framework and as such is identified as framework/util/a
Am I missing something or is a better approach to structure my framework as a CommonJS package and use require.js's packages configuration option?
Re: 1. It seems that indeed r.js optimisation not was designed to optimise partial dependancy trees, as lazy loading hinges on file paths. E.g. asking path/to/module to actually load path/to would seem like a hack. One solution would be to forgo lazy loading and include framework-built.js above your application code.
Re: 2. So you'll now need your framework-built.js with full paths. One way would be to build a dummy parent that requires all of framework, say dummy-framework.js. That way your dummy-framework-built.js will have the full path defines for framework and if not lazy loaded, it should work fine.
Disclaimer: I haven't used require.js all that much, though that's my best effort :)

Categories

Resources