Require Browserify / Angular Template

I am working in a project with angular and a browser, this is the first time I use these two tools together, so I would like some tips on which this is a way to require browser files.

We can import these files in different ways, so far I have experimented as follows:

Angular Application:

 app _follow - followController.js - followDirective.js - followService.js - require.js - app.js 

For each folder with files for the plugin, I created a require.js file and in it I need all the files in this folder. For instance:

 var mnm = require('angular').module('mnm'); mnm.factory('FollowService', ['Restangular',require('./followService')]); mnm.controller('FollowController',['$scope','FollowService',require('./followController')]) mnm.directive('mnmFollowers', ['FollowService',require('./followDirective')]); 

and then require all require.js files in a unique file called app.js that will generate bundle.js

Question:

Is this a way to require the files to be good structure, or it will have some problems when I need to test? I would like to see your path to achieving a good structure using angular and a browser

+6
source share
4 answers

AngularJS and the browser are not, unfortunately, a great match. Of course, I don't like React and the browser, but I'm distracted.

What worked for me is that each file is an AngularJS module (because each file is already a CommonJS module) and the files export their AngularJS module name.

So your example would look like this:

 app/ app.js follow/ controllers.js directives.js services.js index.js 

app.js will look something like this:

 var angular = require('angular'); var app = angular.module('mnm', [ require('./follow') ]); // more code here angular.bootstrap(document.body, ['mnm']); 

follow/index.js will look something like this:

 var angular = require('angular'); var app = angular.module('mnm.follow', [ require('./controllers'), require('./directives'), require('./services') ]); module.exports = app.name; 

follow/controllers.js will look something like this:

 var angular = require('angular'); var app = angular.module('mnm.follow.controllers', [ require('./services'), // internal dependency 'ui.router' // external dependency from earlier require or <script/> // more dependencies ... ]); app.controller('FollowController', ['$scope', 'FollowService', function ...]); // more code here module.exports = app.name; 

And so on.

The advantage of this approach is that you keep your dependencies as clear as possible (i.e. inside the CommonJS module that they really need), and the one-to-one mapping between the CommonJS module mods and the AngularJS module names prevents unpleasant surprises.

The most obvious problem in your approach is that you keep the actual dependencies that will be inserted separately from the function that expects them, so if you change the dependencies of the functions, you need to touch two files instead of one. This is the smell of code (i.e. the Bad thing).

For testing, any approach should work as an Angular modular system, in fact, is a giant blob, and importing two modules that define the same name will override each other.


EDIT (two years later): some other people (both here and elsewhere) suggested alternative approaches, so I probably should consider them and what are the tradeoffs:

  • There is one global AngularJS module for your entire application and simply requires side effects (i.e. do not have submodules exporting anything other than manipulating a global Angular object).

    This is apparently the most common solution, but it looks like flies in the face of modules. However, this is apparently the most pragmatic approach, and if you use AngularJS, you are already polluting global variables, so I assume that side effect modules are the least of your architectural issues.

  • Combine your AngularJS application code before passing it to Browserify.

    This is the most literal solution to "allow the integration of AngularJS and Browserify." This is a valid approach if you start from the traditional AngularJS β€œjust blindly concatenate your application files” position and want to add Browserify for third-party libraries, so I assume that makes it valid.

    As for the structure of your application, this does not improve anything by adding Browserify.

  • Like 1, but with each index.js defining its own AngularJS submodule.

    This is a template approach proposed by Brian Ogden. This suffers from all the flaws of 1, but it creates some semblance of hierarchy inside AngularJS in that at least you have more than one AngularJS module, and the names of the AngularJS modules really match your directory structure.

    However, the main drawback is that you now have two sets of namespaces that you need to worry about (your actual modules and AngularJS modules), but nothing provides consistency between the two. Not only do you need to remember that you need to import the correct modules (which again rely on side effects), but you must also remember to add them to all the correct lists and add the same template to each new file. This makes refactoring incredibly cumbersome and makes this the worst option in my opinion.

If I had to get out today, I would go with 2 because he gave up all the claims of AngularJS and Browserify that could be unified, and just left to do his job. Plus, if you already have an AngularJS build system, it literally means adding an extra step for Browserify.

If you don't inherit the AngularJS database and want to know which approach is best for starting a new project: don't start a new project in AngularJS. Either choose Angular2, which supports the real modular system out of the box, or switch to React or Ember, which do not suffer from this problem.

+5
source

I tried to use the browser with Angular, but found that it was a bit confusing. I did not like the template for creating a named service / controller, and then demanded it from another place, for example.

 angular.module('myApp').controller('charts', require('./charts')); 

The name / definition of the controller is in one file, but the function itself is in another. Also, having a large number of index.js files makes it really confusing if you open many files in the IDE.

So, I put together this gulp plugin, gulp-require-angular , which allows you to write Angular using the standard Angular syntax, all js files containing Angular modules and Angular module dependencies that appear in your main module dependency tree are require() ' d to the generated input file, which is then used as the recording file for the browser.

You can still use require() in your code base to pull external libraries (like lodash) into services / filters / directives as needed.

Here, the latest Angular seeds are forked and updated to use gulp-require-angular .

0
source

I used a hybrid approach similar to pluma . I created ng modules as follows:

 var name = 'app.core' angular.module(name, []) .service('srvc', ['$rootScope', '$http', require( './path/to/srvc' )) .service('srvc2', ['$rootScope', '$http', require( './path/to/srvc2' )) .config... .etc module.exports = name 

I believe that the difference is that I do not define individual ng modules as dependencies on the main ng module, in this case I would not define Service as an ng module and then list it as dep app.core ng module. I try to keep it as flat as possible:

 //srvc.js - see below module.exports = function( $rootScope, $http ) { var api = {}; api.getAppData = function(){ ... } api.doSomething = function(){ ... } return api; } 

Regarding the comment on code smell, I disagree. While this is an optional step, it allows excellent customization in terms of testing against mock services. For example, I use this quite a bit to test services again, which may not have a ready-made API server:

 angular.module(name, []) // .service('srvc', ['$rootScope', '$http', require( './path/to/srvc' )) .service('srvc', ['$rootScope', '$http', require( './path/to/mockSrvc' )) 

Thus, any controller or srvc dependent object does not know what it is receiving. I could see that this is a bit confusing in terms of services depending on other services, but for me it's a bad design. I prefer to use the ng event system for betw communication. services to keep you in touch.

0
source

Alan Plum's answer is not a great answer, or at least not a great demonstration of the CommonJS and Browserify modules using Angular. The assertion that Browserify does not mix well with Angular compared to React is simply not true.

Browserify and the CommonJS module template work fine with Angular, which allows you to organize functions instead of types, save vars from the global scope, and easily distribute Angular modules across all applications. Not to mention that you no longer need to add another <script> to your HTML, thanks to Browserify to find all your dependencies.

What is the peculiarity of errors in Alan Plum does not require that dependencies for Angular modules, controllers, services, configurations, routes, etc., be set in each index.js for each folder? There is no need for a single requirement in Angular.module, not just one module.exports, as in the context Alan Plum talks about.

See here the best sample module for Angular using Browserify: https://github.com/Sweetog/yet-another-angular-boilerplate

0
source

Source: https://habr.com/ru/post/976483/


All Articles