Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upnew ESM implementation #26745
Conversation
This comment has been minimized.
This comment has been minimized.
nodejs-github-bot
added
the
lib / src
label
Mar 18, 2019
This comment has been minimized.
This comment has been minimized.
MylesBorins
requested review from
guybedford
and
bmeck
Mar 18, 2019
BridgeAR
reviewed
Mar 18, 2019
| return `Cannot use ${typeString} because nearest parent package.json ` + | ||
| ((typeFlag === 'module') ? | ||
| 'includes "type": "commonjs"' : 'includes "type": "module",') + | ||
| ` which controls the type to use for ${filename}`; |
This comment has been minimized.
This comment has been minimized.
BridgeAR
Mar 18, 2019
Member
This seems to miss an else case in case conflicts is neither 'extension' nor 'scope'.
MylesBorins
requested review from
mcollina
,
devsnek
,
Fishrock123
,
jdalton
and
targos
Mar 18, 2019
targos
added
the
semver-minor
label
Mar 18, 2019
devsnek
requested changes
Mar 18, 2019
|
I don't think the |
This comment has been minimized.
This comment has been minimized.
|
I was trying to build this locally on my mac machine to play around, but got back the following error:
BTW, I'm on mac os sierra 10.12.6. |
This comment has been minimized.
This comment has been minimized.
|
@antsmartian have you built node since the last V8 update? I had the same error as well and had to |
This comment has been minimized.
This comment has been minimized.
kristoferjoseph
commented
Mar 18, 2019
|
This PR doesn't mention |
guybedford
approved these changes
Mar 18, 2019
This comment has been minimized.
This comment has been minimized.
|
@kristoferjoseph .mjs is unchanged. In the |
devsnek
added
module
experimental
ES Modules
labels
Mar 18, 2019
This comment has been minimized.
This comment has been minimized.
|
@devsnek I've removed |
richardlau
reviewed
Mar 18, 2019
doc/api/esm.md Outdated
devsnek
approved these changes
Mar 18, 2019
devsnek
requested a review
from
vsemozhetbyt
Mar 18, 2019
targos
reviewed
Mar 18, 2019
doc/api/cli.md Outdated
doc/api/cli.md Outdated
doc/api/esm.md Outdated
lib/internal/errors.js Outdated
jasnell
reviewed
Mar 18, 2019
doc/api/cli.md Outdated
jasnell
reviewed
Mar 18, 2019
doc/api/esm.md Outdated
jasnell
reviewed
Mar 18, 2019
doc/api/esm.md Outdated
MylesBorins
force-pushed the
MylesBorins:modules-lkgr
branch
from
a21e48c
to
682f125
Mar 18, 2019
This comment has been minimized.
This comment has been minimized.
|
FWIW I think
I'd honestly go either |
guybedford
and others
added some commits
Aug 28, 2018
MylesBorins
force-pushed the
MylesBorins:modules-lkgr
branch
from
173c8a3
to
f180ddc
Mar 18, 2019
hiroppy
reviewed
Mar 18, 2019
| added: REPLACEME | ||
| --> | ||
|
|
||
| To be used in conjunction with `--experimental modules`. Sets the resolution |
This comment has been minimized.
This comment has been minimized.
bcoe
approved these changes
Mar 19, 2019
|
Just a first pass reading through everything, but so far it's looking great to me. Good work Myles! |
| else if (conflict === 'scope') | ||
| return `Cannot use ${typeString} because nearest parent package.json ` + | ||
| ((typeFlag === 'module') ? | ||
| 'includes "type": "commonjs"' : 'includes "type": "module",') + |
This comment has been minimized.
This comment has been minimized.
bcoe
Mar 19, 2019
Member
If there's no index.mjs, and type is module will it treat index.js as the entry-point, or would I need to set main: 'index.js?
| SyntaxError: Unexpected reserved word | ||
| at internal/modules/esm/translators.js:*:* | ||
| at Loader.<anonymous> (internal/modules/esm/translators.js:*:*) |
This comment has been minimized.
This comment has been minimized.
bcoe
Mar 19, 2019
Member
nit: is it worth making the loader method a named function, just to make this exception a bit clearer?
|
|
||
| const entry = fixtures.path('/es-modules/noext-esm'); | ||
|
|
||
| const child = spawn(process.execPath, [ |
This comment has been minimized.
This comment has been minimized.
bcoe
Mar 19, 2019
Member
I might add a comment describing the purpose of this test (it's relatively clear from the filename, but might still be nice; I like the approach I've seen in a few sections of the codebase of:
// description of test
{
// test content, in closure to keep it contained.
}
| @@ -301,6 +333,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { | |||
| "show stack traces on process warnings", | |||
| &EnvironmentOptions::trace_warnings, | |||
| kAllowedInEnvironment); | |||
| AddOption("--entry-type", | |||
| "top-level module type name", | |||
This comment has been minimized.
This comment has been minimized.
bcoe
Mar 19, 2019
Member
nit: I find this description slightly confusing ... maybe:
default module syntax supported by application entry-point ... a little bit verbose, but maybe something like this?
| @@ -29,11 +24,6 @@ enum HostDefinedOptions : int { | |||
| kLength = 10, | |||
| }; | |||
|
|
|||
| v8::Maybe<url::URL> Resolve(Environment* env, | |||
This comment has been minimized.
This comment has been minimized.
| process.exit(1); | ||
| }); | ||
| // Handle any nextTicks added in the first tick of the program. | ||
| process._tickCallback(); |
This comment has been minimized.
This comment has been minimized.
bcoe
Mar 19, 2019
Member
this feels a little fragile, do we have a unit test around this specific behavior (I think it would be worthwhile because someone will eventually try removing this function).
| @@ -101,8 +101,7 @@ class ModuleJob { | |||
|
|
|||
| async run() { | |||
| const module = await this.instantiate(); | |||
| module.evaluate(-1, false); | |||
| return module; | |||
| return { module, result: module.evaluate(-1, false) }; | |||
This comment has been minimized.
This comment has been minimized.
bcoe
Mar 19, 2019
Member
it might be worth documenting what -1 and false` indicate, it's a little magical ... I believe it's?
module.evaluate(timeout, breakOnSigint)?
This comment has been minimized.
This comment has been minimized.
|
not to paint a shed, but I don't love |
This comment has been minimized.
This comment has been minimized.
|
After thoughts: However, the way current dual modules are published is through the Accordingly, to provide the least possible migration friction, how about the flag is kept as In this way:
If this is not OK, I wonder how current dual modules could be published / migrate. edit following a couple of packages example (with comments) the one with entry {
// the current/common dual module strategy
"main": "cjs/index.js",
"module": "esm/index.js",
// the present + the future
"type": "module",
"entry": "esm/index.js"
}Alternative to entry, one with type => field {
// preserved as is for backward compat
"main": "cjs/index.js",
// the type fields, also compatible with current ecosystem
"module": "esm/index.js",
// if omitted, fallback to "main"
"commonjs": "cjs/index.js",
// the type field, either module or commonjs
"type": "module" // or "commonjs"
} |
This comment has been minimized.
This comment has been minimized.
|
@WebReflection let’s discuss in nodejs/modules#296 |
This comment has been minimized.
This comment has been minimized.
michael-ciniawsky
commented
Mar 19, 2019
node -m|--module file.js // === node file.mjs
node file.js // === node file.cjs (default)The concept of 'package scopes' is generally questionable compared to an explicit way of being able to deteremine the module type of a particular file e.g |
This comment has been minimized.
This comment has been minimized.
It's taking a very generic name, so it's going to be confusing when we add other flags that contain the word |
This comment has been minimized.
This comment has been minimized.
|
@joyeecheung we should be a bit more pragmatic here, 'cause there are also perfectly valid cases such as:
Decontextualized, all of the above flags could be considered ambiguous, but these are actually simply the most commonly used one, and indeed they all have their counter shortcut. Accordingly, since
Prefixes are also very good to explicit meanings in general, so I don't see why |
This comment has been minimized.
This comment has been minimized.
michael-ciniawsky
commented
Mar 19, 2019
•
While I generally understand and not disagree, this actually doesn't seem to be an strictly 'enforced' naming convention atm either e.g main --config ... # instead of main --main-config
main --component-config ...Following the node --module-type="module" file.js
node --module-type="commonjs" file.jswhich is perfectly fine (explicit, extensible). But since the (implicit) default node file.js === node --module-type="commonjs" file.js`already exists and to improve usability, it maybe justifiable to add a shorthand node -m|--module file.js === node --module-type="module" file.jsfor the common ESM usecase aswell ¯_(ツ)_/¯ |
This comment has been minimized.
This comment has been minimized.
Is the flag expected to be used frequently in the presence of the type field in package.json? What's the expected percentage of users who are going to use this?
But it's not |
This comment has been minimized.
This comment has been minimized.
|
--loader is probably going to be renamed or removed anyway. I guess you can argue that --check should be --check-entry but overall, why would you use "we named things poorly in the past" as an argument? let's do better in the present, right? |
This comment has been minimized.
This comment has been minimized.
|
Most of the single-worded flags are pretty old, except for Note that we just added
to our CLI options (they are also still experimental). I'd like to see that we have some consistency around brevity of these flags before they go out of experiments at which point they are going to stay with us. (although in general, we have more verbose flags than succinct ones) |
This comment has been minimized.
This comment has been minimized.
michael-ciniawsky
commented
Mar 19, 2019
No, it checks a 'script' without executing it. 'script' strictly doesn't need to be an entrypoint or the like... This is a good example where pseudo explicitness may make things actually harder to understand in the end... |
This comment has been minimized.
This comment has been minimized.
I guess everyone that used Various, including me, already said that
the
The node is the script executor, and I've said "we should be a bit more pragmatic here" not by accident, I literally meant it. If you think people can get confused about HTML |
This comment has been minimized.
This comment has been minimized.
|
Hey y'all can we please move the discussion about flag names and behavior to nodejs/modules#296 in order to keep the comments in the PR focused on actionable changes? Thanks |
MylesBorins commentedMar 18, 2019
This PR updates the current
--experimental-modulesimplementation based on the work of the modules team and reflects Phase 2 of our new modules plan.A longer form description of these changes can be found in our draft blog post.
The largest differences from the current implementation include
packge.typewhich can be eithermoduleorcommonjstype: "commonjs":.jsis parsed as commonjstype: "module":.jsis parsed as esm--type=[mode]to let you set the type on entry point. Will overridepackage.typefor entry point..cjs.modulemode.--es-module-specifier-resolution=[type]explicit(default) andnode--es-module-specifier-resolution=nodeto enable the commonjs specifier resolution algorithm--experimental-json-loader"type": "module"import 'thing.json'will go through the experimental loader independent of modepackage.mainto set an entry point for a moduletypeof the module