-
Notifications
You must be signed in to change notification settings - Fork 66
Conversation
cc: @trevnorris @caridy |
|
||
1. Allow a common module syntax for Browser and Server. | ||
2. Allow a common registry for inspection by Browser and Server environments/tools. | ||
* these will most likely be represented by metaproperties like `import.ctx` but spec is not in place fully yet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import.context.*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reworded
847c17f
to
1d9de82
Compare
|
||
```javascript | ||
let foo = 'my-default'; | ||
default export foo; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(minor typo): export default foo;
Using an If so, I really think this should go alongside a package.json property to opt-in a package as an all-ES6 module package. NodeJS already reads the package.json, so simply having a field to indicate that the package is all ES6 modules and to run |
@guybedford my complaint for purely ES6 is we lose common idioms such as :
and the ability to partially port modules. I am also against mucking with
May be ES6, but it is unclear since it lacks import/export. So I need to check It should also be made clear that under the EcmaScript spec exports are read only to observers so core modules will be stay in CJS semantics. |
moved |
@bmeck Are there any alternatives to shifting all the (new) file extensions from |
@ChALkeR there have been several brought up and argued against. It is best to think of things as npm packages and file modules. In particular the issues are:
Proposals discussed at various points:
Some important points brought up around things above:
Some important differences with currently transpiled code and the proposal.
|
I'm a bit concerned about introducing a non-standard extension (well, unless there would some standard that would describe it). For example, someone mentioned Also, this is leading us to a world where everyone would be using a non-standard filetype in all the supported modules, and that filetype would not even have the correct mime, filemanager icon, syntax highlighting, etc. I'm sorry, it looks like this was discussed already, so I'm probably just asking silly questions.
3 and 4 would be needed only for not-so-often cases where there is no |
@ChALkeR we can bikeshed off Thats a lot of complexity to have 4 steps, and complexity is not something I enjoy. Don't know if your module is ES6 or CJS? check these 4 things (in 3-4 different places)? eh.....
|
Re number 4 - you couldn't possibly detect it in every case, because an ES6 module need have no |
@ljharb only if we default to "module", if we default to "script" it is possible, but once again sometimes ambiguous |
I haven't really kept up so much, what is the reason we'd want a different extension...? |
@Fishrock123 different parsing goals, clearly stating which mode you are in. Talked about a "use module" pragma at top, but didn't really see much from that. Different file extensions also allow shipping 2 versions of your files and having node pick up the ES6 over the CJS transpilation boilerplate. |
Wait, are we talking about having ...require transpile to ES6? (also there's not really any use in referring to it as CJS, CJS is dead and it's really just node at this point.) |
@Fishrock123 just talking about the fact if we have an extension for ES6 (like |
@ljharb fair enough. Ruling out anything that needs a parser / runtime just leaves us with filenames, file extensions and package.jsons then, I suppose. Oh, and CLI flags and other out-of-band approaches. |
Yes, that's exactly right. |
@ljharb, I agree that other contexts are important, but I'm still not sure how they are relevant to what node does. I mean that literally, not dismissively. Let's say Node chooses package.json approach plus fallback to double parse. How does that effect what rails does? Couldn't rails still require .mjs if that was the solve there? I don't see how Node's decision literally effects rails. Also, that doesnt leave us with package.json vs. file extension. As I just mentioned, Node could choose to additively fallback to double parse in the situation of executing a script without a package.json to avoid having to use CLI flags. Just because part of the solve doesn't work in non-node contexts doesn't mean it's off the table for node. |
What if we implement all major proposals in a series of fallbacks?
I don't think we'll ever have a single solution that everyone is happy with AND that doesn't break compatibility with existing modules. It sucks that the community will likely fragment into different camps preferring different solutions, but at least Node.js will support them all and will be the compatibility glue between the different camps. Perhaps after a year or so, statistics from NPM will highlight approaches that can be culled? |
How many of the semantic differences of modules are essential to the working of modules, and how many were improvements to the language that were just bundled in with it? Going by the few that are mentioned in UnambiguousJavaScriptGrammar, only the |
@curiousdannii there are several differences not mentioned in that proposal
It should be noted that |
@bmeck Right, so a lot of the changes are an implicit strict mode and extensions to strict mode. ISTM that it's a fundamental problem to introduce changes like that which can't be deterministically identified through parsing. But that's a problem for the ES spec team, not the node team. Sorry if this should be obvious, but is it intended that a module will be able to be run as the main file passed to the node binary? If so, would that mean that the .mjs extension would be required, and we couldn't keep our pretty extensionless bin scripts? If the .mjs is not required, then some kind of deterministic parsing would be needed? |
@curiousdannii as it stands |
Note: the symlink npm makes for "bin" does not need to have the same name, and can drop your extension from the command. |
Could also solve extensionless bin scripts with a separate node binary that is essentially equivalent to |
@martinheidegger Nice work on getting the info up! Really useful stuff. I've been studying this for a while, and I think the "fat-packages" approach is a lot of cost and hazard for little gain. I wrote details of why in the doc at https://github.com/billti/node-es2015/blob/master/fat_packages.md . It seems without fat packages the need for the extra file extension is reduced significantly, and with suggestions from The docs also discuss how CommonJS and ES2015 modules would appear to each other, which is critical how we model modules in code (a subject close to my heart, as I work on the TypeScript team). I'd appreciate any feedback. |
The gain is "ES modules survive". Without fat packages, ES modules are DOA, and the community will simply not adopt them. No requirement is more important than the ability to smoothly migrate to ES modules. |
Which parts of the write-up did you disagree with? On thinking through the implications from a few different angles, I came to the opposite conclusion - that fat packages would hold ES2015 modules back (for the reasons outlined). |
So, assuming an existing package
Is this correct? If so, I don't see how ES modules would be "DOA" – why would the community not adopt the most recent release (where most development is likely to occur)? I know I would. Edit: I don't know if point 2 makes sense or is allowed with regard to versioning. If not, skip to point 3. |
@glen-84 in practice, authors will release v3 and ignore v2. The only thing that will allow for everyone to have a smooth migration is if the same version of the same package works in both. Refer to python 2 vs python 3 if it needs further explanation. |
My team targets the current "active" Node.js LTS (v4), and uses only natively-supported features for that Node.js version. We don't currently use babel or otherwise transpile Node.js modules that we publish to npm. That means we are in the land of short arrows and generators, but are not using destructuring. When Node.js v6 becomes the "active" LTS later this year, that will become our new baseline. Node.js v8 is the earliest possible LTS that would support native ES modules, and it might not land until v10. So it's going to be a long time before my team, with our current customer support policy, move up to native ES modules for Node.js. If our policy holds, we probably won't be transpiling. We do make increasingly broad use of babel for browser / webview code. We'll probably review our Node.js-transpile policy as the productivity gains with newer ECMA standards become too good to ignore, but I figured I'd share this as a one use case data point among many. |
If you are going to add functionality that is specific to an ES2015 format module (i.e. you couldn't transpile down to a CommonJS module with identical behavior), then you would ship a package with the ES2015 module which requires an ES2015 syntax capable runtime (i.e. If you are going to ship a package where every module can be represented as a CommonJS module (and you do so for maximum reach), then if the runtime loads the ES2015 format version of the module or not should be opaque to the consumer (i.e. the behavior should be identical). Hopefully this is a goal. So if a package includes both formats that should behave identically, what advantage does the runtime loading the ES2015 version sometimes, depending on the Node.js capabilities, provide? It seems to me high risk that you have two different source files intended to be the same module, but may have subtle differences hard to catch before deployment. (You are always testing both module formats by running on different Node.js runtimes before shipping now, right? 😉 ). Note even if always loading the CommonJS version, nothing precludes you from including whatever ES2015 source you built it from (if you did) for reference and debugging (via sourcemaps). I provide several other reasons, but that to me seems to be the main risk. Aiming for identical behavior in two different source files that have different syntax/semantics is non-trivial, and when folks get this wrong, code is going to break just by upgrading Node.js. |
@bmeck and @jdalton : I see the https://github.com/bmeck/UnambiguousJavaScriptGrammar write-up is starting to align re format detection of .js files, and now recommends an unambiguous grammar - which is awesome! As critical I believe, but I don't see this covered in depth in this write-up, or the "In defense of..." proposal from @wycats and @dherman, is the semantics of how CommonJS modules appear when imported as ES2015 modules, and vice-versa (i.e.an import of a CommonJS modules, or a require of a ES2015 modules). Getting this right has big implications on how friction-free it will be to co-exist, migrate, and continue to use existing code already authored in ES2015 modules (that is currently being transpiled to CommonJS via Babel, TypeScript, etc.). I cover one proposal in my algorithms doc along with some samples, after working through a number of scenarios with my team. How can I get involved in helping land this? |
I haven't looked at that part in depth, but I was under the impression that those semantics are included in this proposal (this PR and followups) and that In Defense of .js is just proposing an alternative approach to detecting the type (script vs module). It seems to me it'd be out of scope for the UnambiguousJavaScriptGrammar proposal as the ES spec has no awareness of CommonJS. |
imo it would be a big mistake to mention "module detection in node" more than casually in https://github.com/bmeck/UnambiguousJavaScriptGrammar - i think it will distract from the simple nature of that proposal, which is to remove an ambiguity in the language. Thus yes, it is entirely out of scope. |
Thanks @jmm. I did read that section initially, but I guess I'd forget by the time I got through the other 650 comments discussing module detection 😩 @bmeck, due to the size of the discussion on this thread already, and being that it mostly covers detecting module syntax, would you rather discuss the CommonJs <-> ES2015 interop semantics on a separate thread? (e.g. #10 ). |
@billti No problem. I wasn't sure if you hadn't seen that part, or thought it didn't address everything. I've only skimmed it, and since, like you said, most of the discussion here was about detection I assumed the rest was probably more straightforward.
I know the feeling. I know you weren't asking me, but FWIW I think discussing the interop in #10 makes sense, but I don't know why it's closed. |
@billti Thank you for your feedback. I commented on your repository about the use of the phrase "no value". Also after reading the discussion about the Unambiguous JS Grammar I added a (imho quite interesting) information of what could happen if we could get a change of the specification: es6modules-nodejs#17. |
Issue links for subtopics: