Current Status
Synchronous, asynchronous, AMD,require()
... apparently these are all right for some use case, but wrong for some other.It looks like JS cannot do synchronous modules ... wait what?
why browsers can't since browser have synchronous require since the very beginning? <script> tag anybody?This was me after reading few times JS cannot do sync. Turned out, sync script is in HTML specs, not JS one, but wasn't this about JS indeed, where JS on browser never had this real problem and is simply envious of
How About Facing Reality
... where in every language, requiring dependencies has always been synchronous because nobody ever cared about that latency, right? And did anyone even bothered using asynchronous file reading to include modules?Not even
node.js
does that, the most async-centric env I personally know!As summary, since this is a browser only problem, what I would expect is the ability from browsers engine to pause in a non blocking way the client until the file has been loaded. You know what I mean? F# does that so that's not an impossible reality ...
How cool would that be and how "free from browsers limits" the specification of the next module loader in a programming language would be?
The answer seems to be that JavaScript is not an HTML/W3C matter but is limited because of HTML/W3C implementors, those browsers ...
It Doesn't Matter, Had Module!
Developers are concerned that TC39 might not have real use cases and the funny part is that an evangelist of everything you know about the web as @paul_irish is had his self some concern about TC39 choices in term of real-world cases.Meanwhile, AMD does not seem to be an answer, neither the preferred choice, but regardless we have these scenarios:
- those who write for the web and go AMD
- those who write for node.js and go require
- those who will probably add all this crap regardless, and with all due respect for the dev who wrote that with best intentions, even if testing only on web or only node.js (and again, the point is not about the snippet but the fact it should be everywhere in the JS world, you got what I mean, I am sure!)
Lazy developers will simply realize at some point nothing works anymore and will go strike blaming the corrupted system, the conspiracy agains the World Wide Web, the fact nobody told them it was going to disappear or change even after 5 years of warnings about deprecations in console, etc etc ... right?
Wrong, they'll just use what worked for them 'till that day without problems and they will still think that you should not break what's in already, which is one of my favorite parts about ES5, the best update ever, if only every browser was there already, it would be a better JS world for everyone, isn't it?
Decoupling Import From Loading
How insane would that be? A semantic syntax that works in any platform, no matter how the platform loads stuff, the build process behind, or the fact you might wrap this way and do what you think is best, even improving upfront your static analysis ... right?So here a beta repository called remodel, something you might want to
git clone git://github.com/WebReflection/remodule.git
to run eventually node node_modules/wru/node/program.js test/remodule.js
and see that all tests are passing already.Wait, What
So that project is about havingimport
like syntax available even in ES3
// ES.next modules syntax import {a} from "something" // remodule imports("a").from("something");You are following, right?
// ES.next modules export module.exports.a = "whatever"; // remodule modules("something", { a: "whatever" });So, kinda yes, the missing part of all this mess is that a module should be able to register itself if we would like to static analyze it and make the logic work everywhere in both sync and async environments, right?
// ES.next modules export module.exports = { what: "ever" }; // remodule modules("exports", { what: "ever" }); // remodule backward compatible modules("exports", module.exports = { what: "ever" });Latter example is about loading that file with current require or without it ... unfortunately modules function should be there but that's easy to fix, right?
What Else
modules("test", { a: "this is a", b: "this is b", c: "this is c" });With above code, we might be able to export the test module, regardless the position in the filesystem or the package manager, and do funny things such:
var test = imports('*').from('test'); JSON.stringify(test); // {"a":"this is a","b":"this is b","c":"this is c"}Cool? we just imported whatever the module exported itself ... there's really nothing to worry about, as @benvie might spot out, the
this
is safe too, is the exported object.
var a = imports('a').from('test'); a; // "this is a"Well, it's straight forward to get that we can import just one thing from a module, right? Behind the scene, the module must be imported once, and never again, but we can grab a property as needed instead of the whole thing, right? ... and more!
var arr = imports('a', 'c').from('test'); // same as var arr = imports(['a', 'c']).from('test'); // same as, once Array comprehension is in ... var [a, b] = imports('a', 'c').from('test');We can specify multiple properties out of a single module ... cool, uh? And more!
var aliased = imports({ a: 'A', c: 'b' }).from('test'); // in a real world scenario ... var $ = imports({ jQuery: '$' }).from('jquery').$;Yep, aliases are there too, so that you can actually test everything for real in this file.
So ...
what I've done there, is not even in charge of loading synchronously or asynchronously anything ... I mean, that should be your build process in charge of making things work and instantly available once needed, right? I mean, the Web/DOM part, I get it, modal spinners all over instead of a frozen tab so annoying for the user, but why nobody simply came out with a library in charge of this? Why ES6 modules will break browsers, using all those reserved words unusable in older browsers, will break node.js logic, being incompatible with the exported module, and will probably be never adopted in fact by anybody?I am still dreaming about web improvements where stuff that gets out is what's really needed and most likely already used out there. Improved? Better? Sure! Pointless? No, thank you!
I too like how Node.js does not introduce yet another keyword and keeps it simple with a plain function, "require".
ReplyDeleteYour way is the way to go, like "let's improve JavaScript by using, well, JavaScript!"
Likewise, I do not fancy new syntaxic diabetic operators like arrows or whatnot.
Cheers!