* The dependencies are static, so you can't do stuff like `if(Math.random() < .5) { require('foo') } else { require('bar') }`. That is a good thing. A lot of people at this point agree that a statically analyzable dependency graph is a huge win.
* Bindings are truly exported. If you exported `const foo = 5`, imported it in another module, and tried to change it, you would get a static error. Semantics and identity of bindings carry over. This also means they are mutable; if the module exporting `foo` changes it everyone else will see it too.
* A fleshed out module loader API, which is seriously lacking in node
There are other advantages too. The simplistic approach of CommonJS works, but long-term it's not the best solution for the wide use-cases of JavaScript.
EDIT: and this will be backwards-compatible. I don't know all the details but this can be implemented in a browser today without breaking things (I know people on the teams working on this)
Could you elaborate on this point a little more? I've worked on Node.js projects varying greatly in size, and even on the larger ones I've yet to feel encumbered the CommonJS module system.
- https://github.com/cujojs/curl - https://github.com/montagejs/mr - https://github.com/substack/wreq
yeah but the 80% solution of loading them both statically but only executing them when the require is run works ridiculously well in practice.
On top of that, module loaders provide hooks, so it's quite possible to use a module loader (e.g. System.JS) that can load commonjs or amd modules.
Browserify is brilliant, and if I couldn't use es6 I'd be using it, but I'm pretty excited about es6 modules.