Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How might one regret choosing injectjs for their next startup? :p #266

Open
jfrux opened this issue Jun 6, 2013 · 1 comment
Open

How might one regret choosing injectjs for their next startup? :p #266

jfrux opened this issue Jun 6, 2013 · 1 comment

Comments

@jfrux
Copy link

jfrux commented Jun 6, 2013

I consider this an open discussion providing an opportunity to talk me out of using injectjs on my next big thing...
Also, responses such as "If you want it to NOT be awesome, then don't use injectjs." are always welcome!

@thecodedrift
Copy link
Contributor

I believe in being very honest about Inject, RequireJS, and the whole "Module Loading" family. I welcome this discussion.

Module Loading is an all-or-nothing approach

People often think you can mix module loading code and regular script tags. I can tell you from experience here at LinkedIn that this is a lot harder than it should be. In fact, I'd even go so far to say that if you are not fully committed from the beginning, you shouldn't consider it at all. Mixing script tags and loaders will often cause weird unexplainable breakages in your code, as some libraries may think AMD or CJS environments are available when, in fact, they're not.

all-or-nothing also extends to your build system. Once you have this beautiful module system, you are going to want some way to optimize for the browser. Downloading a few dozen files, even in parallell can be a huge performance hit. Many systems have some sort of caching plan in mind:

  • AMD systems often rely on both the browser cache and file concatenation (with used with an optimizer like r.js)
  • CJS systems often rely on both the browser cache and localStorage for file retention

But then again, if you're going to put in place all the build system tooling for optimization, you might be better off with an internal module system such as Browserfy and delivering a single payload.

Technically deprecated on arrival

In theory, the ES6 spec already has support for a module system. While it's still draft, and while we may still be living with older versions of Internet Explorer for years to come, the reality is that the need for these kinds of libraries should be going away.

All we need is every browser to support bleeding edge specifications...

Wants to be node. Isn't node

I personally believe the whole browser based CJS/AMD movement is rooted in our desire to offer npm/node power in the browser. It's just so easy to bring in a node module, have its dependencies managed, and you just use require() and things just work. This design has some concepts that simply don't translate to the browser.

  • An npm environment doesn't care about duplicate versions floating around. Have a node module at version 1.0.2 and 1.1.5? npm just keeps two copies in the node_modules directory under the respective dependency locations. Sure, it takes up more disk space, but there's minimal latency in reading from a disk. in the browser, if you had to download multiple versions of a library based on dependencies, you could double or tripple your download immediately
  • require() is awesome. It works with globally installed modules, it works with local file paths, the concept of a module's "ID" is pretty transparent to the end user. Sure, you might encounter this concept if you begin symlinking things inside of your node_modules, but I believe the number of people doing this is really small. in the browser, concatenating for performance completely decouples module ID from path. This makes the whole "what the hell is going on?" problem far worse
  • require() is synchronous. Browsers really suck at synchronous things. Back in the day, dojo used to actually do this kind of package management with synchronous requires. It was awesome. It was also slow since every synchronous request required an HTTP roundtrip. Eventually, dojo created an synchronous require/provide (and eventually moved to AMD). But then they inherited the above two problems.

Libraries come and go

This is true of any library, but especially since CJS/AMD libraries are all evolving quickly. It may be that we all universally agree on one true/simple way to solve this problem, and many of the libraries become obsolete. Thankfully, this isn't as scary as it sounds, because everyone is complying with a predefined specification. So, you can just swap one library for another. All you'll need to do is update your configuration.

And even the configuration is slowly standardizing, making these libraries 100% interchangeable.

Closing thoughts

That's everything off the top of my head. Inject/RequireJS/etc are all pretty awesome.

I look forward to the CJS/AMD library that uses Socket.IO to stream modules to the browser, eliminating roundtrips completely and managing the dependency tree on the server side. That will be delicious. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants