Re: A plan to help TC39 become more open up to community contributions and participations
Maybe also a factor: JS has changed a huge amount in a short time. Developers, browsers, tools need to catch up, digest the changes, decide what real problems remain. We have enough new for now. On Fri, May 27, 2016 at 7:42 AM, Kevin Smithwrote: > Thanks for pointing out some issues with the current state of things. > While, in general, having more people directly participate in the committee > is probably a good thing, I don't think that will fix the problem. I think > you'll find yourself running into the same troubles that the current > members face. Specifically, there is more work to be done than there is > time to do it. There are more things to reach consensus on than there is > time to discuss. Also, there is also the risk of perpetuating an unhealthy > "us-vs-them" mentality which seems to underly this plan and this post. > > Instead (or perhaps simultaneously while you explore this plan) why don't > we try to address the community involvement problem? > > The big problem, I think, is that community members are directed to > es-discuss and yet es-discuss has been largely been abandoned by TC39 > committee members. Why has es-discuss been abandoned? There are a couple > of reasons I think: > > 1. Github (and their "issues" feature) has turned out to be a much better > platform for working out design details on particular proposals. Community > members have successfully and productively participated in the design > process in this way. > 2. The signal-to-noise ratio here is *really* bad these days. Let's be > honest: most of the strawman proposals that are brought here are pretty > terrible. It takes time to review and comment on even the worst ones, and > that's time that I (for one) would rather spend doing other things, like > working on observables, or cancel tokens, or private state, or async > generators, or drinking eine bier. > > The other problem that I've heard mentioned is that certain high-profile > proposals (like that function-pipe one) aren't getting any traction. > > First, there are *very* few proposals that fit into that category. Claude > Pache's https://github.com/claudepache/es-optional-chaining is great! In > general though, if a proposal isn't getting picked up it's probably because > either it has significant issues that committee members don't like, or the > time for it just isn't right. Time is a limiting factor and we have many > proposals working through the process already. > > I'll spend some time thinking about how we can improve the es-discuss > involvement problem. Thanks again for bringing attention to it! > > > On Thu, May 26, 2016 at 8:06 AM G. Kay Lee < > balancetraveller+es-disc...@gmail.com> wrote: > >> (This is a continuation of [a previous discussion]( >> https://esdiscuss.org/topic/tracking-proposals-should-be-standardized-with-issues >> )) >> >> So, to summarize, while rules and platforms currently in place do allow >> for community contributions, they are hardly friendly ones. A few issues: >> >> * The mailing list is a really awkward platform for community >> participants to collaborate, especially when debates and discussions can >> span months, even years; threads, reasonings, and important conclusions >> tend to become buried over time, resulting in a never-ending reincarnation >> of dead ideas and, more importantly, lose of precious lores and insights. >> >> * Self-contradictory rules about the processing of community proposals in >> official documents, because these rules were [authored by a few different >> individuals without a definitive source]( >> https://esdiscuss.org/topic/tracking-proposals-should-be-standardized-with-issues#content-17 >> ). >> >> * The most widely circulated version of these rules demands community >> proposals to find "champions", ie. member representatives willing to serve >> as lobbyists; the real story, however, is that member representatives are >> very busy and, when they do have time, they will almost always lobby for >> proposals that their organizations or themselves are interested in. No >> blaming here because this is just the way human society works, which brings >> the conclusion that this requirement is simply antihuman. >> >> In the previous discussion, Allen mentioned that a lot of efforts have >> already been put in place to make TC39 as open as possible under the bylaws >> and rules of Ecma International, for which I am sure every non-member >> participant of the standardization process is really appreciated. But I >> think there is still room to do better. >> >> For that reason I intend to form a nonprofit organization and apply for >> Ecma membership to help further opening up the standardization process of >> ECMAScript to interested participants who currently do not enjoy the >> privilege of becoming member representatives. >> >> I've been in contact with Secretary General Istvan and apparently this is >> doable as long as the General Assembly vote in favor of my
Re: ES6 import directive
Hi Lorenzo, almost all of your requests are covered by a related imperative loader API, http://whatwg.github.io/loader/#loader-import This work is not quite complete and thus not well described but your goals will be met with this API. jjb On Thu, Jan 7, 2016 at 8:30 AM, Lorenzo Ferrarawrote: > Dear Ecma International, (and Dear readers, as I don't exactely know who > will read this mail) > > first of all, I think you do a great job standardising ECMAScript, > which I honestly am a great admirer of. > > However, there is 1 (only 1) point I can't agree with: the "import" > statement. > I want to state my opinion on the ECMAScript "import" statement, > which is why, as I couldn't find a GitHub issues page, I am writing you > this letter. > English is not my primary language, so I hope I can explain you my opinion > without misconceptions. > > Since years there has been a need for a C-style "include" method, > which enables "importing" external library code into own code. > Finally, with the ES6 standard, the "import" directive has been developed, > which is a synchronous and kind of intuitive method for importing external > library code. > > 1) However, I think the ES6 "import" doesn't conform with the general > ECMAScript-style very well, > because while ES is a very dynamic scripting language, where you can > choose almost everything at runtime, > "import" breaks with this style as "import" requires the name of the > library to be known at "compile-time", > what makes things like > import f from (prompt("use old library, for older > browsers")?"oldlib.js":"newlib.js"); > impossible, which takes away a bit of dynamism from ES. > "import" should enable choosing the required libraries at run-time. > > 2) imports shouldn't be synchronous, as they require a file to be > downloaded (probably over network). > As almost any Ajax tutorial states, synchronous file downloads over > network are bad practice for various reasons. > For example, subsequent code in a file importing a library has to pause > execution until the library file has loaded. > So, code in a .js file cannot execute until all libraries have loaded, > which is a great impact. > > imports should be asynchronous. > And, as they can either succeed (when they are successfully downloaded and > parsed) or fail, > they should be tied closely to Promises. > Every import should return a Promise > that fulfills when the library is ready to use > and fails when something went wrong while loading the library. > > 3) imports shouldn't have their own syntax since this makes polyfilling > harder. > there are already some transpilers around, but no recent transpiler can > successfully transpile the following: > alert(1); > eval('import x from "mylib"; alert(x)'); > alert(2); > In this short piece of code, we can see 2 downsides of current imports: > * they are synchronous, so alert(2) will not alert 2 until "mylib" has > loaded. > * to execute the code, the execution environment (interpreter) has to > fully support the syntax. > Instead of inventing a new syntax for imports, I would use the existing > function-style syntax. > Like the following: > alert(1); > import("mylib").then(function(mylib){ > alert(mylib.x); > alert(2); > }); > > 4) I don't think a library should be a singleton. Rather, libraries should > be kind of instantiatable classes. > Further more, one should be able to pass arguments to the library when > importing a library. > But 4) is just my personal opinion based on personal experience. > However, I think 1) to 3) are important and should at least be considered. > > So, in general, I think introducing imports on a language level is a great > idea, > however, for implementation easement and for other reasons, > I would prefer asynchronous imports using existing syntax > instead of synchronous imports with new syntax. > > Please correct me if I got something wrong. > I'm looking forward to your feedback. > > Cheers, > 74h7k3fg > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: treated as a module if ...
On Sun, Jul 5, 2015 at 8:46 AM, Domenic Denicola d...@domenic.me wrote: To be explicit: there is no way to look at a string of JavaScript text and tell whether it should be treated as a module or a script. In many instances the same string can be treated as both. The decision is made by the execution environment. I don't think Domenic meant that the standard explicitly states that the execution environment may choose the parse method. Rather that the context of loading the code determines the parsing method. I believe that the current status is that the standard describes the two parsing methods but says nothing about when they will be applied. We do know that script tags always parse as Script. Of course, modules imported by import statements are parsed as Module. Sadly, as far as I know, there is no standard way to import a ES2015 root module. The discussions on modules imply that there will be an explicit loader import function that will parse as Module and there has been discussion of script type=module and module but these proposals are moving slowly if at all. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Promise sub-class: super((resolve, reject) = this) ?
On Wed, Jun 3, 2015 at 1:27 AM, Benjamin Gruenaum benjami...@gmail.com wrote: Am I missing something obvious in `super((resolve, reject) = this)` ? First of all, it makes perfect sense for `this` not work work before super has been called - and it has not been called yet. Rather than starting off by claiming the restriction on this before super() makes perfect sense, let's be honest that lots of normal developers will be tripped up by this restriction. this is used a reference throughout class code: it makes perfect sense to use it in a constructor. Passing extended-class-specific values to super() is exactly what super() does. Thus using this in a constructor before calling super() is entirely natural in light of other experience with the language. Our inability to support this before super() is unfortunate, so let's sympathize and encourage people to understand. I think that the crux is that the promise constructor runs _synchronously_ so when you pass it `this` it has not finished running yet. Of course, the workaround as domenic has pointed is to extract `resolve` and `reject` from the `super` call since it is synchronous. (also I'm assuming you're not really mapping `(resolve, reject)` to `this`? `this` is an object and the promise constructor ignores return values anyway, you might as well pass a no-op in.) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: import ModuleSpecifier
This same claim could be made about every item in ECMAScript. Implementation variation in ModuleSpecifiers is no different from variation in the allowed keywords, character set, or really anything a developer types. Failing to specify this aspect of the language makes no sense to this developer at least. On Sun, May 31, 2015 at 7:30 PM, Brendan Eich bren...@mozilla.org wrote: Browsers in any semi-competitive market will agree on a standard. I don't see why that needs to be called into doubt, even as part of a hypothetical future :-|. (Is there another kind? :-P) /be Domenic Denicola wrote: Yes, in theory. However, browsers are more likely to wait until there’s a standard for browser module loaders before shipping modules, in order to avoid such divergent behavior. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Are ES6 modules in browsers going to get loaded level-by-level?
Correct, ES6 has no plans for a bundling solution and the whatwg group working on the loader has not proposed one. Nevertheless bundling solution is easier to build and specify. In ES6, given a root module you can compute the (static) dependency graph as the basis for creating a bundle. The bundle will be complete and -- if the code has no unnecessary imports -- minimal. Moreover, the unnecessary imports can be determined by parser analysis alone. Since bundling includes issues of transport, compression, and minification, I suspect that a standard may not emerge any time soon. Rather I expect a few tools to emerge and these will become de facto standards for bundling. jjb On Wed, Apr 22, 2015 at 7:10 PM, Matthew Phillips matt...@bitovi.com wrote: Can you clarify what you mean about bundling? Unless I've missed something, the ES6 module system does not have a story for bundling at all. Of course formats can be invented in userland but I'm not sure that they are any easier to implement than say AMD's. I might have missed something though, looking forward to your reply. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Are ES6 modules in browsers going to get loaded level-by-level?
Sorry, but what I read was not an explanation but rather a hope that HTTP/2 would magically solve this problem. I'm all for HTTP/2 solving this. But so far I've not heard or read anything to back up the idea. Will HTTP/2 make multiple round trips, one for each level of the dependency tree, competitive with pre-bundling? If not, then we will have to send dependency info to the client or cache info to the server or bundle. Or there is some magic as yet unexplained? jjb On Thu, Apr 23, 2015 at 7:47 AM, Domenic Denicola d...@domenic.me wrote: Indeed, there is no built-in facility for bundling since as explained in this thread that will actually slow down your performance, and there’s no desire to include an antipattern in the language. *From:* es-discuss [mailto:es-discuss-boun...@mozilla.org] *On Behalf Of *Eric B *Sent:* Thursday, April 23, 2015 10:25 *To:* Frankie Bagnardi; Matthew Phillips *Cc:* es-discuss *Subject:* Re: Re: Are ES6 modules in browsers going to get loaded level-by-level? So just to clarify, when browsers support es6 modules we will still need some extra library to bundle the modules? This would mean es6 modules are only a syntactical addition and not something functional? On Thu, Apr 23, 2015 at 10:18 AM Frankie Bagnardi f.bagna...@gmail.com wrote: Matthew, there are already tools for es6 modules + bundling (e.g. babel + webpack), or converting es6 modules to AMD (e.g. babel https://babeljs.io/docs/usage/modules/). On Wed, Apr 22, 2015 at 7:10 PM, Matthew Phillips matt...@bitovi.com wrote: Can you clarify what you mean about bundling? Unless I've missed something, the ES6 module system does not have a story for bundling at all. Of course formats can be invented in userland but I'm not sure that they are any easier to implement than say AMD's. I might have missed something though, looking forward to your reply. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are ES6 modules in browsers going to get loaded level-by-level?
On Thu, Apr 16, 2015 at 11:16 PM, medikoo medikoo+mozilla@medikoo.com wrote: Thanks for clarifications, Still after reading your comments I have a feeling that providing ES6 modules to browsers (efficient way) will be much more cumbersome and tricky than it is to provide CJS ones now. There is no technological reason to have such a feeling. The design of the ES6 module system makes creating bundles much easier and with much less chance of error. All of the imports can be computed from a given root module without relying on the developer build a list or organizing the bundle inputs into folders. This is not true for CJS. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are ES6 modules in browsers going to get loaded level-by-level?
On Thu, Apr 16, 2015 at 1:22 PM, Domenic Denicola d...@domenic.me wrote: From: John Barton [mailto:johnjbar...@google.com] But the push scenario in your first paragraph would not use the cache either. Yeah, that's what I was alluding to with the most naïve comment. one or the other has to send its information at the outset of a import request, or One way of doing this I came up with off the top of my head is to add some kind of dependency graph version or hash to the query string. I.e. script type=module src=entry.js?1234/script. The server can then assume that the client has in its cache version 1234 of the dependency graph, and can push the incremental updates since then (i.e. added or modified files). If parts of the cache were evicted, so that the versioning signal is not entirely accurate, then the penalty is not so bad, as you just fall back to the normal loading process for the evicted subset. But I feel pretty silly speculating here as I'm not an expert on HTTP/2 techniques, and there are probably other methods that are better in various ways. Perhaps, but I feel the issue is more fundamental. HTTP/2 shares statelessness with HTTP/1. It follows that the state of the client must be sent to the server or vice versa. HTTP/2 can make that process much faster but it's not going to know what state to send without instructions from clients or from servers. We can all make up those instructions one at a time and in our own unique ways or the module experts can come up with a good solution for the common cases. I'm hoping for the latter ;-) jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are ES6 modules in browsers going to get loaded level-by-level?
On Thu, Apr 16, 2015 at 12:18 PM, Domenic Denicola d...@domenic.me wrote: Is there any mean in sight, that will allow us to serve them as fast as we can serve hundreds of bundled and minimized CJS modules now? Yes. Any browser which implements the ES6 module loader (none of them right now) will also be a browser that implements HTTP/2 (all of them right now). HTTP/2 server push would allow you to respond to a single request for entry.js (e.g. from `script type=module src=entry.js/script`) with responses for all modules in the entire dependency graph, prioritized according to their level in the graph, all over a single TCP connection. This is just the most naïve strategy I could think of with HTTP/2. There are more interesting ones too. It's also important to note that bundling is an antipattern in the HTTP/2 world, as it prevents incremental cache updates by invalidating the entire bundle graph when you change a single file, and does not allow relative prioritization of individual files. But the push scenario in your first paragraph would not use the cache either. As far as I can tell, only the client knows which modules it has loaded; only the server knows the dependency graph for modules-to-be-loaded. So: one or the other has to send its information at the outset of a import request, or the server needs to send the entire bundle, or the loading has to be layer by layer. HTTP/2 does seem to have the magic to avoid considering these issues in module loading. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: include 'foo/index.js' or include 'foo'?
The following solution has worked very well for us: import './foo/index.js'; means resolve './foo/index.js' relative to the importing file. All of the rest mean look up 'foo' in the developer's mapping of names, replacing 'foo' with a path that is then used to resolve the import. To be sure 'foo' 'foo/index' and 'foo/' would likely fail after lookup since they don't name files. (This kind of thing cannot be up to the host. If TC39 passes on deciding, then developers will). jjb On Thu, Feb 5, 2015 at 5:01 AM, Glen Huang curvedm...@gmail.com wrote: I believe this is out the scope of ecmascript. It’s up to the host to determine how the paths are resolved. See https://people.mozilla.org/~jorendorff/es6-draft.html#sec-hostnormalizemodulename On Feb 5, 2015, at 8:51 PM, monolithed monolit...@gmail.com wrote: I could not find an answer in the specification regarding the following cases: import './foo/index.js' import 'foo/index.js' import 'foo/index' import 'foo' import 'foo/' Is there a difference? Node.js lets create an 'index.js' file, which indicates the main include file for a directory. So if you call require('./foo'), both a 'foo.js' file as well as an 'foo/index.js' file will be considered, this goes for non-relative includes as well. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Any news about the `module` element?
Couldn't the module tag be restricted to be the last tag inside html? Then we don't need them to be async to avoid blocking rendering and the declarative order would more closely match the semantics. Multiple tags could be loaded in parallel and sequenced on execution. jjb On Sat, Dec 20, 2014 at 3:59 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Dec 20, 2014, at 2:02 PM, Caridy Patino wrote: John, think of script defer src=mod.js/script. For script type=module, async is implicit. What if you have a series of modules that need to be evaluated in sequential order? (Remember, that a module with no imports is the module worlds equivalent to a simple sequential script.). eg: script type=module window.sequence = 10; console.log(window.sequence); /script script type=module console.log( should be 11: + ++window.sequence); /script script type=module console.log( shoud be 12: + ++window.sequence); /script Allen Sent from my iPhone On Dec 20, 2014, at 3:01 PM, John Barton johnjbar...@google.com wrote: On Sat, Dec 20, 2014 at 10:54 AM, Matthew Robb matthewwr...@gmail.com wrote: On Sat, Dec 20, 2014 at 1:50 PM, Caridy Patino car...@gmail.com wrote: what make you think this proposal implies blocking? I think he was reading your examples using require() and thinking you were suggesting that the semantics would match. Indeed that is what I was thinking. A non-blocking module tag is a poor match to HTML, a declarative language where order of tags means order of parsing and rendering. Giving up this fundamental characteristic of HTML, in the long-shot effort to improve the apparent load time for some amateur Web sites, has become dogmatic so I suppose there is no value in discussing it. A non-blocking module tag would also prevent experienced developers from controlling rendering through JS action. That means they will need to use script tags which we'd like to deprecate or we'd have to have a blocking form of module. We'll probably end up with the latter choice. On the node side, require() is curiously synchronous given node's heavy emphasis on asynchronous IO. As with the browser script tag, the synchronous require() is the best choice for simplicity. But the synchronous semantics prevents optimizations on both platforms. An asynchronous root-module loading API in a next generation system opens new opportunities. I hope and expect we'll end up with an async option on node. On balance I think a non-blocking module tag with optional blocking is reasonable. However, the description of the browser loading as require() within a asynchronous module tag is really a complete departure from all the previous discussions. A system based on require() is not statically analyzable. I could go on, but really a shift to this extreme seems so unlikely that there must be some misunderstanding. Rather I assume that the content of the module tag will be ES6 code as we know it now and that we will have an additional dynamic loading API that will be asynchronous much like we had earlier this year. Exactly the same solution would work in node. In other words, script and require() would not be used in future code, an async API would be available for root loading, and most developers most of the time would write synchronous code manipulating modules contents. If we are not heading in this direction I hope there will be more discussions in public. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Any news about the `module` element?
On Fri, Dec 19, 2014 at 8:55 PM, caridy car...@gmail.com wrote: inline... On Dec 19, 2014, at 3:21 PM, James Burke jrbu...@gmail.com wrote: ... * How does dynamic loading work in a web worker? In general, how does dynamic loading work when there is no DOM. think about this as nodejs without NPM and core modules, where we can only do `require(‘./path/to/something.js’)` and `require(‘/full/path/to/something/else.js’)`, and we can evolve from there. The web worker is definitely in our radar, we just don’t have a solution for it without the loader implementation (same for realms). This seems to imply that module loading would be a blocking, synchronous call. Such a change would have huge implications, just as the previous Loader's async dynamic API did in reverse. Either way I hope there will be some public debate on that issue so we come away believing the best choice was made. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Any news about the `module` element?
On Sat, Dec 20, 2014 at 10:54 AM, Matthew Robb matthewwr...@gmail.com wrote: On Sat, Dec 20, 2014 at 1:50 PM, Caridy Patino car...@gmail.com wrote: what make you think this proposal implies blocking? I think he was reading your examples using require() and thinking you were suggesting that the semantics would match. Indeed that is what I was thinking. A non-blocking module tag is a poor match to HTML, a declarative language where order of tags means order of parsing and rendering. Giving up this fundamental characteristic of HTML, in the long-shot effort to improve the apparent load time for some amateur Web sites, has become dogmatic so I suppose there is no value in discussing it. A non-blocking module tag would also prevent experienced developers from controlling rendering through JS action. That means they will need to use script tags which we'd like to deprecate or we'd have to have a blocking form of module. We'll probably end up with the latter choice. On the node side, require() is curiously synchronous given node's heavy emphasis on asynchronous IO. As with the browser script tag, the synchronous require() is the best choice for simplicity. But the synchronous semantics prevents optimizations on both platforms. An asynchronous root-module loading API in a next generation system opens new opportunities. I hope and expect we'll end up with an async option on node. On balance I think a non-blocking module tag with optional blocking is reasonable. However, the description of the browser loading as require() within a asynchronous module tag is really a complete departure from all the previous discussions. A system based on require() is not statically analyzable. I could go on, but really a shift to this extreme seems so unlikely that there must be some misunderstanding. Rather I assume that the content of the module tag will be ES6 code as we know it now and that we will have an additional dynamic loading API that will be asynchronous much like we had earlier this year. Exactly the same solution would work in node. In other words, script and require() would not be used in future code, an async API would be available for root loading, and most developers most of the time would write synchronous code manipulating modules contents. If we are not heading in this direction I hope there will be more discussions in public. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: What would a 1JS-friendly strict mode look like?
1JS strict mode would look like modules. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing modules that don't exist
Traceur reports such errors like this: // Error: File not found 'feature/Modules/resources/no_such_file.js' // Error: Specified as ./resources/no_such_file.js. // Error: Imported by feature/Modules/Error_InvalidModuleDeclaration.module.js. // Error: Normalizes to feature/Modules/resources/no_such_file.js // Error: locate resolved against base './' import * as b from './resources/no_such_file.js'; jjb On Fri, Nov 21, 2014 at 3:49 AM, Marius Gundersen gunder...@gmail.com wrote: On Fri, Nov 21, 2014 at 11:49 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: a native ImportError seems to me the best option and it's also easy to polyfill in a meaningful way with all current module loaders used already out there. My experience with AMD and require.js is that it is very useful for the error to include not only the module that couldn't be loaded but also the module that requested it. These two fields should be on the Error object, and so a new ImportError with the field `missingModule` and `requestedBy` (or something similar) sounds like a good solution to me. Marius Gundersen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing modules that don't exist
At least using the older loader spec 'file' and 'line' alone is not enough information for the loader to determine which file to load. I think the error message should echo all of the information the developer would need to recreate the error state and hopefully diagnose the issue. I agree that the importing line would be a good addition. jjb On Fri, Nov 21, 2014 at 9:18 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: to be honest I think that `.file` and `.line` would cover the who imported what scenario but those look like a very good/complete `.message` for such error, nice job On Fri, Nov 21, 2014 at 3:37 PM, John Barton johnjbar...@google.com wrote: Traceur reports such errors like this: // Error: File not found 'feature/Modules/resources/no_such_file.js' // Error: Specified as ./resources/no_such_file.js. // Error: Imported by feature/Modules/Error_InvalidModuleDeclaration.module.js. // Error: Normalizes to feature/Modules/resources/no_such_file.js // Error: locate resolved against base './' import * as b from './resources/no_such_file.js'; jjb On Fri, Nov 21, 2014 at 3:49 AM, Marius Gundersen gunder...@gmail.com wrote: On Fri, Nov 21, 2014 at 11:49 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: a native ImportError seems to me the best option and it's also easy to polyfill in a meaningful way with all current module loaders used already out there. My experience with AMD and require.js is that it is very useful for the error to include not only the module that couldn't be loaded but also the module that requested it. These two fields should be on the Error object, and so a new ImportError with the field `missingModule` and `requestedBy` (or something similar) sounds like a good solution to me. Marius Gundersen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: A new ES6 draft, Rev28
On Tue, Oct 14, 2014 at 11:04 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: This includes the major work items from the September TD39 meeting. Changes include: - Removed loader pipeline and Reflect.Loader API (functionality being transfered to sperate specification) Any discussion about will author this separate spec - TC39? yes, same folks driving the work. Just decoupled the specs and schedules. I just tried to lookup some thing about modules on http://people.mozilla.org/~jorendorff/es6-draft.html. The Loader related stuff is now either unrecognizable or completely different. Why were such drastic changes made and where is the discussion about the path forward? jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: what makes a file a module?
On Sun, Oct 19, 2014 at 2:23 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: It is implementation dependent how it is determined whether an individual file will be parsed as a Script or as a Module. Axel alluded to a possible HTML extension that could be used to distinguish modules from scripts. But, exactly how modules will be integrated into HTML is still under development. You can imagine various ways that modules might be identified in a command line environment. for example js script1.js -m mod1.js -m mod2.js script2.js so of us have argued that a module file extension might be useful in such environments: js script1.js mod1.js mod2.js script2.js FWIW, traceur has to use --script vs --module on the command line and .module.js among files otherwise parsed as script. You may recall that Yehuda Katz suggested on this group that a prefix might be used, script:file.js. To avoid long arguments about What Is a URL, I suggest a postfix string, file.js,script. Of course a file extension would be better. Many build tools use filenames and this issue puts practical work with ES6 at a disadvantage. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: dynamic synchronous import
What is wrong with Loader.get()? --- Reflect.Loader.prototype.get ( name )If this Loader's module registry contains a Module with the given normalized name, return it. Otherwise, return undefined. If the module is in the registry but has never been evaluated, first synchronously evaluate the bodies of the module and any dependencies that have not evaluated yet. But more important perhaps, what is wrong with asynchronous loads? The System.import() promises a module after loading all of its dependencies; previously imported modules are not reloaded. This code can be used in development, then in production the bundled modules can be prefixed to load the registry and the same call executes the same app. If this scheme is not going to work now is the time to sort it out. jjb On Sat, Sep 27, 2014 at 10:01 PM, John Lenz concavel...@gmail.com wrote: I would like to see some way to preload everything, and be able to retrieve them synchronously, something like: System.loader.addNoAsync('...'); // throw if all imports aren't available already So that the script could be used during initial render. I understand that this would mean that the module would need to be parsed and executed synchronously. Forcing folks to never use any module for code that needs to be inline seems like a bad turn. On Fri, Sep 26, 2014 at 1:44 PM, John Barton johnjbar...@google.com wrote: Theoretically you can use System.normalize() and System.get() to lookup a module by name synchronously. The normalize feature requires a referrer or address. Since browsers are determined to eliminate synchronous scripts, you may as well deal with the asynchronous System.import() and obnoxious promises stuff now and save yourself some pain later. jjb On Fri, Sep 26, 2014 at 9:40 AM, Konstantin Ikonnikov ikokos...@gmail.com wrote: I don't want load module using http request. In my case module already defined and I want import it later when I get its name: ```js var moduleName = getModuleName(); import { foo } from moduleName; // use foo ``` 2014-09-26 20:00 GMT+04:00 Marius Gundersen gunder...@gmail.com: And the reason you cannot import a module synchronously is that it would freeze the entire browser until the http request completes, which could be several seconds on a slow internet connection. If you want to import something dynamically you can do it using the API (to be finalized, I believe): ```js var moduleName = 'foo'; Loader.import(moduleName).then(function(foo){ //use foo here }); ``` Marius Gundersen On Fri, Sep 26, 2014 at 5:29 PM, John Barton johnjbar...@google.com wrote: no. On Fri, Sep 26, 2014 at 8:12 AM, Konstantin Ikonnikov ikokos...@gmail.com wrote: Can I import module dynamically, but synchronously? Example for common js ```js var moduleName = 'foo'; var foo = require(moduleName); ``` In es6 draft I found that ModuleSpecifier must be a StringLiteral http://people.mozilla.org/~jorendorff/es6-draft.html#sec-imports ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: dynamic synchronous import
no. On Fri, Sep 26, 2014 at 8:12 AM, Konstantin Ikonnikov ikokos...@gmail.com wrote: Can I import module dynamically, but synchronously? Example for common js ```js var moduleName = 'foo'; var foo = require(moduleName); ``` In es6 draft I found that ModuleSpecifier must be a StringLiteral http://people.mozilla.org/~jorendorff/es6-draft.html#sec-imports ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: dynamic synchronous import
Theoretically you can use System.normalize() and System.get() to lookup a module by name synchronously. The normalize feature requires a referrer or address. Since browsers are determined to eliminate synchronous scripts, you may as well deal with the asynchronous System.import() and obnoxious promises stuff now and save yourself some pain later. jjb On Fri, Sep 26, 2014 at 9:40 AM, Konstantin Ikonnikov ikokos...@gmail.com wrote: I don't want load module using http request. In my case module already defined and I want import it later when I get its name: ```js var moduleName = getModuleName(); import { foo } from moduleName; // use foo ``` 2014-09-26 20:00 GMT+04:00 Marius Gundersen gunder...@gmail.com: And the reason you cannot import a module synchronously is that it would freeze the entire browser until the http request completes, which could be several seconds on a slow internet connection. If you want to import something dynamically you can do it using the API (to be finalized, I believe): ```js var moduleName = 'foo'; Loader.import(moduleName).then(function(foo){ //use foo here }); ``` Marius Gundersen On Fri, Sep 26, 2014 at 5:29 PM, John Barton johnjbar...@google.com wrote: no. On Fri, Sep 26, 2014 at 8:12 AM, Konstantin Ikonnikov ikokos...@gmail.com wrote: Can I import module dynamically, but synchronously? Example for common js ```js var moduleName = 'foo'; var foo = require(moduleName); ``` In es6 draft I found that ModuleSpecifier must be a StringLiteral http://people.mozilla.org/~jorendorff/es6-draft.html#sec-imports ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Idea for Strawman: separate the core standard library itself into modules
A way to start would add new built-ins only in modules. jjb On Mon, Sep 22, 2014 at 12:15 PM, Isiah Meadows impinb...@gmail.com wrote: Transitioning the native API to modules is more of a proposed long term goal of this proposal. It'll take years to fully realize. On Sep 22, 2014 3:10 PM, Isiah Meadows impinb...@gmail.com wrote: @Brendan I'm aware of that pattern. For now, I'm more concerned about the option of modules. It would be nice to import the standard library features you need, and if, for some reason, one of the API natives get overwritten, you have a fallback. On Sep 22, 2014 1:18 PM, Brendan Eich bren...@mozilla.org wrote: Tab Atkins Jr. wrote: OnMon, Sep 22, 2014 at 9:04 AM, Domenic Denicola dome...@domenicdenicola.com wrote: From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Isiah Meadows I know this would break a lot of backwards compatibility completely, so this is purely hypothetical, and I expect this to not have a realistic chance anytime soon. Anything that breaks backward compatibility will not have a chance, realistic or otherwise,*ever*. To square this with Matthew's response, the original idea was to *also* expose the core functionality as modules, to give you the ability to grab clean versions of any standard functions you wanted, while the preexisting global versions would still be there. Right! Isaih, this is good news: you can't insist on removing stuff, but if you put the cleanups and better organization in new clothes, the old drab ones will fade into disuse (even if they don't ever go away). This is kind of a law of the Web. It turns out compat does break, and no one notices (much), over very long timeframes. At least, we saw this going from the early Web to the modern days, with a few things (corner cases in JS and CSS table layout). But these were never predictable, or major. With strict-by-default modules, we can hope for 'with' to whither away over a decade. I wouldn't bet on it, since strict mode is still opt-in and will be for script, forever. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: import script -- .esm
I work on Traceur's loader and participate in the loader discussions on es-discuss. I find the lack of engagement by the developers of the loader disheartening. The long, painful, sometimes contentious discussions about classes yielded an outstanding design that works well. Is the loader on track for similar success? We have no idea. jjb On Wed, Sep 10, 2014 at 9:27 PM, Yehuda Katz wyc...@gmail.com wrote: There's a difference between ZOMG WORKING IN SECRET and talking to people and working on something privately that is still being fleshed out. Not every document on my laptop (or yours) is sufficiently ready for public consumption for me to put it on Github, even though I put many documents, in various levels of completion, on Github. Using a term like secret to refer to in-progress work is unnecessary inflammatory. Yehuda Katz (ph) 718.877.1325 On Wed, Sep 10, 2014 at 11:20 AM, Anne van Kesteren ann...@annevk.nl wrote: On Wed, Sep 10, 2014 at 6:14 PM, Brendan Eich bren...@mozilla.org wrote: RFC4329 rightly favors application/ -- but this is all beyond the scope of ECMA-262. Do Not Want TC39 deciding suffixes. Let developers develop conventions. (Just so long as they do not sound like skin diseases.) Well the default browser loader which is still secret(?) purportedly standardizes on a js suffix. That is probably why this came up. (I think text/javascript is just fine btw. text/* works great for HTML and CSS too. In any event, for the purposes of the browser JavaScript does not really have a MIME type. We parse anything we get...) -- http://annevankesteren.nl/ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
import script -- .esm
A couple of months ago I tried out the suggestion by Yehuda Katz to use import syntax with special module specifiers to mean parse-as-script, do evaluate but do not produce a module. The implementation worked well and now I want to put a version of this idea into Traceur. As soon as I started I ran it issues with the name. Obviously legacy: is ambiguous. script: looks like a URL, which I suppose was intended, but then we get into URLs in URLs. Furthermore, the URL scheme is very cumbersome with a filesystem, you have to have some side-table or algorithm to match URLs to directories or filenames. I implemented postfix ,script, but that sure looks like an extension. Which is exactly what the semantics are: a file with a different datatype needing different processing. So it seems to me that the most honest naming would be some thing like .ess. I would just implement that solution but I proposed a similar idea a while back to Traceur team I got a lot of pushback along the lines of JS is one language. Since then several Traceur users have asked for support to a non .js extension for loading modules, to be able to separate existing JS code in .js files from new module code in files marked with a different extension. Within Traceur's (mostly es6) code we have resorted to implicit marking-by-directory (All code in src/node is script, not module) or with the wonderful extension of .module.js to mean all the other files are script, but this one is module. So it's JS-is-one-language with two incompatible, unmentionable dialects ;-). Finally, naming modules as .js and ES6 Scripts as .ess has the weird result that ES5 scripts (in .js files) would be processed as ES6 modules. That seems dumb. So naming the new things, modules, with a new extension makes more sense. .esm seems like a obvious choice. I know this may not seem to be the most exalted of topics for standardization but the current choice of post-pending '.js' has real consequences for developers. Please consider this issue. jjb On Mon, Jul 14, 2014 at 9:57 PM, Yehuda Katz wyc...@gmail.com wrote: You could imagine a loader plugin that enabled: import legacy:foo; Which would evaluate the module in a script context. Yehuda Katz (ph) 718.877.1325 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: import script -- .esm
On Wed, Sep 10, 2014 at 9:35 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Sep 10, 2014, at 9:28 AM, Matthew Robb wrote: As soon as the language decided it would have a differentiation for modules vs scripts then it seems only natural that it should also specify at least some generic means of entry into one mode or another. Then it's up to browsers or who ever to determine what external signifiers would trigger module instead of script. Or the language parsing logic could say that in the presence of module syntax it will always be treated as module. I don't know if that's feasible or not *shrug* Modules and scripts can not always be identified by inspection. Consider: foo.js --- const answer = 42; --- The semantics of this are quite different depending upon whether foo.js is evaluated as a script or loaded as a module. This case is clearly as script, as a module it has no effect right? Isn't the only ambiguous case would be explicit global manipulation, where we could decide module is used and (most of the time ;-) win. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: import script -- .esm
On Wed, Sep 10, 2014 at 10:07 AM, Guy Bedford guybedf...@gmail.com wrote: The question of whether a file is a module or script is the same problem as to whether a module is ES6 or AMD or CommonJS. Moving it to the extension makes as much sense as having every CommonJS module written as `script.cjs`. I don't think these are the same problem. Existing JS, AMD and CommonJS can be parsed by the same parser, the ES6 Script parser. They can't be parsed by the ES6 Module parser. It is a problem, just not the same as this one. We know that we need outside metadata to work out how to interpret modules, and that the loader will have meta-configuration injection at some level, not determined by TC39. One of the purposes of having modules in ES was to unify the module work in mode and browser. Having two or more incompatible meta-data solutions to this simple problem will defeat that goal. In NodeJS, this can be through `package.json` properties which inform what module format the package is. In the browser, this could be a header, or part of package configuration. John, in your case specifically, it would be good to get more background to understand what type of meta process is most suitable. What more can I say? Some files need to be parsed as Script and some as Module. Sometimes they are in the same project and sometimes in the same directory. They work on browser and node. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: import script -- .esm
On Wed, Sep 10, 2014 at 11:02 AM, Guy Bedford guybedf...@gmail.com wrote: On 10 September 2014 19:18, John Barton johnjbar...@google.com wrote: In NodeJS, this can be through `package.json` properties which inform what module format the package is. In the browser, this could be a header, or part of package configuration. John, in your case specifically, it would be good to get more background to understand what type of meta process is most suitable. What more can I say? Some files need to be parsed as Script and some as Module. Sometimes they are in the same project and sometimes in the same directory. They work on browser and node. For Traceur, the default interpretation is as Module, so it sounds like you want a way to indicate files which break this rule and need to be interpreted as Script? Can you give an example of a type of file this would apply to? Every file in test/ that does not end in module.js (and by extrapolation every file in every existing test suite based on mocha, jasmine etc). Every file in src/node/ (and by extrapolation every pre-es6 node file). jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: import script -- .esm
On Wed, Sep 10, 2014 at 10:33 AM, Brendan Eich bren...@mozilla.org wrote: Matthew Robb wrote: I don't see why they have to? Traceur should be used as a build time tool that ultimately runs in legacy mode. Only REAL modern ES6 module implementations would run in this other world. Basically .es files today would be transpiled into .js files. I doubt people will do any such thing. We can have more suffixes (I was against .js2 in particular -- that particularly confusing proposal was why I unleashed the Nope-topus), but if people can adapt their existing practices with AMD/Require/CommonJS modules and use just .js, I bet they will. I was reporting on the problems in practice. I don't believe any of the problems with module vs script are specific to Traceur. This is not equivalent to the AMD/CommonJS problem. The AMD community agreed on a format and a function call; similarly commonjs. In the ES case, we have one syntax, import, with two meanings depending on an non-standard string interpretation. Tools will have to read metadata, tea-leaves, and etheric winds to keep up. Same as ever. This discussion is about the import statement and Loader.import(), not tools. Ultimately TC39 needs to draw a line: what is ES and what belongs elsewhere. Overall Loader does a good job of drawing that line. But one area I think it has missed is related to module specifiers, given the reality that input source comes from individually named locations. Leaving this detail of module specifiers undefined just makes ES6 harder to adopt, its not very hard to fix compared to many complex problems solved already and I don't see how it has a big downside to fix. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: import script -- .esm
On Wed, Sep 10, 2014 at 11:28 AM, Guy Bedford guybedf...@gmail.com wrote: But within that you would also need a distinction of CommonJS or global as well? One way might be to set up configuration to know which module names are of which format: ``` System.metadata['test/*'] = { format: 'global' }; System.metadata['src/node/*'] = { format: 'cjs' } ``` The property of which parser is appropriate applies to a file, rather than a directory. Thus I could imagine: ``` System.metadata['\.js$'] = { format: 'module' }; System.metadata['\.jsm$'] = { format: 'global' }; ``` This strategy would allow module loaders to paper over the differences created by not having a standard extension. Of course this mechanism doesn't exist by default - but you can create it easily with the loader hooks in just a few lines. This is equally true for many features added to ES6. jjb On 10 September 2014 20:14, John Barton johnjbar...@google.com wrote: On Wed, Sep 10, 2014 at 11:02 AM, Guy Bedford guybedf...@gmail.com wrote: On 10 September 2014 19:18, John Barton johnjbar...@google.com wrote: In NodeJS, this can be through `package.json` properties which inform what module format the package is. In the browser, this could be a header, or part of package configuration. John, in your case specifically, it would be good to get more background to understand what type of meta process is most suitable. What more can I say? Some files need to be parsed as Script and some as Module. Sometimes they are in the same project and sometimes in the same directory. They work on browser and node. For Traceur, the default interpretation is as Module, so it sounds like you want a way to indicate files which break this rule and need to be interpreted as Script? Can you give an example of a type of file this would apply to? Every file in test/ that does not end in module.js (and by extrapolation every file in every existing test suite based on mocha, jasmine etc). Every file in src/node/ (and by extrapolation every pre-es6 node file). jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ... A community is writing the spec...
You can find lots of information about design discussions by reading the ecmascript wiki, for example: http://wiki.ecmascript.org/doku.php?id=harmony:proxies. The other good resource is the past posts to this list and the meeting minutes, http://esdiscuss.org/. In general, the content that is painstakingly written down in the ES6 specification has been designed and discussed in great detail. The appropriate level of comments on those features needs to be equally detailed and thoughtful. Random comments about how you personally don't like some aspects of the design are better directed to your followers on twitter or perhaps a blog post. And of course you are free not to use any new features you dislike. I believe that is what Alex was attempting to communicate. jjb On Tue, Sep 9, 2014 at 3:25 PM, L2L 2L emanuelal...@hotmail.com wrote: Anyone care to justify the use case for the proxy object? Yes I understand it'll let us defined the behavior of an object. But couldn't that be a method for the Object constructor? E-S4L N-S4L On Sep 9, 2014, at 5:55 PM, L2L 2L emanuelal...@hotmail.com wrote: Huh? ... Should I be doing so? ... Huh? E-S4L N-S4L On Sep 9, 2014, at 5:54 PM, Alex Russell slightly...@google.com wrote: Is there seriously going to be no attempt whatsoever to moderate this list? On Tue, Sep 9, 2014 at 3:42 AM, L2L 2L emanuelal...@hotmail.com wrote: ... This language is turning note in an application than a programming language. It could of been a commonjs thing... Long live ES5+. I like the let, and const syntax add on. Foo feature and fits into the language. Yes ai agree they should release as CSS is releasing. E-S4L N-S4L On Sep 9, 2014, at 6:36 AM, Herby Vojčík he...@mailbox.sk wrote: L2L 2L wrote: It worry me... That a community is writing the spec... That a community Well, not the community is writing the spec. AWB is. :-) And he can be pretty tough, I more or less stopped reading this list thoroughly after his letting one of the issues I saw as important left ignored. Nevertheless: is writing the spec Look like W3C... That everyone is striving to get what they want in the language. Most of us are ES5 developers Meaning we don't delve into ES6 and what else to come. let, const, and a couple of others spec implantation is okay. These help better the language... But your adding feature and no trying to better what's already there. You might as well call yourself W3C equivalent.E As long as one can write compliant ES5. A new more stricture spec/style is being made. It's call ES5+ meaning that all compliant code is to be writing in ES5 and additional add on as the let and const statement plus other +. What I see is more functionality of the browser api then an actually language. A lot of us hope this spec die, as did ES4. Most of what you're adding could have been another add on spec... Like commonjs add on. I liked the idea of ES6 pretty much. The commitee was pretty strict in not adding too much, mostly paving cowpaths, had some roadmap, according to which ES6 should be approved in end of 2013. Now is second half of 2014, and lots of issues are not closed yet, from what I see. I got delusioned as well. Isn't the model of big new editions of spec over; in the times we live now, with two-week frequent releases? I think ES6 will never see the light when taken from this approach. That's why, shouldn't the release policy be changed so that: - More frequent, albeit smaller, releases are embraced as a rule; - ES5.5 will be scheduled (and delivered) as a Christmas present in 2014, selecting only small subset of less controversial items (let, const, Reflect global object with all API applicable to ES5.5, possibly block scope; no modules, no classes (unless there is consensus they are already near to perfect, though my issue was about new/super inconsistency), no symbols, no proxies, no for-of, iterators, generators, comprehensions, no promises); - schedule ES5.6 (and deliver it) for July 2015 with, for example, for-of, iterators, generators, comprehensions (it's all related, so in a single set) and if possible, classes and/or promises; ... etc. Possibly switching to 6 when something big gets in (symbols, classes, proxies). This would be nice. Really nice. To all of us who want to get ES.next and actually start developing in it. Thanks, Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss
Re: `this` inside modules
Was this decision reversed? I don't see Reflect.global in the new spec. online. jjb On Mon, Jun 9, 2014 at 10:08 AM, Caridy Patino car...@gmail.com wrote: My point: if 'this' is not global in modules, then ES6 must have an alternative way to name the global object. Yes, we covered that last week. `Reflect.global` seems like the right place for it considering that it will be defined per realm. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
instantiate() deps list
The Loader instantiate() function is described: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-reflect.loader.prototype.instantiate Based on that description I assume that the 'deps' property returned by instantiate() meant dependencies that would be loaded by the loader. That is, one can leverage the dependency traversal from a custom loader. But it's not possible to do this. Specifically: --- Otherwise, the instantiate hook must return an eventual instantiationRequest object. An instantiateRequest object has two required properties. The value of the deps property is an array of strings. Each string is the name of a module upon which the module identified by loadRequest has dependencies. The value of the execute property is a function which the loader will use to create the module and link it with its clients and dependencies. The function should expect to receive the same number of arguments as the size of the deps array and must return an eventual Module object. The arguments are Module objects and have a one-to-one correspondence with elements of the deps array. The module is evaluated during the linking process. First all of the modules it depends upon are linked and evaluated , and then passed to the execute function. Then the resulting module is linked with the downstream dependencies. --- However it turns out that the names in 'deps' are simply fetched and passed back to instantiate(). They do not enter the dependency analysis. To give a concrete example, if A depends on B depends on C and instantiate() is called with A, it can't simply return a deps list with b. It has to perform the entire dependency analysis of A and ensure the tree is loaded. Simply returning 'b' as a deps value will result in an execution sequence like A, B, and then C, not the order C, B, A one would expect from a dependency analysis. I'm sure there is a good reason for this behavior but it should be clearly called out in the spec. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Bundling vs sending serialized dependency graph
On Thu, Aug 21, 2014 at 8:37 AM, C. Scott Ananian ecmascr...@cscott.net wrote: On Thu, Aug 21, 2014 at 11:00 AM, John Barton johnjbar...@google.com wrote: Finally, it would be ideal if we could also adjust those dependencies on the fly, since if we're reflecting dependencies described in the mutable DOM structure, it might be mutated. I think this one is technically difficult. I don't think this is actually all that hard. We have a dependency graph, Where? The Load Request records imply a dependency graph. Are these maintained though out the life of the page? I don't see any existing reason to expect these are maintained. along with a list of things that are (a) required, (b) already loaded, and (optionally) (c) in-flight. We mutate the graph arbitrarily, recompute the list of things that we need to load given the new (a), compare that to (b) and (c), and then start new/cancel old loads as necessary. I don't think it's worthwhile to specify incremental algorithms here, just specify the stop-the-world computation over the complete graph. Optimization left to the implementation, if needed. Huh? How do you plan to parse the modules to obtain dependencies without sending them to the browser? [...] You've really lost me now. I thought your goal was to avoid sending C over the network. Now you want to send it without even seeing A? I think Ian has explained this multiple times already. The HTML file contains a declarative specification of all resource dependencies, via attributes on script tags or some such. This is either generated manually or via some future authoring tool. You deleted the context of my comment. I asserted that a build tool was needed. Ian claimed the Loader could do it. Now you are claiming I'm wrong because a build tool is used. This doesn't seem so crazy to me. That's because you left out the crazy part ;-) And, since presumably we can already deal with mutation of the dependency graph (see above), we can always adjust those declarations to match reality after we parse the module file (although probably only to add new edges, not remove any declared dependencies). Thus the base case with no explicit declarations in the HTML matches the on-demand behavior given by current ES6. Ian, FWIW, I've been staying out of this thread mostly because you seem to be on top of it -- and because frankly I've already been exhausted by the module wars. But IMO you're doing excellent work. I agree that the part of Ian's story about sending over the deps list is beginning to sound very attractive. In fact I think it is a stronger story than the current spec altogether. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Bundling vs sending serialized dependency graph
On Thu, Aug 21, 2014 at 1:55 PM, Ian Hickson i...@hixie.ch wrote: On Thu, 21 Aug 2014, John Barton wrote: ... more misunderstanding about bundles skipped... Let's give upon discussing bundles and pursue your dependency list scheme. I don't think it should be particularly complex. It only requires some minor changes. One is that we need to be able to declare dependencies ahead of the instantiate hook. By the way I recently discovered that the deplist returned by the instantiate hook does not enter the dependency graph analysis. These aren't dependencies in a list rather a list of things needed to be loaded. I'm not sure what you mean here. The list returned from instantiate is treated the exact same way as the list auto-discovered from import statements when instantiate returns undefined: it's passed to ProcessLoadDependencies(), which calls RequestLoad() and AddDependencyLoad(), which, if necessary, updates [[Dependencies]]. I'll defer to Guy Bedford's expertise: https://github.com/ModuleLoader/es6-module-loader/pull/204 That's all I'm talking about. I want to be able to update [[Dependencies]] earlier than instantiate, and I want to be able to mutate [[Dependencies]] to remove nodes that are no longer dependencies before the load is complete. Another (a subset, really) is that we need to be able to declare dependencies for ES6 modules as well as letting the ES6 infrastructure discover them automatically. In theory this should be straight-forward. In practice, well good luck. Good luck with what? The JS module space has had so many rounds of discussions that many participants are no longer willing to consider alternatives to their current point of view. Finally, it would be ideal if we could also adjust those dependencies on the fly, since if we're reflecting dependencies described in the mutable DOM structure, it might be mutated. I think this one is technically difficult. I don't think anyone here is going to shy away from technically difficult problems, it's kind of our bailiwick. :-) Sometimes it is better to have a simpler and less powerful tool which can be well understood than a tool with many difficult-to-master features. Mutating dependencies opens the door to many new kinds of bugs, not only in the implementation of the Loader but, more important, in the use of the Loader by developers. The idea is, in fact, to move as many of the technically difficult problems from things authors have to keep reinventing to things that browsers just support natively. I guess you're proposing the send the dependency graph to the browser, then when a new root is needed, the stored graph is compared with the currently-loaded modules. The additional modules needed are then requested as a group. Up to this point we can just use build tools and browsers. Actually, modulo the changes described above, the ES6 loader already does all this. Huh? How do you plan to parse the modules to obtain dependencies without sending them to the browser? You send them to the browser, just not in the module itself. Where do you get them from? For ES6 it has to be from a build tool or from the server because no one is going to type these in twice. Such a build tool is just not very difficult and it can be built in to dev servers so it has no impact on developers work flow. It just doesn't quite handle it at the level of pre-emptive declaration of dependencies. But suppose you had two modules A, B, and C. A and B depend on C. With ES6 today, when A is loaded, it loads C. If late you load B, B doesn't reload C; it just links into it. So this is all already supported. All that's needed is a way to tell the ES6 system to get C before it has even received A. You've really lost me now. I thought your goal was to avoid sending C over the network. Now you want to send it without even seeing A? Not sending C over the network at all wouldn't work, since it would mean A doesn't have its dependencies available. I don't follow. The idea is that authors be able to predeclare (relevant parts of) the dependency tree such that when a node in that tree is needed, e.g. A in the example above, all the relevant nodes can be fetched in parallel, e.g. A and C in the example above, rather than in a serialised manner, e.g. first fetching A, then parsing it, then fetching C. Authors have already predeclared the dependency relationships. Now you want them to re-declare them. Try it and let me know how many devs you convince. One way to do this would be to predeclare the modules, as in: script type=module src=a.js id=a needs=c load-policy=when-needed /script script type=module src=b.js id=b needs=c load-policy=when-needed /script script type=module src=c.js id=c load-policy=when-needed /script Go back to G+ and ask them if they plan to type thousands of such lines
Re: Referencing modules loaded by HTML Imports.
On Tue, Aug 19, 2014 at 4:22 PM, Ian Hickson i...@hixie.ch wrote: On Mon, 18 Aug 2014, John Barton wrote: I think we could also imagine that such an import declaration could be used without the HTML Import declaration. The fetch() call will ask for baseURL/foo/b.js and the server will say hey that's in an HMTL Import and serve text/html. The fetch() hook will have to detect this and process the HTML Import, then continue with the loading process. That's basically what everything I've been e-mailing the list about is intended to support. While I think this topic -- triggering an HTML Import from a JS import -- is interesting and potentially useful, there is no new syntax or I see no Loader implementation changes needed for this to work. Composing HTML Imports with System.import() has issues because the import is async, see https://groups.google.com/forum/#!topic/polymer-dev/gbWgeLNnMrE jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies during the load process.
On Wed, Aug 20, 2014 at 3:23 PM, Ian Hickson i...@hixie.ch wrote: On Wed, 20 Aug 2014, John Barton wrote: The reverse case, where a img depends on a script, is not a use case. Why not? What if the image has an onmouseover handler that calls an API function defined in a module, for instance? Then the page depends on the onmouseover handler code and it has a dependency on the module. Images are leaf nodes in the dependency tree. Can you show me the markup for how you would like this to work? I'm not sure I follow what your vision is here. script System.import('jquery').then(() = { $(document).ready(() = { $(img.a).hover(() = { $(this).stop().animate({opacity: 0}, slow); }, () = { $(this).stop().animate({opacity: 1}, slow); }); }); }); /script Here the page depends upon a mouseover handler which depends upon jquery. The handler and the page depend upon the image. ... If you don't want multiple round trips, import from a bundle. That doesn't work; see the discussion in this e-mail: https://mail.mozilla.org/pipermail/es-discuss/2014-August/038853.html So I answered on another thread. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Referencing modules loaded by HTML Imports.
I think that only makes sense if 'this.import()' worked for script-tags-marked-as-modules in general. If the general case supported it, then it should just work for HTML imports. OTOH, I think System.import() is clearer. jjb On Mon, Aug 18, 2014 at 6:23 PM, Matthew Robb matthewwr...@gmail.com wrote: Would there be any problems treating the html import as a virtual module itself. Giving all scripts inside the sub document the module context object as its this binding? Then to do any additional loading you'd need to do this.import(). On Aug 18, 2014 6:56 PM, John Barton johnjbar...@google.com wrote: On Mon, Aug 18, 2014 at 2:06 PM, Ian Hickson i...@hixie.ch wrote: Now, in the main page, you reference the HTML import: link rel=import href=foo.html Now how would you refer to the modules? We can't have #b refer to it, since the scope of IDs is per-document, and the import has a separate document. ... HTML imports and regular documents share a Window object, but have separate Documents objects. You can find out more about them here: http://w3c.github.io/webcomponents/spec/imports/ If they share a Window object then they should share a Loader, but they may have different baseURLs. So for you example above we write eg. import {b} from ./b; because the scripts in the HTML import will have names relative to the same default baseURL as the main document. So I guess URL space is like http://example.com/index.html http://example.com/foo.html http://example.com/b.js I suppose it would be more common for the component to be in a subdirectory, eg http://example.com/index.html http://example.com/foo/theFoo.html http://example.com/foo/b.js so the import would be import {b} from ./foo/b; I think we could also imagine that such an import declaration could be used without the HTML Import declaration. The fetch() call will ask for baseURL/foo/b.js and the server will say hey that's in an HMTL Import and serve text/html. The fetch() hook will have to detect this and process the HTML Import, then continue with the loading process. This much I'm just making up. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing modules inside HTML imports
On Mon, Aug 18, 2014 at 12:57 AM, Anne van Kesteren ann...@annevk.nl wrote: On Sun, Aug 17, 2014 at 8:52 PM, John Barton johnjbar...@google.com wrote: The argument goes like this: we all want secure Web pages, we can't secure Web pages that allow inline scripts, therefore we have to ban inline scripts. If the argument is wrong, ignore my advice, CSP will die. I personally think that would be great. It seems you did not read what I wrote. CSP does support inline scripts these days. So you are claiming that CSP no longer restricts inline scripts and that the various online docs are incorrect? Or only that the server set the unsafe-inline value to opt out of the restriction? Some of the sites that make me think this has not changed: http://www.w3.org/TR/CSP/ In either case, authors should not include 'unsafe-inline' in their CSP policies if they wish to protect themselves against XSS. https://developer.mozilla.org/en-US/docs/Web/Security/CSP/CSP_policy_directives *Note:* Both 'unsafe-inline' and 'unsafe-eval' are unsafe and can open your web site up to cross-site scripting vulnerabilities. http://content-security-policy.com/ jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing modules inside HTML imports
On Mon, Aug 18, 2014 at 8:02 AM, Anne van Kesteren ann...@annevk.nl wrote: On Mon, Aug 18, 2014 at 4:57 PM, John Barton johnjbar...@google.com wrote: So you are claiming that CSP no longer restricts inline scripts and that the various online docs are incorrect? Or only that the server set the unsafe-inline value to opt out of the restriction? Neither. See https://w3c.github.io/webappsec/specs/content-security-policy/ for the new nonce-source and hash-source features. (Don't read TR/, it's kind of equivalent to reading the previous version of ES, but worse.) Excellent thanks! Hope those new features are adopted and servers routinely implement the hash-source feature. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Referencing modules loaded by HTML Imports.
On Mon, Aug 18, 2014 at 10:43 AM, Ian Hickson i...@hixie.ch wrote: To avoid overly spamming the list I've coallesced my responses to various threads over the weekend into this one e-mail. I really think this makes the discussion more difficult to follow and certainly more difficult to participate in. Now, in the main page, you reference the HTML import: link rel=import href=foo.html Now how would you refer to the modules? We can't have #b refer to it, since the scope of IDs is per-document, and the import has a separate document. Separate document implies separate JS global: each needs its own Loader. So the rest of the questions aren't needed. HTML imports definitely need to expose modules across documents. Are you saying this requires changes to ES6 to support? What changes would we need? You need to give more details about such requirements. What is the runtime relationship between Imports and other documents? I assume the Import is providing some state that ends up in the importer but then you are saying these are different documents. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Changing dependencies during the load process.
On Mon, Aug 18, 2014 at 10:43 AM, Ian Hickson i...@hixie.ch wrote: On Fri, 15 Aug 2014, John Barton wrote: On Fri, Aug 15, 2014 at 3:41 PM, Ian Hickson i...@hixie.ch wrote: On Fri, 15 Aug 2014, John Barton wrote: The ES Loader does not maintain a dependency tree. It maintains a table of names-modules. Maybe I'm misunderstanding the ES6 loader spec. What's the Load Record [[Dependencies]] list? The dependencies for the Load. Once the load is complete the record is not needed. How about if the dependencies are changed during the load? For example: script id=a src=a.js load-policy=when-needed/script This seems like an unfortunate design choice script id=b src=b.js load-policy=when-needed/script script id=c needs=a ... /script script // at this point, the script with id=c is blocked waiting for a.js to // load. Let's change its dependencies: document.scripts.c.needs = 'b'; ...which leads to exotic quirks like this. // now the script needs to trigger b.js to load // a.js' load can be deprioritised (or canceled, if network is at a // premium), and no longer blocks the script from loading /script System.import already supports dynamic loading with runtime dependency selection. If you have a problem with it let's discuss that before redesigning it. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing modules inside HTML imports
Sounds promising, but the key use case cited by Brendan is ease-of-use so it's important that all of this happens by default as far as Web devs are concerned. On Mon, Aug 18, 2014 at 11:23 AM, caridy car...@gmail.com wrote: John, you can also use SPDY/HTTP2.0 PUSH to send sticky code alongside with the original HTML that will mimic the use of inline scripts but behaves like an external script. Essentially, you will have: `script src=/my-sticky-data-and-initialization-per-page.js/script`, while that script is actually sent thru the SPDY multi-plex, which means no roundtrip is issued, no perf penalty, and it complies with CSP restrictions, the best of both worlds! /caridy On Aug 18, 2014, at 11:35 AM, John Barton johnjbar...@google.com wrote: On Mon, Aug 18, 2014 at 8:02 AM, Anne van Kesteren ann...@annevk.nl wrote: On Mon, Aug 18, 2014 at 4:57 PM, John Barton johnjbar...@google.com wrote: So you are claiming that CSP no longer restricts inline scripts and that the various online docs are incorrect? Or only that the server set the unsafe-inline value to opt out of the restriction? Neither. See https://w3c.github.io/webappsec/specs/content-security-policy/ for the new nonce-source and hash-source features. (Don't read TR/, it's kind of equivalent to reading the previous version of ES, but worse.) Excellent thanks! Hope those new features are adopted and servers routinely implement the hash-source feature. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies found during the load (before instantiation)
On Mon, Aug 18, 2014 at 10:55 AM, Ian Hickson i...@hixie.ch wrote: On Wed, 13 Aug 2014, Ian Hickson wrote: One of the problems I'm running into when it comes to trying to integrate ES6 modules with HTML and new HTML-based dependency features is the way that I can't tell ES about dependencies I know about before the data is actually fetched and instantiated. Another example of where we have something like this is HTML imports. The fetch hook for HTML imports needs to actually be the hook that does all the parsing, since HTML loads incrementally. (For HTML imports, the translate and instantiate hooks are essentially no-ops.) This means that the in-band dependencies for HTML imports are found during the fetch hook, and need to be set up right away. For example, if an HTML import contains a script type=module block, that inline module needs to be added as dependency of the import itself (so that the import's 'load' event doesn't fire until all internal modules are loaded). It it contains an img src= element, that needs to be added as a dependency as its loading. This is similar to the instantiate hook adding dependencies, except that it has to happen earlier due to the incremental parsing. Can we explore the opposite question: how much does the HTML dependency problem really overlap the ES dependency problem? To the first approximation these are the same problem: given the root of graph, load all of the nodes of the graph. The solution to this generic problem is well known and the code, while not trivial, is not very complex. As soon as we go beyond this first level, the problems diverge. In fact I think your posts make the case that the character of these problems differ on so many points that code reuse is unlikely and algorithm reuse unwise. In particular the reason we -- 'we' being you and me -- can't understand the ES spec is (evidently) that it supports loading a graph of mixed nodes (ES and legacy) with different assumptions about circular references. HTML is unlikely to have the identical requirements on circular references and it's legacy (script tags, document.write, mutable declarations, HTML imports) has quite different issues. It seems to me that a better design for HTML dependency loading would integrate with the ES Loader rather than attempt to mutate it. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies during the load process.
On Mon, Aug 18, 2014 at 2:00 PM, Ian Hickson i...@hixie.ch wrote: On Mon, 18 Aug 2014, John Barton wrote: On Mon, Aug 18, 2014 at 10:43 AM, Ian Hickson i...@hixie.ch wrote: On Fri, 15 Aug 2014, John Barton wrote: On Fri, Aug 15, 2014 at 3:41 PM, Ian Hickson i...@hixie.ch wrote: On Fri, 15 Aug 2014, John Barton wrote: The ES Loader does not maintain a dependency tree. It maintains a table of names-modules. Maybe I'm misunderstanding the ES6 loader spec. What's the Load Record [[Dependencies]] list? The dependencies for the Load. Once the load is complete the record is not needed. How about if the dependencies are changed during the load? For example: script id=a src=a.js load-policy=when-needed/script This seems like an unfortunate design choice Can you elaborate? What would a better design be? The current System.import + Loader mechanism. I'm certainly not married to this approach. Fundamentally, though, if the problem is how to mark HTML elements as load on demand with a dependency tree, I don't see many options beyond putting things in HTML attributes or elements. (I use scripts in the example above, but the problem applies equally to images or other non-script features, and the use cases for them apply even with scripting disabled. The problems are not equal but rather have significant unique aspects. For example, marking images as load on demand so that they don't load until the user scrolls down, with some images needing particular style sheets that are also to not load until you scroll down to the relevant image.) Why should I have to mark images? The page should load the images needed for the visible area. (But I'm unsure if this is even technically feasible since images below the fold could affect layout above the fold). script id=b src=b.js load-policy=when-needed/script script id=c needs=a ... /script script // at this point, the script with id=c is blocked waiting for a.js to // load. Let's change its dependencies: document.scripts.c.needs = 'b'; ...which leads to exotic quirks like this. Well, the DOM is mutable. If we hook something into the DOM, we have to define what happens when it mutates. There is no reason to make this case work great. It's much more important to make the simple cases work well. // now the script needs to trigger b.js to load // a.js' load can be deprioritised (or canceled, if network is at a // premium), and no longer blocks the script from loading /script System.import already supports dynamic loading with runtime dependency selection. If you have a problem with it let's discuss that before redesigning it. I'm not sure I follow. Can you elaborate? Your examples use script. I just don't think now that we should use the same solution for HTML. We should analyze the HTML requirements and design a solution. If the result is similar to script then we can reuse. If we do want to follow the pattern of the script loader, we would extract 'static' dependencies by parsing and use script for dynamic dependencies. We would not mix them. In parsing for static dependencies we need not start from the assumption of extra declarations. These extra declarations added to ES6 are really about convenient abbreviations. For example, import {Foo} from 'src/baz/Foo'; var foo = new Foo(); is just a much nicer syntax than var foo = new {src/baz/Foo}.Foo(); // illegal or whatever. But in the case of image tags we already know exactly which image the HTML depends upon. All we have to do is not load it until we need it to render the page. (Again I'm assuming a magical solution to the rendering part, which is needed in any dependency loading solution). How would you use System.import() to mark e.g. an image as dependent on a style sheet when scripting is disabled? Once we understand how these dependencies arise we can look for ways to extract the dependency information and determine whether explicit dependency declaration is needed. Or indeed even when scripting is enabled, how would you use it to mark one non-loaded script as dependent on another non-loaded script such that when you later ask for the former, the latter loads automatically? import './latter'; It's a solved problem for scripts. If you ask about images, then you will have to explain what it means for an image to be dependent upon an image. Surely there are legitimate non-script dependencies but we can't just treat everything like script and vice versa. Discussing HTML dependency loading and ES dependency loading together makes a lot of sense -- up to a point. But requiring specs and implementations to converge does not seem good to me now. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Referencing modules loaded by HTML Imports.
On Mon, Aug 18, 2014 at 2:06 PM, Ian Hickson i...@hixie.ch wrote: Now, in the main page, you reference the HTML import: link rel=import href=foo.html Now how would you refer to the modules? We can't have #b refer to it, since the scope of IDs is per-document, and the import has a separate document. ... HTML imports and regular documents share a Window object, but have separate Documents objects. You can find out more about them here: http://w3c.github.io/webcomponents/spec/imports/ If they share a Window object then they should share a Loader, but they may have different baseURLs. So for you example above we write eg. import {b} from ./b; because the scripts in the HTML import will have names relative to the same default baseURL as the main document. So I guess URL space is like http://example.com/index.html http://example.com/foo.html http://example.com/b.js I suppose it would be more common for the component to be in a subdirectory, eg http://example.com/index.html http://example.com/foo/theFoo.html http://example.com/foo/b.js so the import would be import {b} from ./foo/b; I think we could also imagine that such an import declaration could be used without the HTML Import declaration. The fetch() call will ask for baseURL/foo/b.js and the server will say hey that's in an HMTL Import and serve text/html. The fetch() hook will have to detect this and process the HTML Import, then continue with the loading process. This much I'm just making up. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies during the load process.
On Mon, Aug 18, 2014 at 5:32 PM, Ian Hickson i...@hixie.ch wrote: On Mon, 18 Aug 2014, John Barton wrote: ... But in the case of image tags we already know exactly which image the HTML depends upon. But other elements might depends on the img, and that we don't know. (For example, a graphical game might need some sprite assets to be loaded before it can start up. So its script might be marked as depending on an img element that loads that image. Or the script contents might have an import statement that refers to that image.) Supporting this case seems straight-forward and can be done entirely by the browser Loader implementation using hooks. The reverse case, where a img depends on a script, is not a use case. Or indeed even when scripting is enabled, how would you use it to mark one non-loaded script as dependent on another non-loaded script such that when you later ask for the former, the latter loads automatically? import './latter'; It's a solved problem for scripts. The key part of my question was non-loaded. The import bit is in the script. The script isn't loaded yet, so we can't rely on it. script System.import('./former').then((former) = { // do stuff with former, knowing './former' imported './latter'. }); /script Here we are expressing the dependency of the HTML file on the non-loaded file './former' and it depends on the non-loaded file './loaded'. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing modules inside HTML imports
On Sat, Aug 16, 2014 at 10:22 AM, Brendan Eich bren...@mozilla.org wrote: Yes -- inline scripts, like document.write, the drive-in, disco, and Fortran, will never die. More things I don't suggest investing effort in. /be Anne van Kesteren wrote: On Sat, Aug 16, 2014 at 2:46 AM, John Bartonjohnjbar...@google.com wrote: As we noted in another thread, Web devs no longer control servers. And servers no longer allow inline script (for the most part going forward). So I don't see this feature as worth investing effort in. (I don't like it either, but it is what it is). That doesn't ring true. CSP didn't, but does now based on feedback that not having inline scripts was too painful. I very much doubt they will go away anytime soon. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing modules inside HTML imports
On Sun, Aug 17, 2014 at 10:08 AM, Brendan Eich bren...@mozilla.org wrote: John Barton wrote: On Sat, Aug 16, 2014 at 10:22 AM, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: Yes -- inline scripts, like document.write, the drive-in, disco, and Fortran, will never die. More things I don't suggest investing effort in. Seriously, inline scripts were and are important, both for avoiding extra requests (even with HTTP++ these cost) and, more important, for easiest and smoothest beginner/first-script on ramp. I have no idea why anyone would seriously contend otherwise. Latency still matters; tools didn't replace hand-authoring. These are not subjective matters. I agree, but the forces behind CSP control the servers. You'll have to convince them. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing modules inside HTML imports
On Sun, Aug 17, 2014 at 11:14 AM, Rick Waldron waldron.r...@gmail.com wrote: On Sunday, August 17, 2014, John Barton johnjbar...@google.com wrote: On Sun, Aug 17, 2014 at 10:08 AM, Brendan Eich bren...@mozilla.org wrote: John Barton wrote: On Sat, Aug 16, 2014 at 10:22 AM, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: Yes -- inline scripts, like document.write, the drive-in, disco, and Fortran, will never die. More things I don't suggest investing effort in. Seriously, inline scripts were and are important, both for avoiding extra requests (even with HTTP++ these cost) and, more important, for easiest and smoothest beginner/first-script on ramp. I have no idea why anyone would seriously contend otherwise. Latency still matters; tools didn't replace hand-authoring. These are not subjective matters. I agree, but the forces behind CSP control the servers. You'll have to convince them. Forgive me, but I don't follow this—could you elaborate? It would be appreciated. The argument goes like this: we all want secure Web pages, we can't secure Web pages that allow inline scripts, therefore we have to ban inline scripts. If the argument is wrong, ignore my advice, CSP will die. I personally think that would be great. If the argument is correct, then people who run servers and thus are liable for security failures will have to choose between security and easiest and smoothest beginner/first-script on ramp. In my opinion, security will win this contest every time. Server operators are under a lot of pressure to improve security so they are likely to adopt CSP requirements. Of course I could be wrong, that's the thing about advice. HTH, jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Fri, Aug 15, 2014 at 9:43 AM, Ian Hickson i...@hixie.ch wrote: On Thu, 14 Aug 2014, John Barton wrote: But since the only way the client can know that it needs a.js and jquery.js is if the server tells it [...] There's at least four ways this can happen: - the server tells the browser that it needs file a.js when the server is sending index.html, then tells the browser that it needs query.js when it is sending a.js, and the server doesn't preemptively send anything. - the server sends the browser all three files at once, preemptively. - the server tells the browser that it needs file a.js when sending index.html, then when a.js is requested, it preemptively sends jquery.js at the same time as telling the browser that it'l need it. - the server tells the browser that it needs files a.js and jquery.js at the same time as when it is sending index.html, and the server doesn't preemptively send anything. The first is too slow, since it requires one RTT per file. It's what we have now, and what ES6 modules describe in the absence of server support. The second is too slow, because it implies sending resources that aren't needed, possibly using up bandwidth that could be used for other purposes. It's something that can be supported by packaging and other solutions already being developed, if people want it. The second method is faster than your method. It results in the same three file transfer in one less round trip. The second method does not imply sending any more or less resources than any other method listed. The second and third require server-side support beyond what many authors will be able to do. HTTP2 can provide this if people want it, I believe. The fourth is what I'm looking at. The fourth consists of the server having no built-in knowledge except what is in-band in the HTML file, namely, predeclared dependency trees. By humans writing markup? That's not happening, at least not for more than trivial programs. No one is going to write hundreds of lines of dependency declaration already specified in their JS files. And if you allow a tool running on the server (eg a build) then its the same as bundling with an extra unnecessary round trip. ... If you meant suppose we had magic file on the server which listed dependencies and a Loader that read that file, then we can succeed by building the magic file and don't need server code changes. Well, the file wouldn't be magic. It'd just be a predeclared dependencies in the HTML file, something that authors have long asked for, at least on the WHATWG list. You mean devs re-writing the same declarations they used in JS in HTML? Do these authors write modular JS? I am very skeptical. That's what bundling does: builds a magic file and ships all of the required modules in dependency order to the server. It even skips the step where the list it built and just sends the all the dependencies. Could we have better tools that allowed finer grained control over the bundle size vs trips? Sure. Ok, great. That's all I'm asking for. Actually I'm asking for less than that, I'm asking if the ES6 module system could be slightly adjusted so that this finer-grained control could be implemented on top of it without duplicating the dependency management (which is what you have to do now if you manually call LoadModule() on the dependencies early). You can specify dependencies in `instantiate()` returns. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Fri, Aug 15, 2014 at 2:43 PM, Ian Hickson i...@hixie.ch wrote: On Fri, 15 Aug 2014, John Barton wrote: On Fri, Aug 15, 2014 at 9:43 AM, Ian Hickson i...@hixie.ch wrote: On Thu, 14 Aug 2014, John Barton wrote: But since the only way the client can know that it needs a.js and jquery.js is if the server tells it [...] There's at least four ways this can happen: - the server tells the browser that it needs file a.js when the server is sending index.html, then tells the browser that it needs query.js when it is sending a.js, and the server doesn't preemptively send anything. - the server sends the browser all three files at once, preemptively. - the server tells the browser that it needs file a.js when sending index.html, then when a.js is requested, it preemptively sends jquery.js at the same time as telling the browser that it'l need it. - the server tells the browser that it needs files a.js and jquery.js at the same time as when it is sending index.html, and the server doesn't preemptively send anything. The first is too slow, since it requires one RTT per file. It's what we have now, and what ES6 modules describe in the absence of server support. The second is too slow, because it implies sending resources that aren't needed, possibly using up bandwidth that could be used for other purposes. It's something that can be supported by packaging and other solutions already being developed, if people want it. The second method is faster than your method. It results in the same three file transfer in one less round trip. The second method does not imply sending any more or less resources than any other method listed. The second is too slow because there's lots of other files involved in practice, for example the default style sheet, the scripts that are needed straight away, the Web components that are needed straight away, all the default images, etc. The whole point of the discussion in this thread is that we're talking about files that are not needed straight away, and how to obtain them promptly once they are needed. Loading all of the files in a web page in the order they are needed is great goal and one that I think would make a great improvement in the Web. It is certainly true that data for pages is chunky: we need a mechanism for loading a group of related files at the right time. Within each chunk we need all of the files if we need the root of the chunk. But that is exactly the ES6 case: if we need the root of the dependency tree, then we need all of the tree, that is the declarative design. Having a design where the browser gets all the names, sends all the names back to the server, and gets the tree is just wasting a trip. Simply send the tree when the browser asks for the tree. That's why in my opinion 'bundles' or 'packages' make sense: they combine the related dependencies and allow them to be loaded in one trip. Divide this problem in to small pieces: ES6 bundles, HTML Imports, and some bundle/package loading solution. Don't use the same fine-grained solution for all layers. The second and third require server-side support beyond what many authors will be able to do. HTTP2 can provide this if people want it, I believe. The fourth is what I'm looking at. The fourth consists of the server having no built-in knowledge except what is in-band in the HTML file, namely, predeclared dependency trees. By humans writing markup? That's not happening, at least not for more than trivial programs. It turns out that on the Web, there are lots of trivial programs. When you have trillions of Web pages, even the smallest of fractions ends up being significant numbers of pages. Such programs don't need the kind of features we are discussing. No one is going to write hundreds of lines of dependency declaration already specified in their JS files. Maybe not hundreds, but maybe dozens. Also, not all these dependencies are written in their JS files. Also, it turns out that people will do lots of things to make their pages quicker, and it's a lot easier, in many cases, to adjust their markup than to adjust their server configuration. But the JS ones are written in JS files. And the non-JS ones are written somewhere. Inventing a mechanism that causes devs to duplicate all of this info is crazy. Just to be clear: I think dependency loading web pages is an awesome direction. Using a duplicate declarative solution? Not so much. And if you allow a tool running on the server (eg a build) then its the same as bundling with an extra unnecessary round trip. The tool is likely to not be running on the server, but on the developent machine. It's unfortunate, and I don't really understand it, but it's a fact of life on the Web that many authors have only minimal control over their servers. Many is now most
Re: Changing dependencies
The ES Loader does not maintain a dependency tree. It maintains a table of names-modules. So when the @import rules mutate, just load the new names. Any new modules will be traversed for dependents and new name-modules entries will be created. Well, assuming you figure out how to integrate CSS parsing for dependents. jjb On Fri, Aug 15, 2014 at 3:24 PM, Ian Hickson i...@hixie.ch wrote: ES6 modules are immutable, but some things on the Web platform that might have dependencies can have those dependencies change over time. For example, CSS style sheets have a mutable object model, and one of the things in that object model is their list of @imports, so you can dynamically change a style sheet's dependencies. Assuming we are implementing all CSS loads through the ES6 module loader system, what's the appropriate way in which I should spec reactions to changes to a CSS object's @import rules? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Changing dependencies
On Fri, Aug 15, 2014 at 3:41 PM, Ian Hickson i...@hixie.ch wrote: On Fri, 15 Aug 2014, John Barton wrote: The ES Loader does not maintain a dependency tree. It maintains a table of names-modules. Maybe I'm misunderstanding the ES6 loader spec. What's the Load Record [[Dependencies]] list? The dependencies for the Load. Once the load is complete the record is not needed. To be sure this is based on my old implementation experience. But as you say the modules are static so the dependency info is not useful after the load. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Importing modules inside HTML imports
On Fri, Aug 15, 2014 at 3:06 PM, Ian Hickson i...@hixie.ch wrote: Suppose you have an HTML import foo.html that declares two modules: script type=module id=a ... /script script type=module id=b ... /script As we noted in another thread, Web devs no longer control servers. And servers no longer allow inline script (for the most part going forward). So I don't see this feature as worth investing effort in. (I don't like it either, but it is what it is). How should they refer to each other? For example, if module id=b wants to import module id=a? I suppose the logical way is like this: import #a; import './a'; Now, in the main page, you reference the HTML import: link rel=import href=foo.html Now how would you refer to the modules? We can't have #b refer to it, since the scope of IDs is per-document, and the import has a separate document. Separate document implies separate JS global: each needs its own Loader. So the rest of the questions aren't needed. The logical way to do it would be: import foo.html#a; ...but that means that #a and foo.html#a should resolve to the same canonical string in the normalize hook. Presumably then, that's the full absolute URL? And we look up the document in the import list? But what if the import hasn't been instantiated yet? Should normalize just wait until it has been? (Otherwise, the module registry won't have the module and so locate will be called and locate won't have any idea what to do with that URL.) None of this is very compelling. Is there some expected way to do this that I haven't thought of? (Similar questions apply to referencing other things in imports, e.g. style sheets, images, etc.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Thu, Aug 14, 2014 at 2:20 PM, Ian Hickson i...@hixie.ch wrote: On Wed, 13 Aug 2014, John Barton wrote: On Wed, Aug 13, 2014 at 3:52 PM, Ian Hickson i...@hixie.ch wrote: On Wed, 13 Aug 2014, John Barton wrote: On Wed, Aug 13, 2014 at 2:59 PM, Ian Hickson i...@hixie.ch wrote: Suppose a page has this markup: script type=module id=jquery href=jquery.js whenneeded/script script type=module id=a href=a.js uses=jquery whenneeded/script script type=module import a; // ... /script Your example will just work if you just use script type=module import a; // ... /script When this module is compiled the other two will be loaded and compiled. That assumes that you have some sort of server-side support so that the server knows that when you request a, it should send a.js and jquery.js, which is an assumption that will work for some people but not [...] No, the loader just requests each of these when it needs them. Right. What I'm trying to do is have the loader load them _before_ it needs them. Without server-side support, on-demand loading looks like this: Client Server || 0ms |-_ | Client finds it needs a.js | -_| |-_ | | -_| Server sends back a.js | _- | | _- | | _- | 200ms |-_ | Client finds it needs jquery.js | -_| |-_ | | -_| Server sends back jquery.js | _- | | _- | | _- | 400ms |- | Client runs the scripts ...whereas if the client is aware of the dependencies early, it can do: Client Server || 0ms |-_ | Client finds it needs a.js and jquery.js | -_| |-_ | | -_| Server sends back a.js and jquery.js | _- | | _- | | _- | 200ms |- | Client runs the scripts ...which is a lot faster. But since the only way the client can know that it needs a.js and jquery.js is if the server tells it, then: Client Server sends a.js and jquery.js || 0ms |-_ | Client finds it has a.js and jquery.js 0ms |- | Client runs the scripts which is even faster. everyone. One of the big pieces of feedback I am dealing with on the HTML side is a request for a way to predeclare the dependency graph to avoid this problem (so that the browser knows to request a.js and jquery.js at Actually I guess you mean avoid multi-pass requests for the entire dependency graph. I'm not sure what that means. But if that means the same thing, then sure. Yes, your example just happens to be one layer deep and thus requires just one extra trip. The key is just that the client can request all the files it's going to need at one time, so that, even without server support, the client doesn't wait more than one total RTT. Wait, you claimed earlier that without server support it's extra round trips. Now without server support it's no extra round trips. Which one ;-) If you meant suppose we had magic file on the server which listed dependencies and a Loader that read that file, then we can succeed by building the magic file and don't need server code changes. That's what bundling does: builds a magic file and ships all of the required modules in dependency order to the server. It even skips the step where the list it built and just sends the all the dependencies. Could we have better tools that allowed finer grained control over the bundle size vs trips? Sure. (If you don't have either server-side support or client-side dependency predeclaration, you end up having to discover the dependency chart at runtime, which is a huge latency loss.) Well, as they said back when I worked on a dairy, you've step in it. This issue is at the root of the split between commonjs (modules for node, synchronous loading) and requirejs (modules for browser, prebuilt into bundles to avoid latency). The ES module system attempts to solve this by providing an asynchronous API (eg System.import()) and a proposal, to support server side dependency bundling in HTTP++. The workaround we have now is to pre-build bundles and use the locate() function to map module ids into bundles. That is basically the requirejs solution (with a much better programmer API). I predict node will extend their System to include a synchronous API. Then the circle will be complete. To be sure this is a difficult or even fundamental problem. I respect all efforts to solve this problem; don't believe anyone who says the solution is simple. Relying on packages doesn't really scale, unfortunately. When you have thousands of modules, as e.g. Google+ does, some of which are script and some
Re: Modules and dependencies known before the load
Your example will just work if you just use script type=module import a; // ... /script When this module is compiled the other two will be loaded and compiled. jjb On Wed, Aug 13, 2014 at 2:59 PM, Ian Hickson i...@hixie.ch wrote: One of the problems I'm running into when it comes to trying to integrate ES6 modules with HTML and new HTML-based dependency features is the way that I can't tell ES about dependencies I know about before the data is actually fetched and instantiated. The problem can essentially be summarised by this line from the definition of ProcessLoadDependencies(): # The ProcessLoadDependencies abstract operation is called after one # module has nearly finished loading. It starts new loads as needed to # load the module's dependencies. Suppose a page has this markup: script type=module id=jquery href=jquery.js whenneeded/script script type=module id=a href=a.js uses=jquery whenneeded/script script type=module import a; // ... /script ...where uses is some hypothetical markup for telling the browser about dependencies ahead of time (the assumption being that anims.js contains a line like 'import jquery;'), and where whenneeded is some attribute that tells the browser to not bother starting the whole loading process until the resource is needed. In this example, the first two scripts do nothing at first. Then the third one is parsed, PromiseOfStartLoadPartwayThrough() is called with the contents of the element as the source, and eventually the ES system learns that it wants module a. Here, the normalize and locate hooks work together to determien that the element with id=a is what we're looking for. (Maybe it should be import #a, to distinguish a package name from an ID, but that's a topic for another e-mail.) At this point, I want to tell the ES6 module that: (a) we need to set off a load for that second script element, and (b) once we have that script element's file, it's probably going to want to import jquery, and therefore, we should also set off a load for that first script element with id=jquery. Right now, I don't see any way to do (b). ProcessLoadDependencies() is called after instantiate is done (by InstantiateSucceeded()), and it is the first time the ES6 module system tries to load anything. Ideally I think we should adjust the ES6 module system to support loading and compiling code (though not necessarily executing it) for dependencies at or around the fetch hook. Failing that, I guess we can also just do that at the HTML level. Will that just work? I'm not able to follow the ES spec closely enough to determine if, when ProcessLoadDependencies() is called for a and finds it needs jquery, it will properly link to the as-yet-not-loaded-but- already-in-progress-load for jquery. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules and dependencies known before the load
On Wed, Aug 13, 2014 at 3:52 PM, Ian Hickson i...@hixie.ch wrote: On Wed, 13 Aug 2014, John Barton wrote: On Wed, Aug 13, 2014 at 2:59 PM, Ian Hickson i...@hixie.ch wrote: Suppose a page has this markup: script type=module id=jquery href=jquery.js whenneeded/script script type=module id=a href=a.js uses=jquery whenneeded/script script type=module import a; // ... /script Your example will just work if you just use script type=module import a; // ... /script When this module is compiled the other two will be loaded and compiled. That assumes that you have some sort of server-side support so that the server knows that when you request a, it should send a.js and jquery.js, which is an assumption that will work for some people but not No, the loader just requests each of these when it needs them. everyone. One of the big pieces of feedback I am dealing with on the HTML side is a request for a way to predeclare the dependency graph to avoid this problem (so that the browser knows to request a.js and jquery.js at Actually I guess you mean avoid multi-pass requests for the entire dependency graph. the same time). People apparently have huge difficulties even getting their servers configured to send the right MIME types, let alone getting the servers to know about dependencies. Yup. (If you don't have either server-side support or client-side dependency predeclaration, you end up having to discover the dependency chart at runtime, which is a huge latency loss.) Well, as they said back when I worked on a dairy, you've step in it. This issue is at the root of the split between commonjs (modules for node, synchronous loading) and requirejs (modules for browser, prebuilt into bundles to avoid latency). The ES module system attempts to solve this by providing an asynchronous API (eg System.import()) and a proposal, to support server side dependency bundling in HTTP++. The workaround we have now is to pre-build bundles and use the locate() function to map module ids into bundles. That is basically the requirejs solution (with a much better programmer API). I predict node will extend their System to include a synchronous API. Then the circle will be complete. To be sure this is a difficult or even fundamental problem. I respect all efforts to solve this problem; don't believe anyone who says the solution is simple. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Understanding the 'normalize' Loader hook
See the implemention in es6-module-loader: https://github.com/ModuleLoader/es6-module-loader/blob/master/lib/system.js#L117 In traceur we have different code that passes the same tests. The tests: https://github.com/google/traceur-compiler/blob/master/test/unit/runtime/System.js We would map your examples to: On Tue, Aug 12, 2014 at 2:05 PM, Ian Hickson i...@hixie.ch wrote: Assume my script is http://example.com/test.js, and assume that there is no extra information (nobody has registered any module names or anything like that). If I do: import a; http://example.com/a.js import ./a; http://example.com/a.js import /a; /a.js import //example.com/a; http://example.com/a.js import http://example.com/a; http://example.com/a.js ...am I supposed to end up with the same normalized name for all five? How many entries in [[Modules]] should this result in? (I understand that the answer depends on the default loader; what I'm asking is, what should the default loader's behaviour be.) -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Understanding the 'normalize' Loader hook
On Tue, Aug 12, 2014 at 2:45 PM, Ian Hickson i...@hixie.ch wrote: On Tue, 12 Aug 2014, John Barton wrote: See the implemention in es6-module-loader: https://github.com/ModuleLoader/es6-module-loader/blob/master/lib/system.js#L117 Ah, fascinating. So basically: - normalize does relative URL logic based on the current base URL and the referrer (i.e. the URL of the script doing the importing). I would expect that normalized names to be platform independent. - locate resolves that URL and adds .js This step is platform dependent, it produces an address from a name. (only if the last segment is part of the path part of the URL and doesn't contain a .?). No such restriction is applied in our code. Is that more or less right? (There's also the loader.paths stuff. Why is that in locate rather than normalize?) Because the paths processing can produce arbitrary addresses (to cache, CDN, I guess) (BTW, I noticed that both in that code above and in the spec, referrer is consistently misspelt as referer, the HTTP way.) I've already reported this bug. I'm exploring some ways that the module system could be extended on the Web platform. You might look at Guy Bedford's experiment on loader plugins https://github.com/systemjs/systemjs that follow the path laid down by Jame Burke in requirejs http://requirejs.org/docs/api.html#plugins jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Understanding the 'normalize' Loader hook
On Tue, Aug 12, 2014 at 3:26 PM, Ian Hickson i...@hixie.ch wrote: On Tue, 12 Aug 2014, John Barton wrote:... (only if the last segment is part of the path part of the URL and doesn't contain a .?). No such restriction is applied in our code. Sure. What do we want for the default Web loader though? Be consistent with URLs.which.allow.dots Is that more or less right? (There's also the loader.paths stuff. Why is that in locate rather than normalize?) Because the paths processing can produce arbitrary addresses (to cache, CDN, I guess) Sure but presumably if someone explicitly puts in the long URL, they still don't want it to cause a second load, right? I mean, if you do: loader.paths = { 'foo': 'scripts/foo', }; // in a different module import foo; // in a different module import scripts/foo; ...surely you want just one module loaded. No? One module, but my point was more that the right hand side can be an absolute path. Come to think of it, maybe you actually just want one loaded even if someone does: import scripts/foo.js; In my opinion this should be an error. Either we have .js or we don't, not half-baked. ...or even: // assuming the base URL the whole time has been // http://www.example.com/ import http://www.example.com/scripts/foo.js;; Also an error. Is there any time we'd want all those imports to result in separate module loads? FWIW, most of the time I expect to write relative paths in imports: import ./foo/bar; If I see import foo/bar; I expect foo to be remapped to a package. Or to put it another way, we need a story for packages. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader vs ES6 Classes
Related issue that had come up in discussions I've had off this list: is it likely that the spec will constrain the constructor arguments of custom Loader classes to match the arguments of Reflect.Loader? For my part I was surprised that this might be a possibility. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader vs ES6 Classes
f you read the Loader source carefully you can see that Jason fixed the Loader to support inheritance. But his fix does not allow classes to inherit the platform's loading behavior. That behavior is given in options properties passed to instances. By defining the system loader as an instance of a SystemLoader extending Loader, the platform behavior would be extendable and the Loader would be ES6 not merely class-friendly. On Mon, Aug 4, 2014 at 6:40 PM, Kevin Smith zenpars...@gmail.com wrote: On Mon, Aug 4, 2014 at 6:33 PM, Kevin Smith zenpars...@gmail.com wrote: If I understand correctly, John was wanting to use a state-carrying options as the options argument when specifying hook overrides. What part of this has anything to do with ES6 classes? As far as I can tell, nothing. Looks like good work was done to make Loader class-friendly. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader vs ES6 Classes
As far as I can tell you are basically arguing that simple Loader hooks don't need object state. Of course that is true. And sure we can write code that carefully and cleverly avoids using 'this'. Why? ES6 added classes because this is often the clearest way to structure more complex systems. In my case the LoaderHooks.normalize() function needs to mark names as originating from 'script' rather than 'module' based on the name (eg 'script:' or in my case trailing ',script'. The marking table needs to be on 'this'. I extend LoaderHooks to InterceptOuputLoaderHooks which calls this.onTranscoded() to copy the transcoded results from load to listeners. But my real point is why should I have to think about 'this' binding in 2015? We don't need to use an old school API now, we have ES6. jjb On Mon, Aug 4, 2014 at 6:29 AM, Axel Rauschmayer a...@rauschma.de wrote: On Aug 4, 2014, at 15:16 , Juan Ignacio Dopazo jdop...@yahoo-inc.com wrote: In practice we've found that we rarely use the new Loader(hooks)` option and instead this is more common: var loader = new Loader(); var loaderFetch = loader.fetch.bind(loader); loader.fetch = function (loadRecord) { // do something return loaderFetch(loadRecord); }; Why not like this then? You’d need (a compiler for) ES6, though. ```js class MyLoader extends Loader { fetch(loadRecord) { // do something return super(loadRecord); } } let loader = new MyLoader(); ``` -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader vs ES6 Classes
Neither example binds 'this' assuming the current Loader implementation, so no object state. Although maybe you are saying your example ought to work, then we agree ;-) On Mon, Aug 4, 2014 at 7:47 AM, Axel Rauschmayer a...@rauschma.de wrote: On Aug 4, 2014, at 16:33 , John Barton johnjbar...@google.com wrote: As far as I can tell you are basically arguing that simple Loader hooks don't need object state. Of course that is true. No, I’m arguing that Juan’s code is basically “subclassing” a loader, overriding a method and calling that method. ES6 classes seem like a more elegant way of doing this. You’d get as much object state in the subclass as you want. And sure we can write code that carefully and cleverly avoids using 'this'. Why? ES6 added classes because this is often the clearest way to structure more complex systems. In my case the LoaderHooks.normalize() function needs to mark names as originating from 'script' rather than 'module' based on the name (eg 'script:' or in my case trailing ',script'. The marking table needs to be on 'this'. I extend LoaderHooks to InterceptOuputLoaderHooks which calls this.onTranscoded() to copy the transcoded results from load to listeners. But my real point is why should I have to think about 'this' binding in 2015? We don't need to use an old school API now, we have ES6. jjb On Mon, Aug 4, 2014 at 6:29 AM, Axel Rauschmayer a...@rauschma.de wrote: On Aug 4, 2014, at 15:16 , Juan Ignacio Dopazo jdop...@yahoo-inc.com wrote: In practice we've found that we rarely use the new Loader(hooks)` option and instead this is more common: var loader = new Loader(); var loaderFetch = loader.fetch.bind(loader); loader.fetch = function (loadRecord) { // do something return loaderFetch(loadRecord); }; Why not like this then? You’d need (a compiler for) ES6, though. ```js class MyLoader extends Loader { fetch(loadRecord) { // do something return super(loadRecord); } } let loader = new MyLoader(); ``` -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader vs ES6 Classes
IMO a better design would have each platform subclass Loader, eg SystemLoader extends Loader and System (or 'system' if we decide to suddenly come to our senses) would be an instance of SystemLoader. SystemLoader would define the hook functions and custom Loader classes would extend SystemLoader to add features. Custom loaders probably don't want to re-implement the hooks so much as augment them. The SystemLoader would support this naturally. On Mon, Aug 4, 2014 at 12:52 PM, Guy Bedford guybedf...@gmail.com wrote: I suppose the point is whether System can be subclassed itself, since that is usually the starting point for a new loader as it is common to share the base environment normalization, locate and fetch functions. Currently, if System is set via the options hooks this isn't possible. Note also that things like baseURL and the mapping table being created through the constructor would also make sharing these easier. If System were defined to be based on a class found at System.constructor like this, things get a lot easier for that starting point. On Monday, August 4, 2014, Jason Orendorff jason.orendo...@gmail.com wrote: On Sun, Aug 3, 2014 at 2:31 PM, Kevin Smith zenpars...@gmail.com wrote: I've often wondered why we aren't using inheritance to customize Loaders. I'd be interested in the rationale. When I was working on Loaders, I modified the design so that inheritance works. That is, you can just subclass Loader and declare the methods you want to override, and the Loader will call those methods. It all works, as far as I can tell. I don't remember why we kept the options argument after that. I'm in favor of dropping it. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader vs ES6 Classes
On Mon, Aug 4, 2014 at 1:50 PM, Jason Orendorff jason.orendo...@gmail.com wrote: The design as it stands doesn't specify the system loader or its class. It's a platform-specific detail. Yes, but ES should say a couple of things to get everyone on the same page, eg that the system loader instance will have the interface and semantics of Loader and be available on Reflect.global (or whatever). jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader vs ES6 Classes
The System object is global, so depends is the answer to all such questions. On Mon, Aug 4, 2014 at 2:24 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: Would the System object for a module loaded with a sub classed System be the sub classed one or the original one? IMO a better design would have each platform subclass Loader, eg SystemLoader extends Loader and System (or 'system' if we decide to suddenly come to our senses) would be an instance of SystemLoader. SystemLoader would define the hook functions and custom Loader classes would extend SystemLoader to add features. Custom loaders probably don't want to re-implement the hooks so much as augment them. The SystemLoader would support this naturally. On Mon, Aug 4, 2014 at 12:52 PM, Guy Bedford guybedf...@gmail.com wrote: I suppose the point is whether System can be subclassed itself, since that is usually the starting point for a new loader as it is common to share the base environment normalization, locate and fetch functions. Currently, if System is set via the options hooks this isn't possible. Note also that things like baseURL and the mapping table being created through the constructor would also make sharing these easier. If System were defined to be based on a class found at System.constructor like this, things get a lot easier for that starting point. On Monday, August 4, 2014, Jason Orendorff jason.orendo...@gmail.com wrote: On Sun, Aug 3, 2014 at 2:31 PM, Kevin Smith zenpars...@gmail.com wrote: I've often wondered why we aren't using inheritance to customize Loaders. I'd be interested in the rationale. When I was working on Loaders, I modified the design so that inheritance works. That is, you can just subclass Loader and declare the methods you want to override, and the Loader will call those methods. It all works, as far as I can tell. I don't remember why we kept the options argument after that. I'm in favor of dropping it. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Loader vs ES6 Classes
Since I guess not too many developers work with ES6 and the Loader object, here is some feedback: the Loader callback design does not play well with ES6 classes. The Loader takes 'options', an object with function properties like normalize, locate, and fetch. If you pass a literal object with function properties, it works fine. If you pass an instance of a class, then you discover that the Loader calls these functions with 'this' bound to the Loader, not the 'options' object. There isn't a simple way around this as far as I know. The options functions don't have access to the options object, only module-state and global. So you're stuck with the awkward: var loader = new Loader({ normalize: options.normalize.bind(options), locate: options.locate.bind(locate), etc, }; I guess you can give up on ES6 inheritance and create the hook instances by old-school JS, but that is even more annoying. Or maybe there is something else I've not thought of? jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader locate/fetch/translate/instantiate API
Ok thanks, I see that this was added and I did not notice. (I think this kind of creeping overspecification annoying but inevitable I suppose). jjb On Wed, Jul 30, 2014 at 7:20 AM, Juan Ignacio Dopazo jdop...@yahoo-inc.com wrote: I don't have an answer, but the metadata property of the loadRecord object was designed to be the place where you put your own custom metadata so that it's persisted across hooks. And it works in es6-module-loader: http://jsbin.com/kutey/2/edit?js,output. Juan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader locate/fetch/translate/instantiate API
The spec seems inconsistent about the metadata property. The define() function of Loader accepts options.metadata: --- 26.3.3.2Reflect.Loader.prototype.define ( name, source [ , options ] ) ... 8. Let metadata be GetOption(options, metadata). 9. ReturnIfAbrupt(metadata). 10. If metadata is undefined then let metadata be ObjectCreate(%ObjectPrototype%). --- But the import() function does not: Reflect.Loader.prototype.import ( name [ , options ] ... 4. Let p be the result of calling LoadModule(loaderRecord, name, options). ... 15.2.4.1LoadModule(loader, name, options) Abstract Operation ... 8 Let metadata be ObjectCreate(%ObjectPrototype%). That means I can pass .metadata to define() but not import(). I think the metadata should be passed on both. jjb On Wed, Jul 30, 2014 at 7:20 AM, Juan Ignacio Dopazo jdop...@yahoo-inc.com wrote: I don't have an answer, but the metadata property of the loadRecord object was designed to be the place where you put your own custom metadata so that it's persisted across hooks. And it works in es6-module-loader: http://jsbin.com/kutey/2/edit?js,output. Juan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Loader locate/fetch/translate/instantiate API
The Loader hook callbacks all have an API defined like: Reflect.Loader.prototype.locate ( loadRequest ) My interpretation of this description was that the callback provider should expect the same loadRequest object in to reappear during the load pipeline and furthermore, this being JavaScript, I could add any properties I need to this object as long as they don't collide with the documented properties used by the Loader. es6-module-loader interpreters the spec to mean each loadRequest parameter is bound to a new object with only the documented properties provided. Which interpretation we can count on? Thanks, jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Quantifying Default Exports
On Mon, Jul 21, 2014 at 10:06 AM, Guy Bedford guybedf...@gmail.com wrote: In Brian's case we actually need default exports. This is because the dynamic loader can't pick up the code he has written right now in ES6. This is how he is loading a NodeJS module in ES6: module minimist from 'minimist'; In ES6 this means give me the Module object with getters to the exports. But unfortunately in Traceur this is compiling into: var minimist = require('minimist'); As a result the `module` syntax can possibly return him a 'function' or other non-Module object. You seem to be saying The traceur implementation of 'module' fails in this case. It seems to me that Traceur could generate code which would wrap functions in Module objects. That is, this is not a fundamental limit, just an unreported bug. Thus we have broken the ability to parse his code in the ES6 dynamic loader, as it is not capable of returning a non-Module object for a module import, which is pretty critical. Thus default export properties are critical to enabling this support path. I believe that Caridy's point is: fine, use dynamic linking. On 21 July 2014 09:51, Caridy Patino car...@gmail.com wrote: Interoperability should not be a decisive factor here, we have fallen into that trap before, the conclusion was to let Loader to handle those cases rather than trying to drive it from the perspective of the module syntax. Let's focus on what is best and what makes sense for the ES Modules, and keep the dynamic module systems out of the picture since we know we have a lot of flexibility with the loader to deal with those dynamic modules. /caridy On Mon, Jul 21, 2014 at 12:37 PM, Brian Di Palma off...@gmail.com wrote: Yep, that makes sense. Highly unlikely but still possible and could cause issues. No doubt you could complicate your compiler to deal with these edge cases but why force that? Yet more problems with default imports/exports. This feature doesn't seem worth its cost. On Mon, Jul 21, 2014 at 5:21 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: (woops hit reply instead of reply all) Because the `function mainThing(){}` might already have a method named helper or, more likely, the named export is something like call or bind. On Mon, Jul 21, 2014 at 12:06 PM, Brian Di Palma off...@gmail.com wrote: On Mon, Jul 21, 2014 at 4:16 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: I have a CommonJS module which exports a single function ```js //cj.js module.exports = function (){} ``` If I was to transform it into an ES6 module the best way to do so currently it so use a default export ```js //cj2es6.js export default function () {} ``` now say I want to import those from another commonjs module, importing the first one is easy, but when importing the second one slightly less so, how should the loader treat that default export, a easy solution for this case is to simply have default exports act the same as a module.exports But then what would you do about es6 modules that use default and named exports like the example at http://jsmodules.io/ which can be sumerized as ```js export default function mainThing(){} export function helper (){}; , if we return a default export if it exists then there is no way to access the named exports. As mentioned in the GitHub issue I don't see why you couldn't compile to ` module.export = function mainThing(){}; module.export.helper = function(){}; ` Allowing access to the default and named. So in that case it would make more sense to treat default as just another export name. But if we do that then that means that if we go back to our second example ```js //cj2es6.js export default function () {} ``` if that was to be treated that way then importing it from another commonjs module would be make it be equivalent to ```js //cj2es62cj.js exports.default = function (){} ``` In other words treating default as a regular name prevents you from losslessly converting commonjs in a backwards compatible way. Making named and default exports be mutually exclusive would mean that you could treat default export like module.exports. On Mon, Jul 21, 2014 at 10:45 AM, Brian Di Palma off...@gmail.com wrote: On Mon, Jul 21, 2014 at 3:31 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: that won't help if module.exports is a function That's exactly what `minimist` is, works just fine. https://github.com/substack/minimist/blob/master/index.js Overall the import/exports semantics of es6 and cjs modules would be compatible if mixing named and default exports was prohibited, but the ability to have both is hard to represent in cjs modules. Don't understand this, do you have
Re: Re: Quantifying Default Exports
There are two issues here: 1) Is 'default' essential? 2) Should the spec. explicitly define commonjs loading? Brian is claiming 1) no and 2) no. More important for me: does 2) require 1). Evidently not. jjb On Mon, Jul 21, 2014 at 1:34 PM, Brian Di Palma off...@gmail.com wrote: It doesn't seem an issue that requires the ES6 module spec to have something like default imports though. The compiler could output ` newModule({ default: require('minimist') }) ` and importers could do `import {default as minimist} from 'minimist';` Or you could have ` newModule({ minimist: require('minimist'); }) ` and `import {minimist} from 'minimist';` depending on how the compiler is configured/written. This is implementation detail of compilers and loaders of legacy systems as opposed to spec concerns. On Mon, Jul 21, 2014 at 6:50 PM, Guy Bedford guybedf...@gmail.com wrote: Yes this is a bug that can be fixed at the compiler level. As you say we can generate a wrapper when loading a non-ES6 module in ES6: newModule({ default: require('minimist') }) We then conditionally add this wrapper based on detecting if the import is an ES6 module. This is the same method we have for AMD compilations at the moment, which seems to have been working well. On 21 July 2014 10:17, John Barton johnjbar...@google.com wrote: On Mon, Jul 21, 2014 at 10:06 AM, Guy Bedford guybedf...@gmail.com wrote: In Brian's case we actually need default exports. This is because the dynamic loader can't pick up the code he has written right now in ES6. This is how he is loading a NodeJS module in ES6: module minimist from 'minimist'; In ES6 this means give me the Module object with getters to the exports. But unfortunately in Traceur this is compiling into: var minimist = require('minimist'); As a result the `module` syntax can possibly return him a 'function' or other non-Module object. You seem to be saying The traceur implementation of 'module' fails in this case. It seems to me that Traceur could generate code which would wrap functions in Module objects. That is, this is not a fundamental limit, just an unreported bug. Thus we have broken the ability to parse his code in the ES6 dynamic loader, as it is not capable of returning a non-Module object for a module import, which is pretty critical. Thus default export properties are critical to enabling this support path. I believe that Caridy's point is: fine, use dynamic linking. On 21 July 2014 09:51, Caridy Patino car...@gmail.com wrote: Interoperability should not be a decisive factor here, we have fallen into that trap before, the conclusion was to let Loader to handle those cases rather than trying to drive it from the perspective of the module syntax. Let's focus on what is best and what makes sense for the ES Modules, and keep the dynamic module systems out of the picture since we know we have a lot of flexibility with the loader to deal with those dynamic modules. /caridy On Mon, Jul 21, 2014 at 12:37 PM, Brian Di Palma off...@gmail.com wrote: Yep, that makes sense. Highly unlikely but still possible and could cause issues. No doubt you could complicate your compiler to deal with these edge cases but why force that? Yet more problems with default imports/exports. This feature doesn't seem worth its cost. On Mon, Jul 21, 2014 at 5:21 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: (woops hit reply instead of reply all) Because the `function mainThing(){}` might already have a method named helper or, more likely, the named export is something like call or bind. On Mon, Jul 21, 2014 at 12:06 PM, Brian Di Palma off...@gmail.com wrote: On Mon, Jul 21, 2014 at 4:16 PM, Calvin Metcalf calvin.metc...@gmail.com wrote: I have a CommonJS module which exports a single function ```js //cj.js module.exports = function (){} ``` If I was to transform it into an ES6 module the best way to do so currently it so use a default export ```js //cj2es6.js export default function () {} ``` now say I want to import those from another commonjs module, importing the first one is easy, but when importing the second one slightly less so, how should the loader treat that default export, a easy solution for this case is to simply have default exports act the same as a module.exports But then what would you do about es6 modules that use default and named exports like the example at http://jsmodules.io/ which can be sumerized as ```js export default function mainThing(){} export function helper (){}; , if we return a default export if it exists then there is no way to access the named exports
Re: System as a SystemLoader class
Why not something more like: class RemappingLoader extends Reflect.Loader { constructor(hooks, baseURL, paths) { super(hooks); //... } fetch(load) { // .. } } Reflect.global.System = new RemappingLoader(Reflect.global.System, process.cwd() + '/', {'*': '*.js' }); The main differences here are: 1) This already works, 2) Use std Loader not System.constructor, 3) Don't attach baseURL to loaderConfig, since the loaderConfig is documented in the std. (System is already an instance of Reflect.Loader so I'm unclear on why we need the change you suggest). The biggest hole I see in my example is the use of Reflect.global.System as the value for the loader hooks. What I want to say here is This platform's built in loader hooks, not The loader hooks some random other package wrote onto System. jjb On Mon, Jul 14, 2014 at 10:39 AM, Guy Bedford guybedf...@gmail.com wrote: Currently if I want to subclass the System loader I need to do something like - var newLoader = new Loader(System); newLoader.fetch = function() { // ... } Effectively we're monkey-patching, which isn't pretty. It would be nice to be able to do: class newLoader extends System.constructor { constructor(loaderConfig) { this.baseURL = loaderConfig.baseURL; // ... } fetch: function() { super.fetch } } In order to allow this, we would need to first define a SystemLoader class, and make System an instance of it. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: System as a SystemLoader class
On Mon, Jul 14, 2014 at 11:11 AM, Matthew Robb matthewwr...@gmail.com wrote: Because it seems likely that people will want to use the System Loader but also augment it with their own customizations. Yes, that is what I did below. STILL benefiting from the environment specific implementation details. Yes, we need ways for custom loaders to define which implementation they extend. Some may choose to extend whatever random System was loaded last; the rest of us would like to choose to extend definite testable Loader instance. I suppose we can have LoadMeFirst code and all that but really this is ES6: can't we do better? jjb - Matthew Robb On Mon, Jul 14, 2014 at 1:53 PM, John Barton johnjbar...@google.com wrote: Why not something more like: class RemappingLoader extends Reflect.Loader { constructor(hooks, baseURL, paths) { super(hooks); //... } fetch(load) { // .. } } Reflect.global.System = new RemappingLoader(Reflect.global.System, process.cwd() + '/', {'*': '*.js' }); The main differences here are: 1) This already works, 2) Use std Loader not System.constructor, 3) Don't attach baseURL to loaderConfig, since the loaderConfig is documented in the std. (System is already an instance of Reflect.Loader so I'm unclear on why we need the change you suggest). The biggest hole I see in my example is the use of Reflect.global.System as the value for the loader hooks. What I want to say here is This platform's built in loader hooks, not The loader hooks some random other package wrote onto System. jjb On Mon, Jul 14, 2014 at 10:39 AM, Guy Bedford guybedf...@gmail.com wrote: Currently if I want to subclass the System loader I need to do something like - var newLoader = new Loader(System); newLoader.fetch = function() { // ... } Effectively we're monkey-patching, which isn't pretty. It would be nice to be able to do: class newLoader extends System.constructor { constructor(loaderConfig) { this.baseURL = loaderConfig.baseURL; // ... } fetch: function() { super.fetch } } In order to allow this, we would need to first define a SystemLoader class, and make System an instance of it. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
include
In the module system we issue import {foo} from 'foo'; and the Loader computes an address, say foo.js, fetches the resource and compiles it. If the content of foo.js has no dependencies, it is evaluated, then the importer is evaluated. Yay! Now suppose that foo.js defines a global value. Oh bad sure, but sometimes you have to play cards you are dealt. We still depend upon foo.js, bad or not bad. In the current module system we have to abandon ship. In our importer we need to: // WARNING pre-load foo.js somehow! Now imagine if we could issue include 'foo'; and the Loader computes an address, say foo.js,fetches the resource and compiles it. Since the content has no dependencies, it is evaluated, then the importer is evaluated. Yay! On now back to preloading somehow, jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: include
Sorry, I was imagining a specific scenario without giving the specifics: include 'foo'; // foo is conventional JS, not a module I have written on global in a module, it works ok, but the goal was specifically to mutate global with code written in a module. Here I have given code, designed to be loaded with a script tag or included with require() in node. When I try to use say import foo; I get things like SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function. You could say, oh this is just legacy code, but boy we've burnt a lot of energy on legacy modules maybe a small bit can be invested in legacy scripts. jjb On Mon, Jul 14, 2014 at 6:39 PM, Yehuda Katz wyc...@gmail.com wrote: There is also: import foo; Yehuda Katz (ph) 718.877.1325 On Mon, Jul 14, 2014 at 6:24 PM, Sam Tobin-Hochstadt sa...@cs.indiana.edu wrote: Why not: import {} from 'foo'; or import * as f from 'foo'; This is assuming that there are no other desired exports -- if there are, then the case is even easier. Sam On Mon, Jul 14, 2014 at 8:37 PM, John Barton johnjbar...@google.com wrote: In the module system we issue import {foo} from 'foo'; and the Loader computes an address, say foo.js, fetches the resource and compiles it. If the content of foo.js has no dependencies, it is evaluated, then the importer is evaluated. Yay! Now suppose that foo.js defines a global value. Oh bad sure, but sometimes you have to play cards you are dealt. We still depend upon foo.js, bad or not bad. In the current module system we have to abandon ship. In our importer we need to: // WARNING pre-load foo.js somehow! Now imagine if we could issue include 'foo'; and the Loader computes an address, say foo.js,fetches the resource and compiles it. Since the content has no dependencies, it is evaluated, then the importer is evaluated. Yay! On now back to preloading somehow, jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Asynchronous Module Initialize
On Wed, Jul 9, 2014 at 1:57 PM, Jussi Kalliokoski jussi.kallioko...@gmail.com wrote: ... I proposed (it was less of a proposal though, more an idea or an example to spur better ideas) that we had a single dynamic exportable per each module, and that could be an object, function, undefined for side effects or anything. But, the important part was that it could also be a Promise of what you want to export, allowing asynchronous module initialization. The use cases addressed include: * Optional dependencies (required for porting large amounts of existing code to use ES6 modules). * Async feature detection. * Dependencies on things other than JS, such as stylesheets, images, templates or configuration (e.g. a default language pack). * Waiting on something to be ready, for example something like jQuery could wait for DOM ready so that the API consumer doesn't have to. All of these can be done with the current design, however you cannot defer the module being ready to be imported. So if you depend on these use cases, you have to provide async APIs for things that are possibly synchronous otherwise, not only imposing a performance penalty, but also a convenience downer on the consumers of your API. ... If I understand your question here, I think the current solution as adequate support for these cases. The current module loading solution mixes imperative and declarative specification of the JS execution order. It's a bit of a layer cake: imperative layer trigger declarative layers trigger imperative layers. The top imperative layer (eg System.import()) loads the root of the first dependency tree and parses it, entering a declarative specification layer, the import declarations. These declarations are then processed with Loader callbacks, in effect more imperative code, that can result in parsing and more declarative analysis. By design the declarative layers prevent all of the things you seek. This layer is synchronous, unconditional, wired to JS exclusively. The imperative layers support all of the use cases you outline, though to be sure some of this is more by benign neglect than design. By providing a custom Loader one can configure the module registry to contain optional, feature-detected modules or non-JS code. The Loader can also delay loading modules until some condition is fulfilled. I expect that multiple custom loaders will emerge optimized for different use cases, with their own configuration settings to make the process simpler for devs. Guy Bedford's systemjs already supports bundling for example. This approach concentrates the configuration activity in the code preceding the load of a dependency tree (and hopefully immediately before it). This seems like a better design than say commonjs where any module at any level can manipulate the configuration. The only unfortunate issue in this result is the decision to embed the custom loader in the global environment. This means that a tree of interdependent modules can issue Loader calls expecting a particular Loader to be in System so a custom loader will have to set/unset the global while loading the tree. Maybe we can experiment with modular loaders some time. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Loader.parse ?
In https://people.mozilla.org/~jorendorff/es6-draft.html#sec-instantiatesucceeded-instantiateresult-functions , 15.2.4.5.3 InstantiateSucceeded(instantiateResult) Functions The step number 4 reads: - If instantiateResult is undefined, then Let body be the result of parsing load.[[Source]], interpreted as UTF-16 encoded Unicode text as described in 10.1.1, using Module as the goal symbol. Throw a SyntaxError exception if the parse fails or if any static semantics errors are detected. Set load.[[Body]] to body. Set load.[[Kind]] to declarative. Let depsList be the ModuleRequests of body. While trying to use es6-module-loader, https://github.com/ModuleLoader/es6-module-loader/, as the Loader in Traceur, https://github.com/google/traceur-compiler/, rather than our current TraceurLoader, it became clear that the above step 4 would be architecturally clearer if it were a hook comparable to normalize/locate/fetch... For example: parse(load) - depsList nicely fulfills the requirements of step 4. The loader.js file in https://github.com/ModuleLoader/es6-module-loader/pull/174 shows the consequences in source that follows the spec. Adding `parse` as a Loader hook allows customization of the declarative path of the Loader. This mechanism is a good fit for Traceur, providing evidence that this API would prove useful. Please consider adding a `parse()` hook to the Loader. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: ModuleImport
On Thu, Jul 3, 2014 at 2:31 AM, Jussi Kalliokoski jussi.kallioko...@gmail.com wrote: Tools like Traceur can support it for an easier migration path since they already have diverged from ES.next anyway with all the annotations (for which, off topic, I haven't seen even a proposal here yet) and stuff. Jussi, I would appreciate a bug report on the Traceur github project pointing to information that makes you think this statement is correct. We consider divergence from ES.next to be a bug and do not support any feature outside of the proposal from TC39. Our project does provides great technology that has been used to develop migration tools, annotation experiments, and stuff. All of that comes on other projects or under opt-in flags on traceur. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
This seems like a bit too many issues, so let me just correct one (important) one. On Wed, Jul 2, 2014 at 2:09 PM, Jussi Kalliokoski jussi.kallioko...@gmail.com wrote: On Wed, Jul 2, 2014 at 7:09 PM, John Barton johnjbar...@google.com wrote: Now, I know there are people that think that this isn't not good, but it is. It gives you a lot of power when debugging things or playing around with new things (something I haven't seen discussed re:modules on this list). One of the greatest things in JS is that instead of reading the usually poor documentation, let alone the code, of something you want to use you can just load it up in node or the developer tools and play around with it. With node, you require() something in the repl and you see immediately what it exports. Loader.get() provides the module. Hmm, my bad, I actually thought that Loader.get() works only when the module has already been fetched. Your thought was correct: Loader.get() only works if the module is fetched. It was my impression that you were describing a debugging scenario where the module would be loaded and where you are likely to want to avoid module-loading since your goal is to debug the live image. Well that improves things a lot but that still leaves the disparity between what you'd write in actual code and the repl and thus fails to be better (in this case) than for example CommonJS. I expect devtools to support declarative import in their REPL, so the code you would write is the same. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
Let me try to restate my request for clear information on the advantages of module bindings vs module object architectures. The import syntax already allows pre-execution tools to collect every module that will be accessed by a root dependent module (including some that may not be used). This advantage is clear and it can be weighed against the disadvantages, including more syntax restrictions to learn and the need for a separate dynamic API. On balance I think it's a win, because I understand the advantage. What's not clear is the advantage of module bindings form for modules. When the world of possibilities opens up, what specific things will I see there? On Sun, Jun 29, 2014 at 7:46 PM, Kevin Smith zenpars...@gmail.com wrote: Bruno and John's arguments are classic examples of the straw man fallacy. In my concrete examples I made no reference to static type systems (or any type systems at all, for that matter). I merely pointed out that by allowing the programmer to provide compile-time information in the form of exports and declarative forms, a world of possibilities opens up. Of course, static information can always be *inferred* from dynamic. That's basically how JS engines work, but raising that up to some ideal principle is foolish dogmatism. They accuse me of advocating decades-old technology, but it is purely dynamic JS that is decades old. Evolve or die is the way. The we don't need no stinkin' classes argument is counter-productive, counter-intuitive reactionary garbage, and quite frankly it bores me. : P ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
On Mon, Jun 30, 2014 at 12:00 PM, Kevin Smith zenpars...@gmail.com wrote: What's not clear is the advantage of module bindings form for modules. When the world of possibilities opens up, what specific things will I see there? I think I'm following you now. So let's pose the question like this: Let's posit that there are no default export or import forms, otherwise the current *syntax* is the same. Now, we have two semantic options that we can attach to that syntax: 1. Modules are just regular objects with getters. The import declarations just get properties from those objects at runtime. 2. Modules are a collection of named bindings. Those bindings are resolved at compile-time. Now, since the syntax is the same, our ability to do offline static analysis is the same. So what are the differences between these two semantics? Thanks! This is the kind of information I was hoping for. (All of this has been gone over before, of course...) Perhaps, but clear explanation of complex topics is difficult. Isolating the issues and getting to specifics helps. In that spirit I'll ask for more details. Advantages of 1: - None? Advantages of 2: - Good support for circular dependencies - Mutable bindings As far as I know, this is not something JS developers understand. What is it and what makes it an advantage? - Compile-time optimizations for module.member expressions Is this known to be significant and fundamental? As in there is no way to achieve this optimization with the other format? Seems to me that the compiler introduces the getters and thus can inline them. The advantage of 1 only appears if we allow module object overwriting. Concretely you mean monkey patching module objects in the importing code? Or? Those advantages are: - Auto-renaming the import (questionable) - Smoother interoperability with CommonJS modules. On the other hand, module object overwriting disables our ability to do offline static analysis. So I think the only forceful argument if favor of option 1 (i.e. modules are regular objects with getters) is interoperability, and only if we allow export overwriting. The interoperability question is therefore of central importance. Based on other discussion on this point, it seems like module-as-named-bindings can interoperate with CJS and AMD except perhaps in some unusual cases. Clarifying these cases would help. To me, these two lists are pretty darn small compared with the overall advantages of modules. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
Thanks Kevin. I'm going to challenge your list below, but I hope you don't take it negatively. I want the case for the module system to be as strong as possible. On Sat, Jun 28, 2014 at 11:51 AM, Kevin Smith zenpars...@gmail.com wrote: Static checking of imports and exports has well-known advantages and would help the long-term viability of the language. Enumerating these specific advantages would inform this discussion. These advantages are not well-known. Many developers have experienced the disadvantages of complex systems of rules and thus favor simple solutions over ones with theoretical advantages. Explaining the benefits concretely would help them balance the well-known costs. So pretty much everything in Javascript is dynamic, which is one reason why IDE support for Javascript has always lagged behind. You simply can't know what anything is until you actually run the program. Statically verifiable exports gives us the ability to inspect and analyze code without having to run it. There are two big benefits that this affords us: ## Early Errors and Warnings ## Let's say that you want to deprecate and remove an exported member from a module within a large JS code base. With static imports, the system will generate an error at compile time if something on the other side of that codebase is importing it. It seems to me that the compiler can verify these two statements with equal success: import {foo} from './foo'; var foo = require('./foo.js').foo; I agree that as a practical matter compilers may be more likely to implement checks on the first form simply because it is standard. And I agree that the language-defined module syntax will lead to better quality tools simply because more developers have formal training in compiler technology than have training in dynamic analysis. These are important pragmatic issues. Or am I wrong and these are not equivalent? Or there are examples which show the issue more clearly? For exported function declarations that use default parameters to indicate optional parameters, we can generate build-time warnings when such an function is imported and called with too few arguments. A good argument for default parameters. For exported classes, we have even more static information at our hands. Without having to run the program, we know the number of arguments for the constructor and we know the list of methods for class instances. We can generate warnings when we see an instance using a misspelled method name, for instance. A good argument for standard rather than ad-hoc class class syntax. ## Computer Aided Coding ## The information used above to generate lint-like warnings can also be used to give the developer in-editor feedback. Reliable code-completion for imported function and class declarations becomes possible. Again, for exported classes we can also do code completion for instance methods. These advantages may not seem like a big deal now, but imagine writing JS in a large team five years from now. Do you want the power of static analysis at your team's fingertips, or do you want to be stuck with anything goes so anything can break CommonJS modules? Does that do it? These are arguments for statically computable import module names -- so the compiler can determine the imports without executing source code -- and for top-level or hoisted (static) import statements -- so every import in a module is a dependency of the module without runtime conditionals. I believe that both of these limitations would be acceptable to almost all developers interested in using modules. Unfortunately I think we need more specific and detailed examples to understand the advantages of the static form. Thanks, jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
On Sat, Jun 28, 2014 at 3:58 PM, Kevin Smith zenpars...@gmail.com wrote: Static checking will be limited anyway. If you want to go this way you should use typescript. That's the point that I'm trying to make, shops will choose other languages that provide more static information. We should be thinking about expanding the user base and ensuring that JS is a viable option years down the road. JavaScript's enormous user base is the strongest possible evidence that static analysis provides no advantage to programming language viability. Static analysis may encourage some new users; overall complexity may discourage as many. (I recently started using a typed version of JS; I am not impressed.) Any survey of the top languages in actual use clear demonstrates that the runtime platform and app goals dominate language choice. Even within a platform it is clear static checks are way down the list of valued features. Rather than point towards type-checking, I think we should focus on the actual checks offered by the module design. It seems that these would come with a small cost quite unlike type-checking. CommonJS falls a bit short on the import side because static analysis of require calls is brittle. A special language syntax would enable a robust static analysis of dependencies. If you don't have static exports, then how are you going to know if what you import is valid? You can't, without executing the program. If you don't execute the program, how do you know if the code you are checking is even called? Oh, you do plan to execute the program. Well there you go. (I just think it is so weird that JavaScript's huge advantage of rapid dynamic feedback for developers receives so little attention while so much is lavished on static technologies developed decades ago for a computing environment vastly inferior to our current world.) jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
On Sat, Jun 28, 2014 at 9:03 AM, Kevin Smith zenpars...@gmail.com wrote: Static checking on exported members feels odd. Static checking of imports and exports has well-known advantages and would help the long-term viability of the language. Enumerating these specific advantages would inform this discussion. These advantages are not well-known. Many developers have experienced the disadvantages of complex systems of rules and thus favor simple solutions over ones with theoretical advantages. Explaining the benefits concretely would help them balance the well-known costs. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
+1 On Fri, Jun 27, 2014 at 6:39 AM, Matthew Robb matthewwr...@gmail.com wrote: My opinion is that CommonJS and AMD work today and will continue to work into the future so we should optimize for the ideal looking forward, not backward case when adding to the language. Loader will still be overload-able and since both CommonJS and AMD require a library today it seems completely reasonable that they will continue to do that and can hook into es6 through loader extension. Conclusions: - Drop default exports - export function readFile(){} - import fs from es6-fs; // fs.readfile(); - import { readFile } from es6-fs; // readFile(); - Done. - Matthew Robb On Fri, Jun 27, 2014 at 6:32 AM, Kevin Smith zenpars...@gmail.com wrote: - Either we think real modules are an improvement, and checking is important. Then the model and the syntax should be consistent about that. Moreover, checking needs to consistently apply, no matter how a module and its components are defined or accessed. - Or we come to the conclusion that supporting the legacy singleton export model as a primary use case is a mandatory matter. Then we should drop attempts of building something in/semi-compatible, and limit innovation to making export and import declarative, and designing a loader API. Since real modules are at the core of the current design, I think the first option is feasible and equates to simply dropping the default feature, leaving everything else intact. The second option, on the other hand, will take us back to the drawing board and I don't see how we can do that within the ES6 timeline. We don't want Promises all over again. So, if we cannot settle on option 1, then I think modules must be deferred from ES6. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Default exports, without explicit syntactic support
On Thu, Jun 26, 2014 at 7:39 AM, Axel Rauschmayer a...@rauschma.de wrote: // my-class.js export class MyClass { constructor() { ... } method() { ... } } // use-class.js import { MyClass } from my-class.js; You do have redundancy in `my-class.js` and, as Marius pointed out, the importer has to know both the name of the module and the name of the entity inside the module. Not that big of a deal. But these examples are misleading. my-class.js is not the name of the module. Its is a module identifier, and probably incorrect since the identifier is both absolute and ending in .js. A more realistic example is import {MyClass} from ./pretentious/kernel/core/util/my-class; In the big picture the time to type a few characters in regular pattern is completely overwhelmed by the time it takes to figure out what MyClass does and where it lives. Again, standardizing on `_` for default exports helps, I guess you meant developers may choose to adopt short export identifiers; I don't suppose you are proposing to standardize _. but then importing is more verbose: // my-class.js export class _ { constructor() { ... } method() { ... } } // use-class.js import { _ as MyClass } from my-class.js; -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
// I have a module named `foo`. // I don't care what `foo` is. // Including whether or not its a namespace. // I need make no promises about identifier `foo`. import {bar} from './foo'; On Wed, Jun 25, 2014 at 12:52 PM, C. Scott Ananian ecmascr...@cscott.net wrote: On Wed, Jun 25, 2014 at 2:59 PM, Kevin Smith zenpars...@gmail.com wrote: Correct me if I'm wrong, but the perspective says: why would I need to import the multiple-exports if I'm specifically overriding the exports with a default? Having a way to import both the default and multiple-exports is silly and confusing. For my part, my personal perspective is, I have a module named `foo`. I want to write `foo.bar` to get the export named bar. I don't care *what* `foo` is. Perhaps its a function object for backwards-compatibility. Perhaps it's a module object because of some circular dependency. Perhaps it's a plain object. To me it's just a namespace. Please let me use the same import syntax regardless. In exchange, I promise never to use bare `foo` in my code. There are a couple of different solutions; default-default is one of those. --scott ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loader Hooks
Guy Bedford's es6-module-loader follows the Loader spec closely. I just refactored it to create a function call `parse(load) - deps`: https://github.com/ModuleLoader/es6-module-loader/blob/master/lib/loader.js#L389 This location in the pipeline is pretty much where you suggest. I think I've convinced Guy to let me add it as a hook. Maybe your request will push him over the edge ;-) Note that as far as I can tell, this function call provides a neat interface between the Loader and parser. jjb On Tue, Jun 24, 2014 at 7:17 AM, Calvin Metcalf calvin.metc...@gmail.com wrote: I've been doing work with the loader hooks and one gap that stands out is that there is no hook to let you manipulate the exports and imports of an module without parsing it yourself, in other words if you want to add, remove, or modify exports or imports of a module you have to write your own parsing function because the default instantiate function returns undefined. Ideas: - There is a way of doing what I need to do that I am missing. - Add a post instantiate hook between 15.2.4.5.3 (InstantiateSucceeded) and 15.2.4.6 (ProcessLoadDependencies) - The steps in 15.2.4.5.3.4 could be moved to the default instantiate function so that when overriding it you can still call it to get the parsed module object. --- -Calvin W. Metcalf ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: debugging modules
On Tue, Jun 24, 2014 at 12:53 PM, Guy Bedford guybedf...@gmail.com wrote: If it is a tools problem, it becomes a much more complex problem. Firstly note that the promise isn't rejecting, it is resolving correctly. That is if I have a module X: X.js throw this module throws; Then: System.import('X').then(function(m) { // this returns correctly, with m defined. }); Surely this case must call reject(). What circumstances would call reject() if not the failure to import? So the only information we have is the environment exception that something went wrong executing module X. We have no information of what dependency chain caused this. If we want to inspect the dependency chain, there is nothing to inspect, since we don't even know what loads might have caused it in the first place. So there is no way for a debugger to tell the user anything useful apart from inspecting the entire dependency tree. The evaluation chain that was an explicit set of modules for ensureEvaluated, is no longer available for useful debugging. I don't follow all of this but using your example from es6-module-loaders/test for import('load/main') dependent on 'load/depError' which throws 'dep error', then we should be able to give an error like Module Evaluation Error: 'dep error' in loads/deperror loaded by loads/main https://github.com/google/traceur-compiler/pull/1127 We can give line/col info with a bit of work in Traceur; it would be trivial in a native implementation. If the spec does not allow this, then we need to fix it. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: TC39 vs the community
On Fri, Jun 20, 2014 at 6:42 AM, Domenic Denicola dome...@domenicdenicola.com wrote: Can you develop these particular accusations? Why would TC39 have priorities that don't align with the needs of developers? especially on modules which are clearly one of the most awaited feature as far as developers are concerned? TC39 has a lot of constituents who use their experience with other languages to develop the shape of features, instead of building on community-developed solutions to the problems the community sees as worth solving. In modules this is particularly apparent. If you want a qualifier for community, try ES5-module using community. The ES5-module using community tried, valiantly, to reach a compromise module solution. They were not successful. Thus ES6 cannot build on their solution. Their experience did however have a huge impact on the ES6 module design. I wouldn't call these accusations, and in general I don't appreciate the uncharitable (perhaps even accusatory) tone of your message. Experience from other languages is valuable in evolving a language---of course! It would be silly to think otherwise. And often these working modes are not in conflict at all, allowing us to solve problems the community has run into by drawing upon our experience with other languages. But there is, especially in this case, a real conflict between the guidance from other languages and the guidance from the ES5-module using community's experience. I started out with a similar opinion. Then I wrote some ES6 code. What we need now is experience from using ES6-modules. We have plenty of decent implementations. We've built nodejs and browser applications based on ES6 modules. That experience shows that the ES6 solution is modestly superior to any ES5 solution. Moreover the ES6 solution interoperates with the main ES5 solutions. Are there projects which attempted to use ES6 modules but where unable to succeed because of technical barriers? Whatever they end up looking and behaving, ES6 modules will happen with the community or without it. They may happen, in that engines may indeed implement the syntax once it settles, and browsers may indeed implement a loader once it's designed and specced. But whether they will be adopted by, say, Node.js (by supplying their own loader implementation), or the 80K packages on npm, or by the developers who are currently using AMD, or the developers who are currently just happy with script tags, is another question. Any claims otherwise are tendentious speculation, to borrow a phrase. Implementors and proponents of legacy systems always fight for their point of view. It's natural and valuable input. But at this point we are speculating about tendencies of developers, not arguing about technical feasibility. Some node developers will never switch; some devs will always use script tags; some business apps will be written in COBOL. It's ok. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: TC39 vs the community
On Fri, Jun 20, 2014 at 2:03 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: I am trying to stay outside this discussion as much as I can but there is a specific sentence that I'd like to understand: On Fri, Jun 20, 2014 at 8:39 AM, John Barton johnjbar...@google.com wrote: The ES5-module using community tried, valiantly, to reach a compromise module solution. They were not successful. how 80K modules mentioned by Domenic, the concrete adoption of CommonJS or the usage of Browserify for most of the web, can be defined exactly a failure? Individually both node modules and amd modules are a huge success. I was only referring to the unsuccessful effort at convergence. I am not sure ES6 modules have been overlooked since the beginning but I believe that the rest of the real-world in production out there will keep doing just fine with current inline or AMD based `require(module)` logic. A new ES6 syntax, unfortunately unable to be brought over a UML (Unified Module Loader) as it has done before, will also take much longer to became a de-facto standard as `require` has become these days. Here probably the community sentiment Domenic mentioned, everyone I know somehow applauded fat arrow, nobody I know reacted differently from WTF?!? about ES6 modules. That being said, as complex and powerful APIs can be wrapped and brought to simpler libraries, maybe we actually will keep using `require` but with `import ES6 from module` behind the scene so everyone might win? To the best of my knowledge, nothing in ES6 prevents you from continuing to use `require()`. If you think require() is the perfect module system, then use it. I think the ES6 module system is better and I plan to use it. If we ever stop talking about it and ship it. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
ES6 already has what you want: _Named Exports_: export var foo = 1; _Single Export Object_: export var moduleName = { foo: 1, bar: function() {} }; _Single Export Function_: export function fName() { } And even cooler, the syntax for import is uniform, import {foo} from './namedExport'; import {moduleName} from './singleExportObject'; import {fName} from './singleExportFunction'; On Fri, Jun 20, 2014 at 3:21 PM, Ron Buckton rbuck...@chronicles.org wrote: -Original Message- From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Sébastien Cevey Sent: Friday, June 20, 2014 3:46 AM To: Axel Rauschmayer Cc: es-discuss list Subject: Re: ModuleImport On 20 June 2014 11:39, Axel Rauschmayer a...@rauschma.de wrote: The `*' symbol universally represents a glob of everything, but when used to import from a module that has multiple exports, you won't get everything, you will get either the single default export (if there is one) or nothing. What gives you that impression? Quoting David’s original email: ```js import * as fs from fs; // importing the named exports as an object import Dict from dict; // importing a default export, same as ever ``` With all due respect, why is it that we cannot change the specification to allow `import name from module` for both the default export (for single export modules) and the Module object (for multi-named export modules). The same question goes for using `import { name as name } from module` for both. As specified, a default export is equivalent to a Module object with a default property, and as a result requires special handling with respect to how it is bound to the _ImportBinding_ in `import name from module`. Wouldn't it make sense to simplify the syntax and expand the static and runtime semantics for imports? Are we sure that the current semantics are the right approach that we should shoehorn the syntax into? Is it imperative for module authors to be able to provide both a default export *and* named exports within the same module? From most of the comments in this thread, it seems that expected module use falls into two categories: Single-export modules and Multi-export modules. Is there a use-case in the wild (via ES6 module transpilers) where a single module today uses both a default export as well as named exports? With respect to Node libraries, I often see one of three approaches to exporting from a module: _Named Exports_: ``` exports.foo = 1; // or module.exports.foo = 1; ``` _Single Export Object_: ``` module.exports = { foo: 1, bar: function() {} } ``` _Single Export Function_: ``` module.exports = function() { } ``` In Node, if you wanted to have a default export that is a function, but also have additional exports you would most likely add them as data properties on the function: ``` module.exports = function() {} module.exports.foo = 1; ``` Given that, why not simplify the syntax and semantics to just the following three forms: ``` import module; // imports the module but does not perform binding import name from module; // imports the module (either the default export or a module object with the named exports, see below) import { name1, name2 as otherName } from module; // imports members of the module. ``` Simplifying this requires the following (approximate) changes in semantics: * Either (A) a module cannot have *both* a default export and named exports, _or_.. * (B) A modules named exports become attached properties of the default export if provided. * If (B), it becomes an runtime error to add a default export after a named export, and a runtime error to add a named export if the default export is not an Object. * The ImportBinding (`name` above) becomes bound to a [[Value]] property of an (not part of the current spec) Import exotic object. * When the Module exotic object is loaded, if it has a property named default, that becomes the value of the [[Value]] property of the Import exotic object. * If the Module exotic object does not have a property named default, the Module itself becomes the value of the [[Value]] property of the Import exotic object. * NamedImports now points to bindings to the [[Value]] property of the Import exotic object. If you want both a default export and named exports, attach the named exports as properties of the default export. With the above changes, whether you're using a default export or named exports becomes transparent to the developer. If the developer _really_ wants the module object, they could fall back to: ``` import module; var name = System.get(module); // Returns the Module object without the transformations applied from above. ``` The above is a rough approximation of the semantics changes. If anyone finds merit to this proposal,
Re: ModuleImport
On Fri, Jun 20, 2014 at 4:17 PM, Ron Buckton rbuck...@chronicles.org wrote: From: John Barton [mailto:johnjbar...@google.com] Sent: Friday, June 20, 2014 3:48 PM ES6 already has what you want: _Named Exports_: export var foo = 1; _Single Export Object_: export var moduleName = { foo: 1, bar: function() {} }; _Single Export Function_: export function fName() { } And even cooler, the syntax for import is uniform, import {foo} from './namedExport'; import {moduleName} from './singleExportObject'; import {fName} from './singleExportFunction'; I'm not stating that I specifically want anything here, but was rather recommending an alternative approach to the single export vs named export debate and the removal of the ModuleImport production. Sorry, I did understand that. I was (cryptically) recommending that removing ModuleImport and `export default` until a later date gives us a good-enough solution to the cases you outline. These features can be added at a later very easily and since they would be based on real users asking for more features we could move on them quickly. David's mail was proposing the addition of the following syntax: ``` import * as fs from fs ``` This is designed to work around the fact that without ModuleImport, there's no simple way to get the module object for the named exports. What you really want to write is: ``` import fs from fs; ``` However, the current semantics don't allow this. David proposed the new syntax as a replacement for ModuleImport. My only issue is that for the end user this could be confusing, and its possibly future-hostile for refactoring. So let's just remove it and export default and go. No confusion. We make progress. We study real feedback. We reconsider. If I have a library today that uses an object literal as a default export in Node, and I want to migrate to ES6, the easiest approach is to just replace `module.exports =` with `export default`. Easing migration is a great goal for the next release. We can refine ModuleImport between now and then. My consumers would happy use `import foo from foo`. If I later want to move to named exports, I would break my consumers as they would have to change this to `import * as foo from foo`. The whole reason for this is that there is a semantic distinction with how a default export is handled vs. how named exports are handled. Exactly. So don't allow default export. Presto, problem solved. If I were to use TypeScript's syntax for exports and imports, changing from a default export to named exports results in no change for the consumer: [before.ts] ``` export = { foo: 1, bar() {} } ``` [after.ts] ``` export var foo = 1; export function bar() {} ``` [consumer.ts] ``` import before = require(before); import after = require(after); before.foo; // 1 before.bar; // function bar() {} after.foo // 1 after.bar; // function bar() {} ``` Albeit, TypeScript does not have a Module exotic object, nor does it have mutable bindings, nor an ImportList in its import clause. That said, as far as the consumer is concerned there's no real distinction between the default export approach in before.ts and the named export approach in after.ts. We have this distinction in ES6 because it was designed that way to support mutable bindings and cyclic dependencies. I'm proposing that we come up with alternative semantics that preserve that approach while keeping the import syntax simple. I think both export default/module import and cyclic dependency support are marginal features that cause as many wacky problems as the solve. They just don't matter one way or another. The export default/module-import are easy to add later: removing them now is simple. Changing the semantics means redesigning modules. As a module consumer, I would constantly need to be aware of whether I need to use the `import * as foo from foo` syntax or the `import foo from foo` syntax. Where in Node I would use `require(foo)` for both cases. By changing the semantics of ImportDeclaration in ES6 and using a simpler syntax, we could would save developers the cognitive cost of determining which import syntax to among two very similar forms, as well as supporting the ability for a module author to refactor their module from a default export to named exports for the single-export-as-object case without affecting their consumers. Omitting export default and module-import achieves the same cognitive savings. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
Sorry to be dense, but I would appreciate more elaboration of this sentence: On Thu, Jun 19, 2014 at 3:40 AM, Axel Rauschmayer a...@rauschma.de wrote: This is a key sentence in David’s proposal: “ES6 favors the single/default export style, What is the single/default export style? If I understand this claim, it says that a module will typically contain a single export statement, either named 'default' or not. Is there any evidence to support this? Everything I've seen contradicts this claim, assuming I understand it. and gives the sweetest syntax to importing the default. Importing named exports can and even should be slightly less concise.” Could you please give an example? In my experience, export default is rare or at least divisive since it seems stylistically incompatible with named exports. On Jun 19, 2014, at 12:31 , Michał Gołębiowski m.go...@gmail.com wrote: Thanks, Dave, for bringing that up, it shows you're open for feedback. That said (bikeshed begins), what's wrong with: ```js import fs as fs; ``` ? I feel that a lot of effort went in ES6 into reducing boilerplate via e.g. arrow functions, classes etc. but if you start with Node's require, this adds clutter. Compare these 3 forms of importing all the module lodash bindings to an object _: ```js var _ = require(lodash); // Node import * as _ from lodash; // Dave's syntax import lodash as _; ``` -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
On Thu, Jun 19, 2014 at 10:48 AM, Axel Rauschmayer a...@rauschma.de wrote: On Jun 19, 2014, at 16:17 , John Barton johnjbar...@google.com wrote: Sorry to be dense, but I would appreciate more elaboration of this sentence: On Thu, Jun 19, 2014 at 3:40 AM, Axel Rauschmayer a...@rauschma.de wrote: This is a key sentence in David’s proposal: “ES6 favors the single/default export style, What is the single/default export style? If I understand this claim, it says that a module will typically contain a single export statement, either named 'default' or not. Is there any evidence to support this? Everything I've seen contradicts this claim, assuming I understand it. The syntax is ( https://people.mozilla.org/~jorendorff/es6-draft.html#sec-exports ): export default AssignmentExpression Yes, but I was not clear: where is the evidence that ES6 favors this form or single named export. My experience is opposite: the simple thing in ES6 is to export those things you want exported. If it's one thing, then one; if it's 6 things then 6. One is not favored. and gives the sweetest syntax to importing the default. Importing named exports can and even should be slightly less concise.” Could you please give an example? In my experience, export default is rare or at least divisive since it seems stylistically incompatible with named exports. I’m surprised, too. But that seems to be the feedback from people working with large module-based client-side projects and from the Node.js community: single exports are most common. I still don't get it. If you want one export, just export one thing. If you want one big export object called _, then export var _ = {tons of stuffs} One of the best references for devs to understand modules: http://www.2ality.com/2013/07/es6-modules.html says: The syntax for importing a default export is similar to normal importing, but there are no braces To me this is a bug not a feature; we should keep it simple and just have one way to get one import from one export. Just to make a connection to the topic, Dave's intro says: We've consistently seen confusion between the semantics of ModuleImport and default export. For me this confusion lands on default export equally as 'module` import. I think in client-side projects, one class per module was reported as a frequent use case: ```js // MyClass.js export default class { ... }; // main.js import MyClass from MyClass; ``` -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 modules (sorry...)
I guess there is no technical argument that will convince you. Thanks for at least having the discussion, more than we got before. jjb On Mon, Jun 16, 2014 at 9:02 PM, caridy car...@gmail.com wrote: John, there are a couple of solutions at hand that you can apply: 1. loader provides the right hooks for you to hint at loader what are the modules you need to need to load. which is literally 10 lines of code for an extension of the loader: https://github.com/systemjs/systemjs/blob/master/lib/extension-depCache.js 2. partial bundling, which Guy Bedford explained in details You really don't need bundling for the new modules and the new loader. /caridy On Jun 16, 2014, at 8:19 PM, John Lenz concavel...@gmail.com wrote: You don't really want 300/3000/3 modules where you have to load, parse, then request (dependencies). You really need your dependencies, pre-ordered and pre-loaded (that is bundled) if you want your empty cache clients to get a good experience. SPYD is only one piece of a puzzle it isn't a silver bullet for solving module loading. If you want both to have an ideal experience you want bundles of modules and delta compression of your changes. Unfortunately, there isn't a good delta compression solution yet but I have hopes that SDCH might be made more general and standard. On Mon, Jun 16, 2014 at 4:54 PM, John Barton johnjbar...@google.com wrote: On Mon, Jun 16, 2014 at 4:49 PM, caridy car...@gmail.com wrote: I thought SPDY was, to quote wikipedia, about: reducing web page load latency and improving web security How does SPDY help when the issue is lots of small requests ping ponging back and forth between client and server? SPDY multiplexes the requests across the same connection, which is essentially a runtime bundling process at the browser level without the hazards of doing it manually, and getting the benefit of the granular caching at the browser level. Just so I understand, if the dependency tree a depth of 20 and say 300 modules how many round trips from client to server will you need using SPDY? The competition (ES5 prebuilt) uses one. One roundtrip, one cookie is sent, and 300 entries are added into cache. Imagine making a change in one of those 300 modules, today, with bundling, the ES5 prebuilt entry in cache gets stale, and you now have to loaded the whole thing, while using SPDY, only one entry gets stale, so, next time the user visits the app/page, only that piece will have to be loaded over the wire, the rest is just going to rely on the browser's cache. This is a killer feature, specially if you're doing continues deployment. I agree this does sound great, I just don't see how the browser can know which 300 entries to request until it parses the first entry. If on the other hand you mean the server parses the modules, then it sounds equivalent to bundling. (Do we want to wait for SPDY in every browser before we use ES6 modules?) All major browsers (including safari) support SPDY today. But the point is, we should not consider bundling as a prime use-case for modules, because it is not going to be important at all. If people want to do bundling, they will have plenty of options to do so, even with the current module specs. Could you enumerate these? I thought that there was no option, which is why we are asking. We have been working on transpilers to transform ES6 modules into dynamic modules that can in fact be used today, but also tomorrow, these dynamic modules (which are covered in the specs today under the loader section) can be bundle up. In other words, you can use the same tools that you use today, e.g.: browserify, and they will work just fine. Ok, you must mean TC39 don't have any options, you're on your own. /caridy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 modules (sorry...)
On Sun, Jun 15, 2014 at 8:32 PM, Axel Rauschmayer a...@rauschma.de wrote: I apologize for this email, but I still don’t understand the current module design. ... **Single-export modules.** Still missing is support for single-export modules, which could be added as follows (the keyword `default` instead of the asterisk works just as well, in my opinion). ```js // Module 'MyClass' export* class { }; // Module 'client3' import* MyClass from 'MyClass'; ``` Are these now part of the module design or are you advocating for change? jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss