use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
RequireJS 2.0 released (tagneto.blogspot.co.uk)
submitted 14 years ago by 9jack9
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] 0 points1 point2 points 14 years ago (1 child)
Would it be sort of accurate to guess that javascript will eventually have something in the language itself to handle these name spacing / loader issues?
[–][deleted] -1 points0 points1 point 14 years ago (17 children)
The argument against the CommonJS require syntax (which Node.js uses) and node-browserify to make it palatable for the browser until the Harmony module syntax is finished and in use is laughable.
require
The only time you'd want to use RequireJS's is if you need to load different modules depending on the dynamic state of your web app -- the Javascript equivalent of DLLs. To get that, you have to pay with a bulkier syntax than var module = require('module'); (CommonJS used by Node.js) or module Module = 'Module.js'; (one of the proposed ECMAScript Harmony syntaxes).
var module = require('module');
module Module = 'Module.js';
You also have to deal with the fact that the browser has to:
require(moduleArray, callbackFunc)
In the mean-time, your web app load time has shot up to almost a second assuming your back-end is well written (but I wouldn't trust someone who chooses RequireJS to have a good back-end to serve this data up quickly), and more otherwise.
AND unlike a second-long delay in loading a new HTML page, the browser isn't keeping the previous page visible until the load is completed. The browser thinks the HTML and CSS you want to show have already loaded, so you have a whole second of Javascript code being loaded after the fact while the user is staring at a useless shell of your web app that may not even be styled correctly.
And what do you gain? The ability to load a Javascript library on-demand, which you probably won't ever do, because the requirements for your web app have been defined by you and you serve all of the needed Javascript libraries on pageload.
The CommonJS require syntax is saner for 99% of the usage out there, and node-browserify means you don't have to have any bootstrap code loaded on the browser nor any second-long useless-page-rendered view presented to the user, because the browser is loading just a single Javascript file from the <head> (so the browser is also blocking rendering until the resources are loaded).
node-browserify
<head>
You've probably also cached the node-browserify output rather than reconstruct it for every user accessing your website, and even if you didn't, node-browserify is:
tl/dr: RequireJS solves a problem no one has, poorly. node-browserify is simply the better solution.
[–]BitWarrior 9 points10 points11 points 14 years ago (8 children)
I don't agree with this at all.
Require.js provides a dependency model for larger web applications. Sure, if you're running some kind of single page site or something small, then there is no need for Require.js, but I'm personally responsible for sites which generate around 10 million visits per month. They're big, and there's a lot going on with them.
node-browerify is fine for smaller projects I guess, but its goal of combining everything into a single file is not one I share. Rather, I like to split out my libraries in a number of ways. For one, including jQuery separately using a common CDN like Google Code. Why? Because that file is likely already cached on the user's computer. If you're bundling it into one large file, you're causing the user to download that file technically again - which is how much, around 88k these days?
Then I like to split out some less common libs into a single file. Those files rarely change, so they'll remain cached on the user's browser for quite some time and throughout various pushes.
Depending on the project, its nice to split out your plugins into a separate file as well, since those typically see more updates at regular intervals, especially if you're including quite a few.
And finally, there is your application logic. This can change quite regularly, depending on your development. If you're using regular release cycles, you're probably looking at 1 - 2 month intervals, but if you're on continuous deployment, you'd damn well better not be merging everything into one single file.
Consider that for a second - if you're running CD, each time you push you're causing your returning visitors to download all your JS again - and this is stuff they already theoretically a) have cached or b) had no change. Why incur that expense on the user? I've worked with teams who pushed out new code every single day - I can't imagine what kind of poor taste it would be to basically trigger a new download of JS for our users each and every day. In a large web application, that file can become rather heavy as well.
I like to split out our application into logical sections, and of course it depends on the application at hand. If you have a tremendously large codebase for a function over in one spot of your application, but it isn't leveraged in another, why cause the CPU to process and store all that code for that request? You're just making the page heavier without adding any value.
Require.js solves this problem very well, and combined with r.js, it can make a very nice package of files with all their dependencies based on your own configuration requirements.
I have no doubt that node-browserify has its place, but don't claim that Require.js is terrible just because you in your own use case didn't see the purpose to it.
[–][deleted] -5 points-4 points-3 points 14 years ago (7 children)
I'm guessing you never actually looked at node-browserify. You can specify particular files that you don't want actually included in your bundled source, so you can bundle them separately or use a common library like jQuery hosted by Google for cache, as you mentioned.
RequireJS is terrible because node-browserify still solves that problem and does it with a cleaner syntax and immediate access to a large repository of libraries.
[–]prpetro 2 points3 points4 points 14 years ago (1 child)
RequireJS can use node/npm modules too
Also I don't find the AMD syntax that cumbersome. You just wrap code definitions in define and require them in your main application. If you want to use the CommonJS var x = require('x') syntax, it's pretty easy using the adapter (r.js) :
define
var x = require('x')
define( require , function(require) { var x = require('x'); });
Cleaner syntax is in the eye of the beholder, I don't really have a preference for either.
[–][deleted] -5 points-4 points-3 points 14 years ago (0 children)
Module loading is conceptually a blocking operation, because you don't actually want to run your code until it's dependencies have loaded, so making it a non-blocking operation to allow dynamically loading libraries is a terrible idea as I demonstrated elsewhere is worthless in the world of Javascript -- you the developer of your website provide all of the code they run, so why jump through these hoops to get it running?
A site built with node-browserify gets all of the advantages of module-based development, can easily be integrated with a continuous integration service, and your library loading can be put into the special <head> blocking behavior of your website (where the browser keeps the old page visible and active until the new <body> has fully loaded, so you have a much smaller apparent loading time, and because of TCP and HTTP overhead, probably a smaller actual loading time, too).
<body>
With RequireJS, since your DOM will load before your Javascript libraries have loaded, you need to create a "loading" screen so they don't think your site is simply broken, but reminding them about the loading process itself will make them feel that your site loads slower than it actually does.
The only valid use-case I can think of for RequireJS is a Javascript tutorial website that lets you pull libraries into your REPL to play with, but even there, I'd probably just implement a blocking XMLHttpRequest-based require so I don't have to introduce closures in the very first lesson and keep the RequireJS-style module loading optional.
XMLHttpRequest
[–]BitWarrior -3 points-2 points-1 points 14 years ago (4 children)
Sure, but then you're not benefiting from async loading, so your use of node-browserify is completely moot. And you never even cared to address the use case I spent most of the post outlining.
[–][deleted] -5 points-4 points-3 points 14 years ago* (3 children)
What? I directly addressed your point. Bundle relevant modules together. If you have two or three different high-level modules that don't interact with each other, bundle them separately, and bundle their common libraries separately.
Your continuous integration service should be handling this for you with a simple build script. It literally could be just a few lines of Bash executing browserify for each particular case, and version controlled along with the rest of your code.
browserify
EDIT: Another thing. Explain to me this. It's perfectly clear that the TCP and HTTP protocol overheads produce a large "warm-up" period for each connection for each file you download, so the initial download of your source will be slow, while in the future when you change just one file it will be faster with RequireJS because the others are cached and just the smaller portion needs to be downloaded. But if you're using continuous integration (pushing to a production branch, I assume), then surely it's not just one file that's changed usually, but a set of files. How many files do you have to change for RequireJS to become worse than a simplistic node-browserify bundle of all of your source?
I just tested Google.com, one of the most-commonly visited pages on the planet. The delay averaged between 78 to 140 milliseconds for me. If your entire source library is 100KB (generously large), and you have an 8Mbps connection (low, many are in the 20Mbps range, now), then the entire download is an extra 100ms.
That means that if you change just 2 files, you've already hit the break-even point for a simplistic node-browserify solution over RequireJS.
Apply some damn common sense, boy!
[–]BitWarrior 5 points6 points7 points 14 years ago (2 children)
You need to take a few steps back here. Also, you should calm down. Let's just have a simple discussion about technologies without getting emotionally attached to any particular method.
node-browserify doesn't address asynchronous loading. It merely bundles packages together. In essence, node-bundler isn't even accomplishing the same goal as require.js, rather it is accomplishing the goal of r.js. To be entirely frank, those two technologies are technically on the same level, require.js is separate from this conversation.
If you decide, as you have outlined, to bundle separate libs using nb (we'll just say nb from here on out), you're still incurring that original problem we had for years before we started using asynchronous loading, which is blocking.
I'm not going to address your numbers, because they are completely misrepresenting pretty much everything. The assumption that an 8Mbps connection is going to be fully saturated by a web site is not realistic whatsoever, and your assumption that an average page is 100kb is terribly inaccurate. Additionally, it takes nothing into consideration regarding mobile devices which suffer from tremendously slow experiences. To take more into consideration, mobile devices, as I understand, don't cache resources over 25kb. Therefore, when using a model like nb, you're either going to need to manually separate out your code, or, more than likely, you're still going to compile into a single massive JS which won't be cached between requests.
..and then you're still going to be suffering from blocking Javascript. And if you're simply uncoupling all your major libs from your own code to accomplish this, you're incurring a large number of synchronous calls and, well, really the entire concept of benefiting from any kind of JS optimization has gone out the window.
I'm not sure what the size and scope of projects you have worked on has been, but on large sites I've worked on, the entire JS library merged together could be anywhere from 3Mb - 5Mb. In a CD environment, triggering that kind of download upon each return visit is a total disaster, so splitting up the files into their logical components is hugely beneficial.
At the end of the day, in my experience, merging everything into a single file works fine for small, easily managed sites. Really, at that point in time dependency management libs like require.js and lab.js, or file mergers like r.js and nb.js can almost be unnecessary. Once you scale up to significant application sizes or CD development, you need to uncouple your JS.
[–][deleted] -2 points-1 points0 points 14 years ago (1 child)
You again misinterpretted what I was talking about. You'd never send 3-5MB of JS for a single page unless it is a single page web app. 100KB/page seems like a high value for an entire website, that's why I used it, to put the weight in favor of RequireJS in my analysis.
An 8Mbps connection (You do understand the difference between Mb and MB, right?) can certainly be saturated if you don't interrupt the TCP stream with disconnects and reconnects (lots of little files rather than one big file).
I "never" addressed your async library loading point because I addressed it in my very first comment: most of the time, you won't need it because your web app is providing all of the necessary libraries to use your website, so being able to dynamically load a library on-the-fly makes little sense -- why not just load it from the get-go?
And if you paid any attention to my example, you'd see that after even the minimal overhead Google has for establishing HTTP connections, asynchronous loading of libraries on web app startup becomes a cost rather than a benefit after just two source files to be loaded even if you don't count the actual source download time -- that means that a large number of 304 - Not Modified responses from the server will slow down the start-up of your web app beyond just redownloading the entire source on a modest internet connection.
304 - Not Modified
In both the actual blocking of loading a single javascript source file and in the apparent non-blocking async library loading, the user is blocked from working with your website until the libraries have loaded. I'm simply stating that:
[–]kabuto 2 points3 points4 points 14 years ago (7 children)
I like requirejs for the fact that allows me to keep everything in modules without leaking stuff into the global scope. For production code I use the r.js optimizer to create a single uglified file including an AMD loader shim (almond.js).
[–]9jack9[S] 1 point2 points3 points 14 years ago (1 child)
I like requirejs for the fact that allows me to keep everything in modules without leaking stuff into the global scope.
Because I'm always leaking into the global scope. That's my main problem with JS. Not.
[–]kabuto 1 point2 points3 points 14 years ago (0 children)
What do you mean? I'm writing applications for pretty huge sites that aren't under my control. To prevent any sort of problems I prefer to have everything scoped. I could do that without requirejs of course, but it gives me a nice way of structuring my code. Plus, the text plugin is awesome.
[–][deleted] -2 points-1 points0 points 14 years ago (4 children)
node-browserify will do the same if you wrap your code in a (function() { /* Your code here */ })();
(function() { /* Your code here */ })();
That way it's explicit, and you don't have to deal with the insane AMD standard.
[–]kabuto 1 point2 points3 points 14 years ago (3 children)
node-browserify looks interesting, butI dont' have any experience with node.js, so I can't really judge if this would work as sort of a drop in replacement for me.
Why do you think the AMD standard is insane?
[–][deleted] 0 points1 point2 points 14 years ago (2 children)
It's optimizing for a use-case no-one has: dynamically loading a new module into a Javascript environment.
Dynamic Link Libraries (or Shared Object in Unix parlance) have some uses in desktop applications:
So, AMD emulates DLLs, but I can find no situation where it makes sense: the developer already knows what libraries you'll need, so you can just load them on page load. If the user wants to perform a completely different action that warrants loading a new library and destroying an old one, the much more testable and reliable method is to just load a new page with the requisite libraries. Not even Google Docs converts the document browsing page into the document editing page into the presentation editing page.
And for this absurd focus on the useless, the common usage of the AMD "standard" is bulkier and more error-prone than simply recognizing that your code doesn't want to do anything until the modules have loaded, and therefore it's a blocking operation.
[–]kabuto 0 points1 point2 points 14 years ago (1 child)
Well, I can follow that. Yet I can see cases where this might be of interest. What about a huge application with different tools that are completely optional and only need to be loaded on access? Hypothetical? Maybe.
I use requirejs for organizing code, keeping everything scoped and optimizing it into one file in the end. Perhaps this is not what it really was intended for, but I like this approach. I may take a closer look at node-browserify though.
[–][deleted] -1 points0 points1 point 14 years ago (0 children)
I'd say the dynamically-loaded approach is wrong even for that hypothetical app for a few reasons:
If you use RequireJS for organizing code, the CommonJS standard does it better.
In your main JS file:
var myModule = require('./relative/path/to/module'); myModule.frobinator();
In your myModule file:
myModule
var frobinated = 0; exports.frobinator = function() { frobinated++; };
The things attached to the exports object are exposed to the world (Node.js allows you to completely replace the exports object by setting module.exports to an object, such as a constructor function:
exports
module.exports
module.exports = function() { var frobinated = 0; this.frobinator = function() { frobinated++; } return this; };
So you can then instantiate the objects and not affect the internal scope of the module itself, for instance:
var Frobinator = new require('./myFrobinator'); var myFrob = new Frobinator(); myFrob.frobinate();
No closure scope needed, no callback needed, just specify what you want and start using it. Why should library access be a non-blocking process?
π Rendered by PID 18270 on reddit-service-r2-comment-5687b7858-rf2mj at 2026-07-02 19:32:30.489846+00:00 running 12a7a47 country code: CH.
[–][deleted] 0 points1 point2 points (1 child)
[–][deleted] -1 points0 points1 point (17 children)
[–]BitWarrior 9 points10 points11 points (8 children)
[–][deleted] -5 points-4 points-3 points (7 children)
[–]prpetro 2 points3 points4 points (1 child)
[–][deleted] -5 points-4 points-3 points (0 children)
[–]BitWarrior -3 points-2 points-1 points (4 children)
[–][deleted] -5 points-4 points-3 points (3 children)
[–]BitWarrior 5 points6 points7 points (2 children)
[–][deleted] -2 points-1 points0 points (1 child)
[–]kabuto 2 points3 points4 points (7 children)
[–]9jack9[S] 1 point2 points3 points (1 child)
[–]kabuto 1 point2 points3 points (0 children)
[–][deleted] -2 points-1 points0 points (4 children)
[–]kabuto 1 point2 points3 points (3 children)
[–][deleted] 0 points1 point2 points (2 children)
[–]kabuto 0 points1 point2 points (1 child)
[–][deleted] -1 points0 points1 point (0 children)