A Variation on ES Modules

# Kevin Smith (13 years ago)

I've worked up a concrete variation on the modules syntax:

gist.github.com/4337062

I believe that it presents a clean, simple model and coding experience. Comments welcome!

# Andreas Rossberg (13 years ago)

On 19 December 2012 16:24, Kevin Smith <khs4473 at gmail.com> wrote:

I've worked up a concrete variation on the modules syntax:

gist.github.com/4337062

I believe that it presents a clean, simple model and coding experience. Comments welcome!

Thank you! I agree with almost everything you suggest (and especially, what you say about anonymous exports), and your syntax pretty much exactly matches my preferences.

I'm fine with considering syntactic module declarations separately (note, however, that you probably cannot define mutually recursive modules without them). What you do want to have IMO, though, is module aliases

module Short = Long.Qualified.Module.Name

Referring to nested modules can be pretty tedious if you don't have a way to abbreviate names. (You can do that with 'let' or 'const', but then you lose all static checking.)

OTOH, one more other feature I could consider dropping for the time being is the ability to export "from" a ModuleSpecifier. I'm not convinced that this is a common enough use case to warrant specialised extra syntax -- you can already express it by pairing an export with an import. (In fact, allowing the "export" keyword in front of imports seems like the more consistent way to support re-exporting.)

# Russell Leggett (13 years ago)

I will admit - this seems very readable to me, and I don't feel like I have a lot of questions about edge cases. I would be pretty satisfied with it.

This might be a bit of a tangent, but there is something else that's been bugging me. It's almost 2013 now, and we're fill in the gaps for ES to be ready for large projects etc. The modules syntax/functionality seems fine... but I wonder if its just playing catch up or if its actually taking the opportunity to be the best it can be. Specifically, I'm wondering about the modularity question. I understand that with ES being so dynamic it's a lot easier to create mocks for testings, etc. but with static modules, don't we run the risk of having the same problems as Java and needing some kind of dependency injection? Maybe I'm just worried for no reason, just thought I would throw it out there.

# Kevin Smith (13 years ago)

What you do want to have IMO, though, is module aliases

module Short = Long.Qualified.Module.Name

I agree.

OTOH, one more other feature I could consider dropping for the time being is the ability to export "from" a ModuleSpecifier. I'm not convinced that this is a common enough use case to warrant specialised extra syntax -- you can already express it by pairing an export with an import. (In fact, allowing the "export" keyword in front of imports seems like the more consistent way to support re-exporting.)

True, except for the case of export * from "url";, since we don't have import *.

The use case for such a feature (as I see it), lies in creating a "nearby" module that forwards the bindings from some other "distant" module with a long URL.

Let me explain...

I feel pretty strongly that there should not be any blessed, centralized registry for globally naming javascript modules (or packages, or what-have-you). Sorry, NPM, but javascript is different! But at the same time, in order to unambiguously express project-external dependencies, global names have to be used. Well, that's what URLs are for:

// Importing from a project-external dependency:
import x from "//my-js-registry.org/foo-1.2.3.4";

(Of course, the loader for your app will be clever enough to remap this URL to a "local" server, or whatever you need.)

But if you have several modules in your project which reference this same project-external module, then you'll end up having to repeat that long URL several times. To alleviate that pain, you can create a local forwarding module:

// foo.js
export * from "//my-js-registry.org/foo-1.2.3.4";

Then we can use the local URL in our dependent modules:

import something from "foo.js";

If we update the version of "foo", we only have to change the global URL in one place. Notice this provides us with the ability to specify truly global dependencies without the need for "package manifests" or other out-of-language facilities.

# Kevin Smith (13 years ago)

Just to finalize this thread, I updated the gist based on comments from Andreas:

gist.github.com/4382710

It includes syntax for proper inline modules, and an extension syntax for pre-loading (aka concatenating). It also brings the syntax for module aliasing closer to the previous harmony proposal:

module M = "m.js";
module N = M.N;
# Irakli Gozalishvili (13 years ago)

I have added few comments to gist.github.com/4382710

-- Irakli Gozalishvili Web: www.jeditoolkit.com