Hacker News new | comments | show | ask | jobs | submit login
Towards a More Modular Future for JavaScript Libraries (flippinawesome.org)
101 points by remotesynth on Nov 11, 2013 | hide | past | web | favorite | 47 comments

The yui library has an interesting concept of cleint-side modules. They were able to consolidate a lot of their widget code during the rewrite of yui2 to yui3.

I'm also excited to see what the Meteor team comes up with for their v1.0 release. They already have reusable packages for the client and server but currently it's only designed for those using the core meteor framework. Would be interesting to see if what they make could be usable by other clients.

1. http://yuilibrary.com 2. http://meteor.com

I'm on the YUI team - we'll be doing a lot more work in the module space coming up in the future. We have a few goals coming up - mainly to make each YUI component interoperable with different module systems, so that developers can use each individual YUI module whether they're using AMD, CommonJS, just plain YUI modules, or even ES6 modules.

Our goal is to play better with other libraries, so that we don't have the idea of a "walled garden", and that people can use whatever other libraries they want together with YUI, which has been a bit more difficult in the past.

Eric Ferraiuolo gave a good talk on this last week at YUIConf. Unfortunately, the full videos for the talks aren't out yet, but his slides are right here:


Keep posted - we definitely think that smaller, more reusable modules are the better way to go for front-end development in the future, and we'll have some interesting projects soon that anyone - even if you're not using YUI - can use.

Good writeup, thanks. As someone recently shifting focus from backend to frontend this was a good overview of the state of things.

If you're hankering for future blog articles, I'd love to see your take on the tradeoffs b/t using require.js vs Browserify. Or more generally a followup article on your whole FUD section would be useful.

PS - amusing typo, it's CPAN, not CSPAN :)

Couldn't agree more with the article. I use browserify in all my new projects and love having the same module comfort as I do in node.

I've written about JS modules in the past.


While I think OP's link is quite informative, I think it suffers from the same oversight as most others on this topic has - confusing JS modules with Web components.

The JS world is split in 2 right now - client and server - for good reason because they are 2 very different domains with very different requirements. While a node package will work just fine by itself on the server, reusable code written for the browser usually doesn't work on its own. Some will require the window/document/location/whatever host object to be present, while others, mostly UI components, have to rely on other things like CSS and some minimal markup to work. Guess what? Most reusable browser code is NOT a JS module, they are Web components. As such, no pure JS solution with solve the dependency management problem on the browser. A proper solution must be able to package up different kinds of resources that constitute a whole Web component nicely for consumption. Having the One True Way to manage JS dependency is just a small part of it, in which any solution will do (tho I agree with the article OP linked to suggests, CommonJS style is the more tasteful choice for now before ES6 lands).

As far as I know, Browserify, Ender and Bower fail at the above totally, utterly, completely. Only Component and Volo seem to be on the right track as the moment I think.

What do you think of browserify coupled with transforms providing html templates[1] and css inclusion[2].

[1]: E.g., https://npmjs.org/package/browserify-jade

[2]: E.g., https://npmjs.org/package/stylify

package.json doesn't have any place to define the styles and templates your component exports, so browserify can't meaningfully resolve dependencies and build your assets for you. For really good support, you'll need to be able to rewrite the URLs inside CSS too due to different directory structures within each component. Component does that for you.

That's a pretty fair point about the CSS url rewriting, it's possibly the kind of thing you can fix with a browserify transform, but iffy and as you say component is doing it already.

> The JS world is split in 2 right now

What about Meteor?

Highly, highly, highly recommend Component. We've been using it for everything we do at Segment.io for the past year and it's completely changed the way we think about and write Javascript in the best way possible. (Need to write a few more blog posts about this soon since it's never explained well in these comparison articles.)

It treats CSS and HTML as first-class filetypes right alongside Javascript so you aren't stuck inlining CSS or templates as strings which becomes incredibly unmanageable quickly. It's build step is modular too so if you really want to do custom things you can do them very easily. It's got it own's registry so you don't have to wade through junky npm modules figuring out what's supported in the browser and what isn't. It's written by TJ, so you know the API is extremely clean. It's based on GitHub's structure, so forking and tweaking is literally a one-line change instead of having to re-publish and maintain your own fork. There are so many benefits I'm forgetting too.

More than that though, I guarantee if you start using Component for a couple months you will emerge a 5x better Javascript programmer. All of the existing components are very high quality, and their source is always very small, making them trivial to read through. It actually blows my mind now to think about the kind of code we were writing pre-component and how much it has changed. We probably open-source like 5-10 new components a week nowadays, I think we have something like over 200 components between the org account and all of us combined [1][2].

Disclaimer: I seriously love component, and really just want more people to discover how awesome it is.

[1]: https://github.com/segmentio [2]: https://github.com/ianstormtaylor?tab=repositories

Um I took a look at some of the repositories. What is the point of this? onEscape? onLoad? Really? An entire "component" just to add a handler for the ESC key? WHY

Yup exactly. Your use of the word "entire" is what is wrong with your thinking, and what every other package manager gets wrong too. There is so much duplicated code out there as a result of people thinking to themselves "this is too small to be its own component". Instead, they just copy-paste it into the bottom of the file.

Yes the "on-escape" component just attaches an escape handler to the document. One of the reasons for it is just to not have to write that code yet another time, since doing that is boring and, more importantly, prone to bugs.

But the other reason is that it turns this:

  document.attachEventListener('escape', fn, false);
into this:

without losing any clarity whatsoever.

It's also more performant than attaching tons of different escape handlers, because across all components everyone will share the same event listener. Even for components that somebody else wrote and you're just using.

So yes, there's a component just for onEscape.

Don't get me wrong, I think there's a lot of value in components. If you look at my company's logo, you will see that it is three building blocks. Our framework and platform are all about reusable code blocks. Having said that, though, I think this is taking it way too far. Most of these things are trivial one liners in JavaScript. Yes, it is true that you can have many places in the code hooking into the same event listener, but guess what, having many event listeners hooked into the same event dispatcher is rather as edficient. And what if later I want to press the letter K? Do I need a component for every letter? For that matter why don't you have a component for addition and subtraction and another component for pressing the ? I mean, look at node modules. They do more than handle a single key press. Socket.io for example has an overall theme, so does express, and so do other modules. What is the theme here? Make every line into a component so I can introduce setup and teardown code for it?

The point is with component you have a choice of how granular you want your components depending on the project, and there is very low cost to breaking things down and having a bunch of dependencies. Whereas the tendency almost everywhere else is to either use monoliths and toolbelts with a bunch of stuff you don't need, or on the other hand to "cut & paste the wheel" on the other.

There are some components that bundle several components together, e.g. component/dom or component/enumerable. And there are certainly more general components for key handlers. But if you need just one piece of it, you don't have to install the whole bundle. And if you use it just once or a few times or in limited contexts, you're right, you can inline it and skip the dependency altogether. But the point is you have a choice depending on your needs.

I completely agree and recommend component for all the reasons Ian mentions. It is shocking how little-known it is in javascript land. Don't be put off by lack of documentation and examples, it is seriously awesome. In fact I can't imagine doing client-side dev without it.

Just curious, have you guys given bower a chance, and if so why did you guys end up going with component. Component seems to be slightly more opinionated, less adopted, but really nice.

I haven't tried bower, but I always get a little confused when it gets compared to component. Bower seems like a downloader with some 'dependency management'. But its 'dependencies' are disconnected from a module/build system. Great if you have a separate tool to do your build, but frankly most of them out there are awful, and it would be a nightmare even with the best to wire them up to all the conventions of all the libraries you pull in.

As Ian said, component's opinions encourage more modular, better code, and allow you to do what Web Components only now are promising within the DOM itself: bundle together templates, css, code, data, etc. And it does this without imposing a framework. For instance, if you have a pure javascript library, it is extremely easy to package for both component and NPM. Most of the UI components are framework-independent and that is encouraged. The component ecosystem and community is fantastic. And it's not sponsored by a corporation on the NYSE :) These were the main reasons I was attracted to component. The learning curve is a bit steep, but getting better all the time.

1. bower doesn't do much. it downloads all your deps and its deps, but then you have to figure out how to consume the package. component handles all of that for you. if all i wanted to do is download and resolve dependencies, i would just use npm.

2. component doesn't just manage 3rd party packages - it helps manage your internal code/styles/templates as well. see https://github.com/jonathanong/bigpipe-example/tree/master/c.... keeping CSS/JS/HTML for a component of your site in completely separate folders is a thing of the past.

3. it's less adopted because it doesn't have Twitter's marketing and man power. TJ also hasn't had the time to document or market it well. it's also much more difficult to teach (well).

4. i hate requirejs due to its unnecessary callback and defining modules through function arguments. if i weren't using component, i'd use browserify. i have not seen any non-requirejs implementations of a build step, and i'd rather have a single step than two.

5. it's easier to share code between node and the browser. with requirejs, it's a little harder, but it's easiest with browserify.

6. most bower packages are bloated and require other large dependencies like jQuery, and I can't filter through that. component modules, on the other hand, tend to be very small, lightweight, focused, and overall better quality. for example, https://github.com/yields/select is becoming pretty excellent, much better and less bloated than select2.

7. bower packages tend to come with excessive amounts of options (because people request them, ex. select2) and excessive boilerplate code (because people want it to look good right way, ex Font Awesome). component packages tend to be the opposite - minimal, structural styling and very few options.

I've had success with npm and browserify. There are still script tag dependencies I haven't gotten around to cleaning up, but the whole system is working well.

I'm absolutely in love with the npm system though. It's so simple, easy to use, and powerful. It's absolutely a killer reason to use node.js in general. I've never use a framework where installing a project was as easy as `npm install`.

See JSAN: http://openjsan.org/ (without www)

You can download the JSAN Server, and upload modules. And it takes cares of dependencies.

Check it out, and if you like, contribute there and dont reinvent the wheel.

I too belive we need a more modular javascript.

Plus, you can use JOOSE-js to create modular modules. I recommend JOOSE-js. Its great and works in all browsers, also with node (backend) and frontend

Also, in the non-perl world, i see a lot of web frameworks that likes to provide an all in one solution. That leads the developers and applications to tie themselves onto those frameworks(which is bad). ie: someone using webframeworkX that provides ormY builds all his site using that stack... and that is not good, because to use the ormY they will need the webframeworkX.

That sucks. because if i need to use cron for that app, i will need to load the webframework because the app is tied onto it... bah.

The best solution is to have ormY separated from the webframeworkX. So you can build your app with ormY, and use any webframeworkX Y or Z (only on the web facing part of your app). And no need to use orm at all (from the framework)

Looks like the site's down, Here's a text only cached version: http://webcache.googleusercontent.com/search?q=cache:http://...

Both awesome libraries, but I think including lodash and jquery in the list of small modules is a bit of a joke. Both are big old fashioned utility belts.



is hardly the ~200 LOC module being described.

It may help rereading the post as it does explain why both are on the list.

FWIW you're linking to the pre-build dev source.

Lo-Dash is available as modules for AMD, ES6, CommonJS, Node.js, and npm packages per method.





Also, jQuery is using AMD internally and allows custom builds.

There is even a project to convert it to something more easily consumed by browserify:


Please don't use Require.js, it overwrites how require is actually suppose to be used. Try using something that doesn't break instead, like HTTP://github.com/amark/theory (disclosure: this is my library, you should check out my tech talks).

"it overwrites how require is actually supposed to be used"

According to whom? RequireJS is an implementation of the AMD spec.

According to NodeJS, which given its dominance is rather important.

spec written by whom? anybody came write something and claim it's a spec. There is no AMD spec.


The graph of library growth is stunning: http://modulecounts.com/

For all of JS quirks it is clearly getting something(s) very right.

Yeah, it's available in the browser. I'm not even trying to slam JavaScript--I sort of like it for all of its foot-guns, but this is literally the only reason worth considering for its success.

Edit: I like several things about JS. Certainly if it didn't have first class functions, or easy object literals, that would be a pain. Likewise, if it didn't have insane implicit conversions and painful APIs, that would be great. But the good features didn't make JavaScript successful, just like the terrible features didn't kill it.

And Node was a function of JavaScript's ubiquity, not a cause. Having a server side platform will help keep momentum behind the language, but it really happened because JavaScript was already so big.

What about closures and first class functions?

Or easy interop (JSON), object and array literals?

JavaScript has more going for it than platform ubiquity.

While it certainly has good points besides platform ubiquity, if you were trying to derive an equivalent of big-O for the popularity of javascript, language level criticisms and acclamations would count as, at best, linear concerns, where platform ubiquity is an exponential concern.

Platform ubiquity is so completely important in the determination that all other concerns can be ignored entirely.

Given a choice of supporting half of systems in javascript, and all systems in brainfuck, people would begin writing brainfuck-targeting compilers immediately.

All the cool programmers use CoffeeFuck.

Many languages have these things.

The problem is this spurious inference drawn from package count to language superiority. In reality what's popular is targeting browsers, and there simply aren't any other languages with first-class support by browsers no matter how much we want them. This isn't a matter of Javascript being better than everything else, it's a matter of historical accident and network effects.

You don't think it has anything to do with Node?

Node only came about b/c Google wrote V8 for high-performance browser JS. Node has certainly expanded JS's reach in a big way, but wouldn't have existed in the first place if, say, Lua were the lingua franca of all web browsers (or maybe V8 and Node would still exist but target Lua instead).

If you want to run code in browsers, it isn't like you really have a choice.

We already have CommonJS. It rocks. Use it. Whether your code runs in node or the browser is exactly what the "engines" property of the "package.json" file is for.

Interesting but I was expecting a bit more insights on the "modularity" approach of these different client-side package managers.

why not add a real module and dependency system to js at the language/runtime level? Considering how important JavaScript has become, isn't it completely amazing that this discussion is even happening now?

TC39 is working on it ,i think they are 10 years late of that matter, and the solution they chosed is not even that good.

I mostly work with NPM and Node also Bower. Very powerful tools

Based on the site being down, I think the future is to use a CDN, yes? MaxCDN is $39/year.

Site is back up. Sorry about the issues.


Applications are open for YC Summer 2018

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact