Repository navigation
doc: ES module dummy loader resolve hook bug on Windows #29610
Description
Activity
cc @nodejs/modules-active-members
This looks like a bug with resolving argv[1] during bootstrapping.
Edit: https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js#L1005 looks suspect
@DerekNonGeneric do you have your code for
custom-loader.mjs, Are you usingurl.fileURLToPath()?DerekNonGeneric commented
on Sep 25, 2019 ContributorAuthorMore actionsThanks for looking into this @bmeck. I am indeed using
url.fileURLToPath(). My code forcustom-loader.mjshas changed significantly since I opened this issue, but I've tried to bring it back down to a comprehensible reduction to help out anyone looking into this. Apologies in advance for changing the formatting (different style guide).https://gist.github.com/DerekNonGeneric/bdf314493c3262c93ceab6fda1c7695b
Changing https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js#L1005 to use
.hrefover.pathnameseems like it would fix the issue here to me. Thanks for finding this bug @DerekNonGeneric.Reacted by Derek LewisA few documentation-related errors I see:
-
The error stated is incorrect.
imports must begin with '/', './', or '../'; '${specifier}' does notAccording to the Node.js documentation specifiers may not begin with
/. -
URLdoes not need to be imported, since it is already in scope. -
The JSDoc comment at the top should be of type
{string=}as it is optional parameter, yet it reads:* @param {string} parentModuleURL -
The command given to execute this code is not cross-platform. Environment variables cannot be passed to commands like this in PowerShell.
NODE_OPTIONS='--experimental-modules --loader ./custom-loader.mjs' node x.jsit should instead read:
node --experimental-modules --loader ./custom-loader.mjs x.js
or possibly
node --experimental-modules --experimental-loader ./custom-loader.mjs x.js
/to @bmeck, @guybedford Do y'all mind if I make a PR to fix these?
-
I'd avoid the JSDoc change, there is some disagreement and I lean towards TS syntax which does not enforce non-undefined value:
/** * @param {string} x */ function foo(x) { return x; } foo(undefined);
TS syntax which does not enforce non-undefined value
Not sure how relevant that is here but with
strict: true(or just strict null checks), TS does mark your sample as an error. I think it's reasonable to be explicit about optional and/or nullable parameters in the API.Reacted by Derek LewisFYI, that does enforce non-undefined if
strict(or at leaststrictNullChecks) is on. (And it should be on.) It should bestring=if it's optional, which the TS checker'll also recognize.Reacted by Derek LewisI'm not really cozy on relying on non-default configuration to determine that.
It doesn't break in the default configuration to use
string=. And, as Wes said,strictNullCheckisn't an obscure setting but pretty close to an accepted best practice. Your sample relies on the fact that TS actively ignores (some) null errors in the default configuration to make transitions easier (I assume).even if we have a recommendation, we should not do something if it not the default. E.g. don't share strict mode code if the default is non-strict unless you express that it should be strict. We could argue about this a bit but overall it isn't as important, I'd be fine with
string | undefinedsince it always populated however. I'd not be ok with treating it as optional if it always does have a value passed in.string | undefinedworks, yeah. If it's always supposed to be provided, i'd recommend that - and the closure compiler typesystem would, too.don't share strict mode code if the default is non-strict unless you express that it should be strict.
You can drop a jsconfig.json (or tsconfig.json) somewhere at the root of the js source to set options for vscode and other TS-based JS's IDEs. The default for a new one generated by
tscisstrict: true, but that'll pepper errors all over the codebase, likely, since so much internal stuff is missing docs. Then again, those errors won't appear anywhere unless you set thecheckJsoption or drop a//@ts-checkin a file, so... Eh.Point is, the intention can be conveyed, if you'd like.
Point is, the intention can be conveyed, if you'd like.
I'm not eager to add a tripleslash to our docs for Node.js itself.
I'm not eager to add a tripleslash to our docs for Node.js itself.
? "A tripleslash"?
@weswigham https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html
/// <reference strict="true"/>That would be how I'd assume we would show intent in the docs if we expect it to be
strictTS, as I don't think explaining how to add a JSON config for typescript is reasonable.We don't support anything like that right now. Triple slash directives only exist to specify file dependency ordering in legacy concatenate type code, mostly. (You can't set arbitrary compiler options)
as I don't think explaining how to add a JSON config for typescript is reasonable.
Rather than explaining, you could just... Add it. Like the lint config, to which it is very similar.
@weswigham I don't understand. This is the documentation of the function, what do you mean "add it"
Oh, I mean "add the config file to specify that you'd prefer stricter checks throughout the project".
- I'm remain not comfortable adding a TS config to the docs.…On Tue, Oct 1, 2019, 12:38 PM Wesley Wigham ***@***.***> wrote: Oh, I mean "add the config file to specify that you'd prefer stricter checks throughout the project". — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#29610?email_source=notifications&email_token=AABZJIZL4F3NVZMN3LCPAXDQMODHZA5CNFSM4IYFKIOKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEACDC6A#issuecomment-537145720>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AABZJI2XMIKWLGZKCUG6HNLQMODHZANCNFSM4IYFKIOA> .
I think this is a bit of a red herring. We should not have jsdoc comments in code samples. The types are already specified exactly in the documentation.
Reacted by Derek LewisReacted by Wesley Wighamjsconfig.json
The tool may be named TypeScript, but ultimately there's no required exposure to TS as a language (unless you'd like to be pedantic and say the type documentation syntax is TS, but since it supports all the closure compiler syntax, too, I don't think that's really a problem), especially if you're just configuring IDE features when used this way.❤️ It's not much different from your eslint config file, really - it's a config file for a tool that runs checks over js files, the primary difference being this one does semantic checks and improves IDE features in some popular editors - especially if you're only using it for the editor support, and not actually running the tool for errors in CI. I somehow doubt we'd be having quite the same discussion if the js checker and the ts checker were different libraries, but they're not (since they're almost identical), so here we are.
Plus, I, at least, think a single config file is a bit nicer than inline pragmas for configuration - there's a reason every file doesn't list the lint rules it enables at the top; it's a bit messy, and usually repetitive. (Which, I guess, is why you said you wouldn't want to add one, if one worked, yeah?)
In any case, I wouldn't write inaccurate documentation, checked or no - the docs should include the
undefined-ness of a param in some way. 🤷♂️The types are already specified exactly in the documentation.
Aren't we talking about the code comments in the implementation? Oh, I had no idea we were talking about the doc sample, totally misread that. 🤦 (I thought we were talking about docstrings on the actual internals, which I'd love to see more of, cause they're pretty rare right now.)
I think stating the types in the sample is convenient (since it condenses what you need to read to understand the functionality), it's just unfortunately hard to keep it in sync with the API's types. Oh, and it being inaccurate messes with editor intellisense when people copy & paste it into their codebase, so if it's there, it should be precise~
Reacted by Derek LewisReacted by Derek Lewis@DerekNonGeneric I'd use the
--experimental-loaderReacted by Derek Lewis@devsnek, should I modify my PR to remove the type annotations?
@DerekNonGeneric i'm not planning to block it or anything, but i don't really see the point of including them.
DerekNonGeneric commented
on May 20, 2020 ContributorAuthorMore actionsThe ES module dummy loader has since been removed from this document and replaced with several wonderful examples. 🎉
An error occurs after creating the
custom-loader.mjscontaining the dummy loader code as directed by the documentation, anx.jsfile, and running the following command in PowerShell.node --experimental-modules --loader ./custom-loader.mjs x.jsBy the way, this command diverges from the one provided in the documentation to be used on Windows as
NODE_OPTIONS='--experimental-modules --loader ./custom-loader.mjs' node x.jsfails in PowerShell.The
x.jsfile certainly exists. It turns out that there is a Windows-specific error where a leading forward slash causes this example to break. I was able to resolve this by adding:prior to (from the dummy loader code):
and including the following function:
P.S. This also needs
import url from 'url';added to the top ofcustom-loader.mjs.