Feed back and proposal for modules: allow importing ES5 files

程劭非 csf178 at gmail.com
Mon Sep 24 04:22:28 PDT 2012

Thank you for replying, Alex.

Replied inline.

2012/9/24 Alex Russell <alex at dojotoolkit.org>:
> Hi Shaofei:
> On Sep 22, 2012, at 6:29 PM, 程劭非 <csf178 at gmail.com> wrote:
>> Hi, everyone,
>> I noticed that current importing grammar will not work for ES5 files,
>> I mean there is no way to import one or more es5/es3 files as a module
>> and import variables from it.
>> The problem is:
>> 1. There are no "export" keywords in a es5/es3 file, no variables are exported.
>> 2. They might be using more than one files but current mudule grammar
>> allows only one file as one module.
>> When the new standard(es6) comes out, I guess a big number of
>> libraries need updating. And before they finish their work, I think we
>> need a cheap solution for the new code(es6) to use old
>> libraries(es5/es3) without modifying their code
> One option here is for you to create an export "wrapper" for them, in essence a separate file that requires the old library be loaded which then exports the library's symbols through an export. Not pretty, but it requires no code changes for well-designed libraries.

I tried to find a way to make a wrapper but I failed.

Consider I have a file
// mylib.js

//depends on jQuery

When importing it as a library

//There is no way to add $ to it's scope
//except polluting the global object
import "mylib.js" as myLib;

>> For the two points, I was considering two solution:
>> 1. Export all global variable by default.
>> Anonymous function could be used to protect the global namespace and
>> most libraries are already using it. So I don't think "export" is
>> needed.
> You inadvertently identified why we need "exports": it's very difficult what is "global". In particular, what should be exported in the case of a file that includes:
> var f = function(param) {
>   thinger = param;
> };
> // ...
> if (someGlobalConfigurationSetting) {
>  f("howdy!");
> }
> ?
>> Exporting all global variable will not pollute the module's user's
>> namespace for we still need "import" phase.
> Perhaps instead of "global" you mean "the top-level IFFE"?
> In that case, it's easier, but then it depends on the IFFE both being executed (it's not a static form here) and there being only one. Or is the suggestion that a file like this should export both a and b? And what will the value of c be?
> // example.js
> (function(p){
>  var a = p;
> })("hello");
> (function(p){
>  var b = p;
> })("world");
> var setValue = function(p){
>   var c = p;
> };
> setValue("it's a sunny day!");
> setValue("it's raining in London");
> // end example.js
> As you can see, at the limit, this creates some serious hazards for violating the data-hiding provided by closure-bound variables. Suddenly importers can not only see these internal names, but watch their values change!

Perhaps I'm not expressing clearly.(Sorry I'm not a native speaker.)

I'm not saying that  we should export variables inside a IFFE.

I mean that :


var $;
// for ES5 $ should be a property of global object,
//I mean even without “export”, Module instance object
//should have a binding for "$" when example.js imported
//as a Module


    $ = function(){
    // $ could be changed

    var $2 = function(){
    // $2 will not be imported
    // because it's in a IFFE.

// somewhere
// Variant A:
import "example.js" as myQuery;
import $ from myQuery;

// Variant B:
module myQuery = "bar.js";
import $ from myQuery;

//$ should be able to be used here

>> 2. Allow importing multiple files as one module.
>> This will completely decouple file and module. We need to modify the
>> ModuleSpecifier grammar:
>> ModuleSpecifier ::= StringLiteral | Path
>> ===>
>> ModuleSpecifier ::= ( StringLiteral | Path ) ( "," StringLiteral | Path )*
>> With this, for example, if I'm using a RSA library like
>> <http://www-cs-students.stanford.edu/~tjw/jsbn/>, I can do the
>> following:
>> import "jsbn.js","prng4.js","rng.js","rsa.js" as RSA;
>> If I want to use a module depend on jQuery1.3.2, I can do:
>> import "jQuery1.3.2.js","MyModule.js" as MyModule;
>> I've mentioned this idea in a reply, post it as a separate thread to
>> get more feed back :-)
> This is interesting. Do you have a proposed resolution mechanism for conflicts? We had such a thing in the old traits system for classes, but I don't think it has survived anywhere.

Do you mean name conflict?

If "jQuery1.3.2.js" and "MyModule.js" are all ES5 style (no module
system used). There should not be any conficts or they will not work
in ES5.

This is different from
import "jQuery1.3.2.js" as jQuery;
import "MyModule.js" as MyModule;

The declaration
import "jQuery1.3.2.js","MyModule.js" as MyModule;
should behave like importing a file just like "jQuery1.3.2.js" and
"MyModule.js" are copied together.

> --
> Alex Russell
> slightlyoff at google.com
> slightlyoff at chromium.org
> alex at dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

More information about the es-discuss mailing list