-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
doc: add Customization section and subsections to related sub systems #50419
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,52 @@ | ||||||||||||||||||
# Customization | ||||||||||||||||||
|
||||||||||||||||||
> Stability: 1.0 - Early development | ||||||||||||||||||
|
||||||||||||||||||
Node.js has multiple APIs for customizing behaviour and can easily be invoked | ||||||||||||||||||
via [`--import`][]: A `"nodejs-customization"` [entry point][`"exports"`] for a | ||||||||||||||||||
package loaded via [`--import`][] is automatically run at startup. The | ||||||||||||||||||
package.json of such a plugin would look something like this: | ||||||||||||||||||
|
||||||||||||||||||
```json | ||||||||||||||||||
{ | ||||||||||||||||||
"name": "example-nodejs-plugin", | ||||||||||||||||||
"keywords": [ | ||||||||||||||||||
"nodejs-plugin" | ||||||||||||||||||
], | ||||||||||||||||||
"exports": { | ||||||||||||||||||
"nodejs-customization": "./registration.mjs" | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
``` | ||||||||||||||||||
|
||||||||||||||||||
Setting the keyword `nodejs-plugin` is important for users to find the package | ||||||||||||||||||
(which may be automated). It should also contain the official name(s) for the | ||||||||||||||||||
support it provides; for a plugin extending support for typescript would contain | ||||||||||||||||||
`typescript` in its keywords; avoid red-herrings such as `typescript` as a | ||||||||||||||||||
keyword when the library does not extend support for typescript but is merely | ||||||||||||||||||
itself written in typescript. Failing to avoid these red-herrings will cause | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
your package to be listed for things it does not do, aggravating users. | ||||||||||||||||||
|
||||||||||||||||||
These steps configure Node.js with a customization plugin: | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section mixes instructions for package authors writing a plugin with instructions for using such a plugin. I feel like those should be separate sections, as end users aren’t going to care about how a plugin should be authored. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll add a heading ("Setting up a plugin") between 28 and 30 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably put the “Using a plugin” section first, as it applies to more people. (Not sure if “setting up” means authoring or consuming.) |
||||||||||||||||||
|
||||||||||||||||||
1. Install the plugin via your preferred package manager. For finding the | ||||||||||||||||||
plugin, package managers provide often a CLI utility, such as [`npm | ||||||||||||||||||
search`][], as well as a website. | ||||||||||||||||||
2. Once installed, in order to get Node.js to automatically use it, create a | ||||||||||||||||||
[`.env`][`--env-file`] file containing an [`--import`][] for your chosen | ||||||||||||||||||
plugin, like `NODE_OPTIONS="--import=example-nodejs-plugin"`. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we’re using the standardized export that you mentioned above, this would be
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OH!! Actually, this is an interesting point, and I think absolves us from a not-great entry-point name: We "control" this {
"name": "example-nodejs-plugin",
"exports": {
"register": "whatever.mjs"
},
"keywords": ["nodejs-plugin", "…"]
} NODE_OPTIONS="--import=example-nodejs-plugin/register" The problem before would exist if node automatically calls the entry-point whenever any package is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but that’s also why it’s not that important that it be standardized. I think the only benefit of standardization is so that the wizard we eventually create knows what export to use. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, exactly. |
||||||||||||||||||
3. Include the env file flag on subsequent runs, like | ||||||||||||||||||
`node --env-file=.env main.mjs`. | ||||||||||||||||||
|
||||||||||||||||||
## APIs | ||||||||||||||||||
|
||||||||||||||||||
Customizable systems each expose a `register` function, whereby the | ||||||||||||||||||
customization plugin is registered into Node.js. | ||||||||||||||||||
|
||||||||||||||||||
* [`node:module`][module.register] | ||||||||||||||||||
|
||||||||||||||||||
[`"exports"`]: packages.md#exports | ||||||||||||||||||
[`--env-file`]: cli.md#--env-file | ||||||||||||||||||
[`--import`]: cli.md#--import | ||||||||||||||||||
[`npm search`]: https://docs.npmjs.com/cli/v10/commands/npm-search | ||||||||||||||||||
[module.register]: module.md#moduleregisterspecifier-parenturl-options |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -683,6 +683,44 @@ export async function load(url, context, nextLoad) { | |||||
In a more advanced scenario, this can also be used to transform an unsupported | ||||||
source to a supported one (see [Examples](#examples) below). | ||||||
|
||||||
### External formats | ||||||
|
||||||
Node.js natively understands a handful of formats (see the table in [`load` | ||||||
hook][load hook]). Non-native or external formats require transpilation to | ||||||
something Node.js understands, and many packages exist to handle this. A simple | ||||||
example of such a package would look something like this: | ||||||
|
||||||
```json | ||||||
{ | ||||||
"name": "example-nodejs-plugin", | ||||||
"keywords": [ | ||||||
"nodejs-plugin", | ||||||
"typescript" | ||||||
], | ||||||
"exports": { | ||||||
"nodejs-customization": "./registration.mjs", | ||||||
"typescript": "./hooks/typescript.mjs" | ||||||
} | ||||||
} | ||||||
``` | ||||||
|
||||||
```mjs | ||||||
import { register } from 'node:module'; | ||||||
|
||||||
register('example-nodejs-plugin/typescript'); | ||||||
``` | ||||||
|
||||||
`typescript.mjs` would contain [customization hooks][hooks]: | ||||||
|
||||||
* A [`resolve` hook][resolve hook] that sets `format` for applicable modules to | ||||||
the format it handles, such as `'typescript'`. | ||||||
* A [`load` hook][load hook] that transpiles the external format (as signalled | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
by its `resolve` hook) to something Node.js understands. | ||||||
* Optionally, an [`initialize` hook][`initialize`]. | ||||||
|
||||||
See [Node.js Customization][Customization] for information about registering and | ||||||
persisting these plugins. | ||||||
|
||||||
### Examples | ||||||
|
||||||
The various module customization hooks can be used together to accomplish | ||||||
|
@@ -1027,6 +1065,7 @@ returned object contains the following keys: | |||||
|
||||||
[CommonJS]: modules.md | ||||||
[Conditional exports]: packages.md#conditional-exports | ||||||
[Customization]: customization.md | ||||||
[Customization hooks]: #customization-hooks | ||||||
[ES Modules]: esm.md | ||||||
[HTTPS and HTTP imports]: esm.md#https-and-http-imports | ||||||
|
@@ -1048,5 +1087,6 @@ returned object contains the following keys: | |||||
[load hook]: #loadurl-context-nextload | ||||||
[module wrapper]: modules.md#the-module-wrapper | ||||||
[realm]: https://tc39.es/ecma262/#realm | ||||||
[resolve hook]: #resolvespecifier-context-nextresolve | ||||||
[source map include directives]: https://sourcemaps.info/spec.html#h.lmz475t4mvbx | ||||||
[transferrable objects]: worker_threads.md#portpostmessagevalue-transferlist |
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.
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.
Gah. I think VS Code uses my system language for spell check. (This project has confused the heck outta spell check on my iPhone)
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.
I use this extension: https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker
It allows you to have custom settings by workspace, so you can create a Node workspace and configure
cSpell
within that workspace to use US English.