Hacker News new | past | comments | ask | show | jobs | submit login

The existing solutions that the JS community had created were insufficient.

CommonJS is anything but - the synchronous loading and node-style resolution doesn't work well over a network, and the scoping doesn't work out-of-the-box in a browser. I wish node had just discovered and used AMD-style modules.

AMD is pretty great for what it is, IMO. It's minimal, it works (without transpilation!), and it's pretty easy to understand how and why given the language and environment it's defined for. I'm kind of sad that it "lost" to CommonJS. Still, the syntax (even though given JS, it really just falls out) isn't preferable, and it's still imperative, which makes tooling more difficult.

Modules give a better syntax than either CommonJS or AMD, with asynchronous loading that works on a networks, and imports and exports are declarative so that tools are easy to write.

Tree-shaking and static analysis are only possible with CommonJS/AMD if you strictly limit them to declarative-style use: imports at the top-level only, exports as a literal, etc. Deviate from that and tools trip up. In that case, it's better to have a new, clear, declarative-only syntax.




> the synchronous loading and node-style resolution doesn't work well over a network

answered below in https://news.ycombinator.com/item?id=11491590

> and the scoping doesn't work out-of-the-box in a browser

sorry, didn't get you on this one. Example?

> Tree-shaking and static analysis are only possible with CommonJS/AMD if you strictly limit them to declarative-style use: imports at the top-level only, exports as a literal, etc. Deviate from that and tools trip up. In that case, it's better to have a new, clear, declarative-only syntax.

Agreed with the former part, but I am not sure how the new syntax is better and clear. Infact the new syntax imposes limitations. The old regular would just not optimize in some cases. You won't lose anything or any optimization.

Further, the "top-level" only is a bit of an itch. I want to be able to do this:

    if (DEBUG) {
        import 'something';
    }
which is a common usecase and something the builder can easily remove at build time. But ES treats that as a syntax error. The "old" way doesn't have this limitation. Surely the builder's grammar can be extended to support this with the new syntax, but it just feels more magical and weird.

You/someone might very well have an answer for that - honest question, not mocking :)


Replace your debug versions of libraries with stubs that contain no-ops. So in your code, just do:

  import 'something';
And then create separate versions of 'something.js' for debug and release, where your release version just has stubs:

  export function debugPrint(msg) {}
While the debug version might use console.log or winston or whatever.

If you compile your JS and the compiler provides tree-shaking, the calls will get optimized out entirely. Even if you don't, you can deploy the no-ops to prod and it'll use minimal bandwidth and no CPU time. And the best part is that it keeps the syntax of your code very clean; you don't have to litter your code with "if (DEBUG)", you just have it do what it needs to and those calls will equal doing nothing in prod.


(Not OP) Usually when I am using this technique it's for some 3rd party library that provides a useful debugging tool. To use your suggestions I'd need to create a wrapper that calls through to the 3rd party library in dev. Sounds like a huge pain.


You should be able to use Loader config for some of this: With the right plugin to your Loader you could do things similar to AOP/injection in debug/dev with a suitably complex Loader or set of Loader plugins.

Arguably things like this are part of why standardizing the Loader APIs has been so complex. But eventually it may pay out by letting you do some nice things very simply and in a way that is configurable for different environments and also transparent from your configuration how complicated or not your libraries and plugins may be set up. (Whereas dynamic rewriting in memory and dynamic loading and lots of scattered if() blocks can feel much more opaque.)


You'll be able to do that with System.import, kind of. It's async, and it returns a promise, which is sensible but it makes code a bit more complicated.

The ECMAScript wiki appears to be down but this polyfill has a good overview:

https://github.com/ModuleLoader/es6-module-loader


If you look at how browserify/webpack works, you'll see that AMD is the same thing except that you're coding the module wrappers by yourself manually, when browserify & webpack does it for you.


Right, so AMD works in the browser, and CommonJS doesn't. Tools can transform CommonJS to behave like AMD.


oh man, you're confused. AMD was originally a CommonJS compiler in its very early days. The guy who wrote it invented its own standard (AMD) way later than CommonJS.


How am I confused? AMD works in the browser, CommonJS doesn't. It's very simple, and tools that convert CommonJS to a format that works in the browser only prove that it doesn't.

The history of the formats does not change the facts of how they operate today.




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

Search: