Requirejs - Dynamic module dependency injection with variables - angularjs

We created dynamic module injection with requirejs in our angular application. Now we have created parameter instances of function for each module separately (commonModule, usersModule). How can we possible to make it dynamic for module dependency injection in requirejs and angularjs?
var _moduleFiles = ["common/module", "user/module"];
require(_moduleFiles, function(commonModule, usersModule) {
var app = angular.module('Myapp', [commonModule, usersModule]);
});

I have investigated about this issue and can found out that it may not be possible to implement dynamic module injection in requirejs.
Dynamic code loading (done in AMD systems via require([], function
(){})) is a basic requirement. CJS talked about it, had some
proposals, but it was not fully embraced. Node does not have any
support for this need, instead relying on the synchronous behavior of
require(''), which is not portable to the web.

Related

How can I inject an AngularJS module dependency without declaring it in the dependency array when the module is defined?

Currently the only way that I know of to make module dependencies available is to specify them when a module is declared. e.g.:
angular.module("myApp",["myDependentModule"]);
This becomes a problem when the app gets large and modules have a lot of dependencies, libraries that must be loaded. If these libraries aren't required for any of the modules that the first page the user visits, it seems that those dependencies could be deferred to improve load time.
Any advice would be appreciated.
Use angular.injector(...)
https://docs.angularjs.org/api/ng/function/angular.injector
Mention and example is here:
var injector = angular.injector(['someModule']);
var someService = injector.get('someService');
AngularJS - Injecting factory from another module into a provider
you can use lazy load moduls.
https://oclazyload.readme.io/docs

Webpack with angular 1.x and ES5

After reading hundreds of lines about browserify vs webpack and several how to of both I decided to go for webpack. The main reason it's because I liked the idea of bundling everything into a js file.
I have an angular project already working and I want to refactor it for webpack. The problem? My project is using angular 1.4.7, ng-animate and plain javascript (ES5) and all the tutorials and manuals are for ES6. I don't want to refactor my project so much. What's the way to go? I would like an example of each angular module : factory, directive, controller and so on. Many thanks
I typically have a feature.module.js file which has my module definition and requires all of the directives / services contained within the module. Also has the external dependancies.
/* module.js */
angular.module('my.module',['dependancy1', 'dependancy2']);
//External libraries
require('./dependancy1.module.js');
require('./dependancy2.module.js');
//Internal components
require('./thing.directive');
require('./thing.service';
/* service.js */
angular.module('my.module')
.directive('yourDir', function myDir(){...});
I'm dealing with the same problem now. And I found something that works (work in progress, but at least I can see progress). My steps:
Install yeoman
Run this angular-webpack generator. Select 'ES5' when asked (the other option is 'ES2015', which I guess is the same that 'ES6')
Start modifying the automatically generated boilerplate with your Angular code
Yes, you still need to learn about gulp and sass, but at least you can run a simple AngularJS app using the old ES5 syntax, and start modifying it.
I'm probably blogging about this. So, I'll update this answer then.
I tend to do this:
app.js:
require('/any/angular/deps');
var subModule = require('/some/sub/module');
var app = angular.module('myApp', []);
// pass the app module in sub modules to allow them to define their own config
subModule.configure(app);
/subModule/module.js:
var someSubDirective = require('./subDir/directive');
export function configure(app) {
someSubDirective.configure(app);
}
/subModule/subDir/directive.js:
export function configure(app) {
app.directive('myDir', myDir);
}
function myDir() {
}
My idea is to let all sub modules handle their own configuration, so declaring config or constant, factories or providers. Letting this then bubble up to the app.js. This means its really easy to delete a folder from your structure, because it is one line removal from it's parent module.
This also makes relevant file paths a lot shorter and easier to handle.

Angularjs - how to correct inject service from another module that is not depending?

I didn't understand how work modular depending.
I have 3 modules, they are dependent on each other, as shown in the picture.
"App" module includes "module1" and "module2".
"module2" includes "core" module. There are source on plunker.
angular.module("core", []).factory("HelloWorld", function() {
return function () {
alert('Hello World!')
}
});
angular.module("module1", []).controller("main", function(HelloWorld){
HelloWorld();
});
angular.module("module2", ["core"]);
angular.module("app", ["module1", "module2"]);
If I inject service from module core to module "module1" it is work fine. But "core" module not depend in module "module1". Why it happening?
Since your App module depends on Core module (indirectly through Module 2), the services in Core module are available anywhere inside your App module (including Module 1).
This is because Angular will first load all modules and then start instantiating their components and resolving injected dependencies.
Yet, if you indeed need Core services in Module 1, you should make it dependent on the Core module as well. That way your application won't break if Module 2 is modified at a later time (or removed altogether) and your Module 1 will be more self-contained and reusable (e.g. you could use it with a different application that does not depend on the Core module).
In general, you should not rely on "indirect" dependencies. Each module should explicitly declare its dependencies.
Angular is smart enough to only load a module if it is not already loaded, so there is no overhead.
Quoting from the Developer Guide's section on modules:
Modules can list other modules as their dependencies. Depending on a module implies that required module needs to be loaded before the requiring module is loaded. In other words the configuration blocks of the required modules execute before the configuration blocks of the requiring module. The same is true for the run blocks. Each module can only be loaded once, even if multiple other modules require it.
(emphasis mine)

Modularize AngularJS application : one or multiple AngularJS modules?

I try to build a modular application using AngularJS. My first idea is to group each module by functionnality with this kind of folder structure :
/core
controllers.js
directives.js
app.js
/modules
/users
controllers.js
directives.js
/invoices
controllers.js
directives.js
/messages
controllers.js
directives.js
...
Notice that the "core" folder contains basics features that will always be in the app. Others modules can be add or remove independently.
As my application will be large, I also want to use lazy loading. I implemented this solution : http://ify.io/lazy-loading-in-angularjs/ which seems to me actually the easiest way. The problem is that it only does lazy loading for controllers, services, directives ... but not for AngularJS modules.
I know there is another way which permits to lazy load Angular modules (http://blog.getelementsbyidea.com/load-a-module-on-demand-with-angularjs/) but I think it's way too hacky as it uses Angular's core methods.
My question is : does it make sense in my case to use different AngularJS modules for each of my modules, like this :
angular.module('core', ['ngRoute', 'users', 'invoices', 'messages'])
angular.module('users')
angular.module('invoices')
angular.module('messages')
What is the advantage of this approach ? Are AngularJS modules usefull - for now - only for third-party modules for Angular ?
I'm asking this since AngularJS 2.0 will support natively lazy loading. Miško Hevery from Google says "[you] should group by view since views will be lazy loaded in near future", and that we should use one module per application, see it here : https://www.youtube.com/watch?v=ZhfUv0spHCY&t=34m19s
Is it correct for a large application to just use one module for my app like this :
angular.module('core', ['ngRoute']);
And then lazy load my controllers, services and directives based on a route or a view ?
We have a similar structure (on a very large app) to the one you are proposing here, except don't have controllers,services and the like bundled up into single .js files. Instead we just separate our concerns with views, services and the like all bundled into a single module. So each meaningful component might looks like:
/my-component
- i-do-something.js
- a-view.html
- a-view-that-is-a-child.html
- a-view-ctrl.js
- index.js //the thing that creates a module and returns it
/ tests
- i-do-something-spec.js
- a-view-ctrl-spec.js
This is all bundled up into a single app module (named for our org). Then a simple boot module angular.bootstrap(['app'])s the whole thing.
We use browserify to compile all this stuff and it has worked nicely so far.

AngularJS - please explain the line

What exactly does the "inject" line do?:
function PhotoGalleryCtrl($route, $xhr) {
}
PhotoGalleryCtrl.$inject = ['$route', '$xhr'];
Are $route and $xhr predefined somewhere? Where to read about them?
Who said that the PhotoGalleryCtrl function has the .$inject method?
Both $route and $xhr are native AngularJS services, the latter has been replaced by $http in the most recent versions of AngularJS. They are part of the ng module.
You can read about them here
ng.$route
ng.$http
$inject tells angular to make available those services to the controller PhotoGalleryCtrl
Dependency injection and modules are core features of Angular. They both minimize global state and allow for better unit testing, you can read more about them here
Modules
Dependency Injection

Resources