Hacker News new | ask | show | jobs
by tieTYT 4500 days ago
Could you elaborate on Point 2? What causes this bug, and how do you fix it? I'm looking for a low level explanation rather than, "Use a Module Loader" because I want to fundamentally understand what's going on when my code depends on load order and how to fundamentally fix it.
2 comments

Unlike some languages, javascript files execute as they are loaded. In large projects relying on js files to take actions beyond the most basic definitional type things is usually a mistake because it means that there is evolving global state (always difficult to keep track of) with implicit semantics. It's very distressing to move some code around in the include order for an unrelated reason and then suddenly find that hundreds of unit tests start breaking with bizarre errors.

The way to avoid this is to limit your js files to definitions, and then finally kick everything off with a single call. Module loaders enforce this, but you can follow this advice without them.

It's reasonable to have one file that must be loaded first - this provides the mechanisms you're going to use to define your objects and nothing more. Then everything else can be done in whatever order seems good, before finally kicking off the action. Even registering code with factories and registries should be left until the end. There are some ordering requirements that are legitimate - if you inherit from another class, then the super class will typically need to be ordered before the subclass.

If you're doing a small project where you don't mind having up to 10 script tags in a page, then you'll do better following the 'separate definition from execution' advice than not. You'll do better still using some form of module loader that makes concerns of order obsolete and will let you scale. I like browserify, but there are lots of options, ranging from the very simple to the complex.

> Could you elaborate on Point 2? What causes this bug, and how do you fix it?

Unless @async is specified, the scripts linked in a page will be executed in that order. This means it's easy to unknowingly create implicit (and possibly unexpected) dependencies between scripts.

Because a module loader will perform asynchronous loading and execution of scripts, if dependencies are left unspecified the loading order is essentially random (mostly driven by the script's source size and how fast the server happens to respond to that request). A module loader requires that dependencies be explicitly spelled out, or changes are the application will randomly blow up at loading.