6 ms·
I'm really puzzled by the enthusiasm around RequireJS. I've read up on it, I've built several large JS applications (~100 models, views, whatevers in ExtJS and
by CoffeeDregs 13y ago
I'm really puzzled by the enthusiasm around RequireJS. I've read up on it, I've built several large JS applications (~100 models, views, whatevers in ExtJS and Knockout), have been involved with a large BackboneJS/RequireJS application and am currently rebuilding a large site in AngularJS. AFAICT, RequireJS did not solve any problems that I had more easily solved with proper namespacing (yes, the feared global, e.g. TheProject.controllers.chrome.SessionController) or that AngularJS doesn't solve more gracefully.
Instead, RequireJS yielded a fairly verbose and error-prone header* coupled with large and distinct JS downloads for each and every page. Add in Backbone's verbosity and it's boilerplate and hand-wiring all the way down. Just the kind of thing for when you want to handcraft an artisan website, but not so great for cranking out code.
* Good luck catching typos when you're pulling in 20 modules and you lose synchronization between the strings and the vars. Here's a simple example:
define([
'jquery',
'handlebars',
'backbone',
'mymodel',
'mycontrolleranimals',
'mycontrollerpeople',
'myview_cats',
'myview_dogs',
'myview_birds'
],
function(
$,
Handlebars,
Backbone,
MyModel,
MyControllerAnimals,
MyControllerPeople,
MyViewDogs,
MyViewCats,
MyViewBirds) {
Sure, you caught the error because you were looking for it, but what happens in a RequireJS application is that you get weird errors in your application because you were trying to use the MyViewDogs, but myview_cats was actually bound to that variable.
To be perfectly honest, I didn't build the system, so don't that it was configured correctly.
- ghostdiver 13y agoThink about using two different versions of ExtJS, it's just not possible atm. because of globals. You should look into Dojo Toolkit source code, which now is almost entirely built on AMD. Regarding "distinct JS downloads for each and every page": again, look at Dojo Toolkit source code and its build system.
- johtso 13y agoLuckily there's an alternative syntax for requiring modules: define(function (require) { 'use strict'; var Backbone = require('backbone'); var Handlebars = require('lib/handlebars/handlebars'); var someTemplate = require('text!component/templates/some-template.hbs'); http://requirejs.org/docs/whyamd.html#sugar http://requirejs.org/docs/whyamd.html#sugar
- altcognito 13y agoHrm.... I don't think the angular documentation agrees with what you are saying: In the documentation on the $inject annotation: > Care must be taken that the $inject annotation is kept in sync with the actual arguments in the function declaration. > This method of annotation is useful for controller declarations since it assigns the annotation information with the function.
- mbell 13y agoYou don't need to use angular's inline injection annotations if you don't want to. Angular can figure out the needed injection by the parameter name. This causes an issue when you minimize your code but ngmin solves that problem: https://github.com/btford/ngmin https://github.com/btford/ngmin For example: angular.module('app').controller('someController', function ($scope, ModelService, AuthService) { $scope.something = 'Blah'; }); Works just fine as long as it isn't minimized, and ngmin would turn it into something like: angular.module('app').controller('someController', ['$scope', 'ModelService', 'AuthService', function ($scope, ModelService, AuthService) { $scope.something = 'Blah'; }]); Which is then safe to run through a minimizer.
- CoffeeDregs 13y agoAgreed, there are corner cases in which Angular has the same issue (hence my note that Angular does better). This is really only an issue when seriously minifying (e.g. closure compiler) your application code and I tend to stay away from that.
- ktt 13y agoUse this syntax, IMHO it's a LOT more readable: define(function(require) { var $ = require('jquery'), Handlebars = require('handlebars'), Backbone = require('backbone'), MyModel = require('mymodel'), MyControllerAnimals = require('mycontrolleranimals'); Also require.js comes with an optimizer that automatically concatenates all required files (and no more!) minifies them and you don't have to worry about script order. Also using the text plugin you can package templates (text files) along with the rest of the scripts.
- CoffeeDregs 13y agoTotally agreed and you get the benefit that it's the same syntax as NodeJS. But I rarely if ever see that syntax used...
- STRML 13y agoWow, I've been using require.js for more than a year and I've never seen that syntax used. `var module = require('module')` will only work if the module has already been downloaded; otherwise, there's no way it can make an async call and return the result. What's interesting is that requireJS pulls a move very similar to Angular and reads Function.prototype.toString() to pull those definitions back up into the define() call, so it still works if an async call needs to be made. That's really fantastic. As we've seen with Angular, there are some quirks (old browsers, mainly), but code like this will be optimized out by r.js so there will be no problems in production. Thanks for the pointer, I may just change all of my definitions after seeing this.
- nilliams 13y agoAgree, I've used this syntax on my last 2 projects. It is so much better, and closer to Node/CommonJS, I don't know why anyone uses the alternative.
- cwmma 13y agoas someone refactoring a name spaced project into a requirejs one. Thw big benefit is more or less lexical scope for each page and cleaner entry amd exit points for the parts. Its easy to tell if changes to x break y if y has to import x
- jaxytee 13y agoThat can easily be solved by paying attention.
- dustingetz 13y agoI have also maintained or architected two large JS applications (100k+ lines of javascript) in ExtJS, Knockout, Kendo and React and I couldn't imagine not having requirejs, for the benefits of enforcing modularity and sane dependency structure, just as much as the sane approach to an optimized build and the plugin system. The pain point you describe is not a pain point for my team, and even if it was a pain point, it is perfectly possible to abstract the repetition[1], which you are of course aware of since you use Angular. FWIW, we have not felt the need to have any modules with 20 includes. [1] http://www.dustingetz.com/2013/05/13/javascript-dependency-injection-angularjs-style.html http://www.dustingetz.com/2013/05/13/javascript-dependency-i...
- LordHumungous 13y agoYou can put some of that stuff into a core utility function and then just use require('core') everywhere else.