-
Notifications
You must be signed in to change notification settings - Fork 97
Support esm in .js #91
base: latest
Are you sure you want to change the base?
Conversation
Expand definition of Collaborator to include individuals with commit access to any Node.js GitHub repository. Clarify the kinds of things that should be considered when considering inviting new collaborators PR-URL: nodejs/node#14981 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Evan Lucas <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Yuta Hiroto <[email protected]> Reviewed-By: James M Snell <[email protected]>
Some errors in buffer module losed some arguments or received wrong arguments when they were created. This PR added these losing arguments and fixed the wrong arguments. PR-URL: nodejs/node#14975 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
PR-URL: nodejs/node#14974 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Yuta Hiroto <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]>
PR-URL: nodejs/node#14971 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Yuta Hiroto <[email protected]> Reviewed-By: David Cai <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: James M Snell <[email protected]>
PR-URL: nodejs/node#14928 Ref: nodejs/node#12376 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
Original commit message: Work around glibc thread-local storage bug glibc before 2.17 has a bug that makes it impossible to execute binaries that have single-byte thread-local variables: % node --version node: error while loading shared libraries: cannot allocate memory in static TLS block Work around that by making the one instance in the V8 code base an int. See: https://sourceware.org/bugzilla/show_bug.cgi?id=14898 See: nodesource/distributions#513 See: nodejs/build#809 Change-Id: Iefd8009100cd93e26cf8dc5dc03f2d622b423385 Reviewed-on: https://chromium-review.googlesource.com/612351 Commit-Queue: Ben Noordhuis <[email protected]> Reviewed-by: Eric Holk <[email protected]> Cr-Commit-Position: refs/heads/master@{#47400} PR-URL: nodejs/node#14913 Ref: nodejs/build#809 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Nikolai Vavilov <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: James M Snell <[email protected]>
Promise is implemented as a pair of objects. `napi_create_promise()` returns both a JavaScript promise and a newly allocated "deferred" in its out-params. The deferred is linked to the promise such that the deferred can be passed to `napi_resolve_deferred()` or `napi_reject_deferred()` to reject/resolve the promise. `napi_is_promise()` can be used to check if a `napi_value` is a native promise - that is, a promise created by the underlying engine, rather than a pure JS implementation of a promise. PR-URL: nodejs/node#14365 Fixes: nodejs/abi-stable-node#242 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Timothy Gu <[email protected]>
It may not return random bytes right away, but when called asynchronously it will not block. PR-URL: nodejs/node#14993 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
PR-URL: nodejs/node#14992 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
Not knowing which APIs use libuv's threadpool can lead to surprising performance problems. Document the APIs, and also document UV_THREADPOOL_SIZE, which can be used to fix problems. PR-URL: nodejs/node#14995 Reviewed-By: Brian White <[email protected]> Reviewed-By: James M Snell <[email protected]>
Preserve indentation for multiline strings, objects that span multiple lines, etc. also make groupIndent non-enumerable Hide the internal `groupIndent` key a bit by making it non-enumerable and non-configurable. PR-URL: nodejs/node#14999 Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Timothy Gu <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Daijiro Wachi <[email protected]> Reviewed-By: Yuta Hiroto <[email protected]>
The returned chunk is *never* longer than `size`. PR-URL: nodejs/node#15014 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
This changes the error handling model of ServerHttp2Stream, ServerHttp2Request and ServerHttp2Response. An 'error' emitted on ServerHttp2Stream will not go to 'uncaughtException' anymore, but to the server 'streamError'. On the stream 'error', ServerHttp2Request will emit 'abort', while ServerHttp2Response would do nothing See: nodejs/node#14963 PR-URL: nodejs/node#14991 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
PR-URL: nodejs/node#14885 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: James M Snell <[email protected]>
The benchmark script for dns contained functions with args declared but never used. This fix removes those arguments from the function signatures. No test existed for the dns benchmark so one was added to the parallel suite. To improve performance the tests are limited to 1 invocation to a single endpoint. PR-URL: nodejs/node#14936 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Refael Ackermann <[email protected]>
PR-URL: nodejs/node#14997 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Timothy Gu <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
This will allow `localAddress` to be properly set before writing debug output. PR-URL: nodejs/node#12616 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
This test now prints out some child error output if the npm child proc fails, allowing us to debug easier. PR-URL: nodejs/node#12490 Refs: nodejs/node#12480 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
This reverts commit 4ca8ff2. That commit was landed without a green CI and is failing on Windows. PR-URL: nodejs/node#15047 Reviewed-By: James M Snell <[email protected]>
Add `SIGTRAP` to allowed signals (seen on PPC machines in CI). Improve message when assertion fails in test-abort-uncaught-exception by providing the signal name that was not expected. PR-URL: nodejs/node#14013 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Yuta Hiroto <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]>
Improve error message by showing output when frames output does not meet expectations. Since we can't tell at runtime if we have the correct libc for backtraces, allow an empty backtrace and run the test on all platforms. PR-URL: nodejs/node#14013 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Yuta Hiroto <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]>
Currently, tests in test/abort do not run in CI. This change configures the test runner to not write core files for abort tests and to run them. PR-URL: nodejs/node#14013 Fixes: nodejs/node#14012 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Yuta Hiroto <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]>
PR-URL: nodejs/node#15003 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Yuta Hiroto <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
PR-URL: nodejs/node#14807 Fixes: nodejs/node#12802 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Roman Reiss <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
PR-URL: nodejs/node#14394 Reviewed-By: Gibson Fahnestock <[email protected]> Reviewed-By: João Reis <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
Add -i option for release.sh that allows users to specify non-default private key for ssh and scp commands. Change argument parsing to getopts. PR-URL: nodejs/node#14401 Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Gibson Fahnestock <[email protected]>
PR-URL: nodejs/node#14659 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
This changes the error handling model of ServerHttp2Stream, ServerHttp2Request and ServerHttp2Response. An 'error' emitted on ServerHttp2Stream will not go to 'uncaughtException' anymore, but to the server 'streamError'. On the stream 'error', ServerHttp2Request will emit 'abort', while ServerHttp2Response would do nothing. It also updates respondWith* to the new error handling. Fixes: nodejs/node#14963 PR-URL: nodejs/node#14991 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
PR-URL: nodejs/node#14716 Refs: nodejs/node#14332 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Yuta Hiroto <[email protected]>
PR-URL: nodejs/node#14204 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
Not sure why you think that'll be the case, it isn't how my implementation works. There is a single |
@tbranyen requires are relative based on the filename in which they're used; that's why each CJS file in node has a different |
@ljharb please read my PR and the hack I employ. It works "fine" for simple cases, |
I'm wondering if |
The import-based alternative for That being said, introducing an official |
If folks are willing to take a slight performance penalty, and the caveats around reading the calling stack to determine relative positioning, we technically already have a solution that works. I'm just a bit worried I went off the deep end and that this could break in ways I'm not forseeing. Effectively this is what I did: At process start:
Inside an ES module:
When invoked:
I think this is a pretty acceptable overhead given the fact it's a temporary hold over until more code becomes ESM. |
I suspect there's going to be a lot of code that never makes that transition. People aren't going to rewrite their code unless they have a really solid reason to. |
I have not worked on the |
Sorry @bmeck, I only meant that the facade work allows for the syntax I've suggested, without your work this would not function. |
I don't entirely understand what this PR proposes to do. Would you mind going through of these scenarios and explaining what happens in each one? (There ended up being more than I expected, sorry.) Throughout, please assume Suppose
What happens when you do Suppose
What happens when you do Suppose
What happens when you do Suppose
What happens when you do Suppose
What happens when you do Suppose
What happens when you do Suppose
What happens when you do Suppose
What happens when you do Suppose
What happens when you do Suppose
What happens when you do |
As a developer, I'd like to answer with my expectations about his PR. Since we've slightly discussed this already and we seem to be on the same page, I hope this answers for @tbranyen too. I am assuming all questions are about local files in the same project, not npm published modules, and with an implicit Point 1
Project published in npm after transpilation are 100% CommonJS and Being non existent issue, it's straight forward to solve:
The same goes for pretty much every other case. If you use standrd ES2015 module features you are running ESM, otherwise you are running CJS wannabe code that need transpilation. This is already covered by runtime/post-production tools such Babel so ... Point 2
throws in the Point 3
There's probably a typo there, it should be It will also have Point 4It has probably the same Why? Because it's loaded as ESM. It does nothing to break standard ES so it just works as such. Point 5Again, it's very simple: you load as ESM, the file is imported as ESM. You load as CJS, the file is imported as CJS. This is the exact same of having the file duplicated as both The result? Point 6Same as above. Result is Point 7There's no Point 8Another non-existent use case. You are loading same project files, you are shooting your foot if you have both CJS and ESM source code. Nobody does that already today. Regardless, the result should be Arguably the CJS require for a module already loaded, hence valid, as ESM, should simply throw. Point 9
You shouldn't import the exact same file twice, once in CJS and once in ESM world, because the whole point of this issue is that these two environments are not equivalent/compatible. Thanks gosh this won't even happen on the real world. Point 10There is no |
@WebReflection |
@bmeck so is I thought the point here is to clearly differentiate as explicit flag intent between CJS and ESM, and I've answered to that. In CJS modules nobody needs or uses Accordingly, keep NodeJS should fade away from CJS, not work around its limitations, and in doing so, the Developers behind tooling won't need to do anything until they decide to embrace standards, developers that want to adopt ESM and still use legacy CJS via npm, where modules are already published as CJS, can finally do that without compromising the language with two unnecessary extensions: the "it's maybe ES compatible" and "it's totally ES compatible" one. This PR is the best migration pattern out there, it should land in core ASAP behind flags, IMO. |
@WebReflection the fact remains that
This pull request continues to use
async () => {
const global = this;
global.foo = 123;
import('thing-using-foo');
} Has 3 different evaluation results between Script, Module, and CJS. I suspect there will be increased situations where source code becomes ambiguous over time when reading other peoples files. In the case of the file above it would be necessary to state how to consume the file as it may not be obvious. This problem already exists with Continuing the pattern of deferring to how modules are consumed prevents authors form being able to reliably trust that their even module works. This means they will need to do feature detection at runtime if they wish to be consumed in multiple ways and avoid any syntax that is invalid between goals. I do think you have an approach that is able to be implemented, but I do not agree with your conclusions about it being the right approach due to a variety of concerns between teaching, migration planning, and increased need for context when reading files. |
good, I'm OK with that, 'cause I've never used/needed Please find me a published NodeJS npm module that uses it.
Assuming CJS uses the mechanism provided by CJS to load CJS and not If you find an ambiguous solution please expose it to me. I am saying: Keep it this way and you can answer, like I've done, to all those questions. What is the purpose of using If that's really needed you
No. It has exactly what the flag you used expect. You I'm fine with
I suspect that's the case indeed with Keeping With
This proposal solves that issue: SpiderMonkey has the same via JSC is so ahead of time it just goes standard and ESM imports as goal by default.
That's the current status with
Zero ambiguity is my goal. Fade away CJS, embrace ES2015+. It's already possible, we just need to punish those that never cared 'cause tools solved for them. The day they'll start caring about the standard is the day they'll refactor few requires here and there, not a big deal, maybe they'll learn the story.
nothing to teach, the migration plan is highlighted by your editor without needing to read the file extension so it's a win for reading files too. Today? Everyone believes they are using standards and Babel fixes everything, that's it. And that is IMO what we should fix in the JS community. |
I can't because no environment supports it. Babel and Webpack based compilation do not implement it as spec so they also don't support it. However, people are using it in modules today. This discussions are about impact on existing modules and future planning, stating that something is not present in the ecosystem today is not relevant. The purpose in developing specifications is to plan how they will be used in the future. That directly has a relation to backwards compatibility though.
This is an attempt to state that mine is ambiguous compared to yours. We have different forms of ambiguity here. On the side of I am not sure stance you are trying to produce from these statements, but there certainly is ambiguity in both.
To load modules using ECMA262 provided mechanics and produce a Module Namespace, there may be multiple types of modules that it can load.
This has different mechanics and would not be going through the same pipeline as
This is false and based upon unknown environment context. My example does not include a CLI flag, as the author of that text you do not know.
I am not clear here on what is being discussed, but the default is ESM in the current
This is the point of the usage restriction in the internet draft.
I can actively point them to the internet draft as being out of line.
Correct to an extent. Like all new things, you need to upgrade your environments for support of features. We still haven't fully specced out how the web intends to handle path aliasing or bare imports. I am in no rush to make statements about their plans, but am curious how things will work out.
I seem to disagree since ambiguity is present always in
I don't understand this. It is claiming that the standard is not cared about today?
The migration plan keeps |
of course, because Webpack split modules for browsers if you use import. So it's not NodeJS code that is involved, it's browser-land that will still use Webpack to split up bundles. The Web will keep using bundlers, at least in production, with or without
it is.
They have everything they need to avoid issues. They have samever based packages, tooling to help them use the right loader for the right package. They need to know regardless what they are importing because CJS exported after ESM break in ESM once imported transpiled. Can we plese starrt checking what exhaustively already discussed? Because of automatic extension insertion, NodeJS is making imports ambiguous. Authors need to know what they are importing because they might need to explicitly opt in for We've talked about this already.
Excellent, then go full ES2015 if that's your intent.
Perfect, then don't. If I If I use that, the only hook I need would be CJS one, 'cause the module is a CJS one. You need to think inside-out. The intent is explicit in the source code. That's literally it. If the goal is not satisfied, it fails.
Precisely. The NodeJS environment standard has been Use
The If I double click on a file my OS tries to find the best program, or the instrumented program, to open such file. If I right click and open with another program though, that just happens: it's my explicit intent. If I decide to register
You don't have to. Every JavaScript valid MIME served file will do. That's
No. Who uses NodeJS shouldn't act like a tool. It should just work in a never ambiguous way. No exceptions beside those that make sense like Remove CJS goal from anything defined in ES2015+ and you have solved all the ambiguities. Let tools do their job. Let developers that setup those tools migrate with the pace they want.
to keep
Which part is not clear? CJS // I WANT CJS
require('./file'); ESM // I WANT ES2015
import app from './my-app.js'; What is not clear, if you remove CJS goals from any ES2015 explicit intent? Drop CJS goal from any The only missing bit is the following: // I WANT ES2015
import app from './my-app.js';
// BUT I ALSO NEED CJS
import {require} from 'module';
require('./file'); |
Hey, thanks for keeping this heated discussion civil. Just a comment on |
@benjamingr with this PR, and a v8 that supports it, A commonly repeated MJS argument is that it is simply a file extension and that the community will catch up to it, with tooling and modules. That is true, but there is more to the implementation in that it allows for importing CJS with ESM semantics. You will then hear about how |
This encouragement to continue using non-standard syntax when writing new code is part of why I do not think it is a good idea.
These module types are all looking to use MIME/file extension. This statement is misleading about there needing to be different concessions for what loading other file types means. "work with ESM first-class" in particular is misleading because every module type is just needing to define what to create a Module Namespace Object means when loading that module type. Defining a well known procedure for CJS is no different than anything listed here. |
@benjamingr the Although, with
This is why we should put a line for developers: import is for ES2015, require is for CJS. In this way they'll migrate, in any other way they'll continue doing whatever they are doing: omitting the extension because
OK then, tell me what's the difference between
The only module type allowed in ES2015+ is the one defined by ECMAScript. Get CJS out of the equation or you'll inevitably bury all your good intents way before it'll ever disappear as module type for Node. Go full ESM when required and see the migration happening. Neither me nor you have crystal balls, and yet all the polls I've seen, all the voting on GitHub, and all the people I've talked to, would prefer keeping |
The difference is a few things:
1. Browsers dont care about file names so .mjs and .js are equivalent in
their mechanics.
2. The `goal` parameter of `text/javascript` is defaulted to module when
loading via a Module.
3. Scripts in browsers have no mandated MIME so with `<script
type=text/javascript>` no MIME is comin from the attribute and it is
defaulted to `text/javascript` with `goal` being defaulted to script.
Serving Script with MIME like `text/html` is perfectly valid.
I say defaulted above not that it gets added to the MIME but the behavior
is that of using the goal parameter.
…On Oct 15, 2017 4:26 PM, "Andrea Giammarchi" ***@***.***> wrote:
@benjamingr <https://github.com/benjamingr> the import(...) is an ES2015
standard. It works well already on the web, it imports ES2015 modules, and
here we all agree it should continue doing so.
Although import(...) should never be compatible with CJS, because
otherwise we are doing exactly what we are trying to prevent:
This encouragement to continue using non-standard syntax when writing new
code
This is why we should put a line for developers: *import* is for ES2015,
*require* is for CJS.
In this way they'll migrate, in any other way they'll continue doing
whatever they are doing: *omitting the extension* because .mjs is
encouraging this.
These module types are all looking to use MIME/file extension.
OK then, tell me what's the difference between text/javascript for .mjs
and text/javascript for .js ... 'cause I'm sure my browser doesn't remove
any ambiguity from these two extensions.
"work with ESM first-class" in particular is misleading because every
module type is just needing to define what to create a Module Namespace
Object means when loading that module type.
The only module type allowed in ES2015+ is the one defined by ECMAScript.
Get CJS out of the equation or you'll inevitably bury all your good
intents way before it'll ever disappear as module type for Node.
Go full ESM when required and see the migration happening.
Neither me nor you have crystal balls, and yet all the polls I've seen,
all the voting on GitHub, and all the people I've talked to, would prefer
keeping .js and explicitly opt in for ESM.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#91 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAOUo6xHhlp5jPhRcdfe3t3siK4mhGFHks5ssnhngaJpZM4PqF03>
.
|
same goes for SpiderMonkey and JSC
same should happen when the engine is asked to
But
If the intent is clear, it should be OK for any engine to load whatever file name as module too. Being in JS the JS itself the only reasonable default target, if that file won't result into a valid JS code with goal module then it will fail as expected. File extensions are, and always will be, a convention, nothing else. Having one programming language under one file extension is what every other programming language has so please, let's not make JS a joke, it's been derided already for a way too long time. |
The language has two parse goals. Extensions determine parse goal for textual formats. The only way JS could retain one extension is if instead of two goals, it was two modes in one goal - i.e., unambiguous parsing. Browser reps on TC39 blocked that change (and presumably would have blocked it pre-ES6 too, for the same reasons which aren't relevant here), thus, two file extensions have always been inevitable. (It's also worth noting that had python 3 had a different file extension than python 2, a "python 3 situation" might not have entered the lexicon) |
As already discussed in this PR, that's done here. You
As already discussed in this PR, that's not the case via
Python 3 migration problems has nothing to do with file extensions, it's about syntax. Here we are promoting exact same syntax for both Python 3 syntax breaks on Python 2 (and vice-versa) Nobody is proposing new syntax here so ... a new extension using Python as previous case, makes even less sense. |
Modules do have different syntax than Scripts, as well as different semantics. An important requirement is that the developer not have to know the module format of the module being imported or required. Forcing one mechanism based off the module format violates this constraint. |
absolutely no. A module can be a polyfill with side effects on the global scope. CJS and ESM don't need to export a thing and use same syntax.
who decided the requirement? if Node users, apparently most of them are not happy with the current status.
that's impractical in the real-world and, accordingly, a made-up problem that doesn't exist. You need to know if you are importing an ESM module or a CJS one or a transpiled one, because you eventually need to address the Node adding extension implicitly when omitted is the source of ambiguity. This also has been discussed numerous times already.
Since I don't think anyone here wants me to repeat all the answers, to avoid repeating everything discussed already please read the conversation from the beginning. Thank you |
This PR is one piece of npm’s proposal to add ESM support in Node. All I can say is if npm supports this then we must be onto something here 😉 npm’s Node branch with this change (among others): https://github.com/chrisdickinson/node-1/tree/you-cant-spell-ex-mea-sententia-without-e-s-m |
For your consideration:
This modifies an early ESM implementation bmeck/node@e47459c to not exclude
.js
files from ESM. This maintains complete backwards-compatibility with.mjs
. It is created as a demonstration that.mjs
should not be a hard requirement to use ESM, as it introduces needless friction to the existing environment.I introduce two command line flags:
--esm
- Parse the initial script as ESM--cjs
- Parse the initial script as CJS (default)Use of the
--esm
flag will parse the script as ESM supportingimport
and allowing the user to import CJS files within the limitations of Node's implementation. Currently all of core is available for named imports. Users can require CJS scripts by importing therequire
function from themodule
core module.Notes on Relative CJS from ESM:
Supports relative
require
calls when called from an ES Module. This was temporarily implemented using a hack where the require fn is called, then the parent caller is matched from the resulting error call stack, then a new require path is formed from the normalized. This is working with simple examples, but is obviously not a long-term solution. The fix is usingimport.meta
to get a caller path and matching relative to that.Limitations:
.mjs
will allow arbitrary execution ofnode script.js
, thisapproach requires the end user to specify what to start with, which can
be problematic for CLIs, although they can use
.mjs
in this case tomake the distinction.
Benefits:
import
for ESM/or core,require
for CJS.mjs
require
for CJS in ESM, opposed to always usingimport
despite its numerous limitations with CJS compatibility
.mjs
, and still allows the benefits of.mjs
without making it a hard requirement
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
require
function in ESM)