Skip to content

Commit bc17659

Browse files
committed
Starting point for helpers design doc
1 parent 439e8ae commit bc17659

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ This team is spun off from the [Modules team](https://github.com/nodejs/modules)
3232

3333
- [ ] Move loaders off thread
3434

35-
- [ ] Add helper/utility functions [`module`](https://nodejs.org/api/module.html) module
35+
- [ ] Add [helper/utility functions](./doc/design/helpers.md) to the [`module`](https://nodejs.org/api/module.html) module
3636

3737
- [ ] Start with the functions that make up the ESM resolution algorithm as defined in the [spec](https://nodejs.org/api/esm.html#resolver-algorithm-specification). Create helper functions for each of the functions defined in that psuedocode: `esmResolve`, `packageImportsResolve`, `packageResolve`, `esmFileFormat`, `packageSelfResolve`, `readPackageJson`, `packageExportsResolve`, `lookupPackageScope`, `packageTargetResolve`, `packageImportsExportsResolve`, `patternKeyCompare`. (Not necessarily all with these exact names, but corresponding to these functions from the spec.)
38-
38+
3939
- [ ] Follow up with similar helper functions that make up what happens within Node’s internal `load`. (Definitions to come.)
4040

4141
- [ ] Support loading source when the return value of `load` has `format: 'commonjs'`. See https://github.com/nodejs/node/issues/34753#issuecomment-735921348 and https://github.com/nodejs/loaders-test/blob/835506a638c6002c1b2d42ab7137db3e7eda53fa/coffeescript-loader/loader.js#L45-L50.
@@ -47,7 +47,7 @@ We hope that moving loaders off thread will allow us to preserve an async `resol
4747
- [ ] Convert `resolve` from async to sync https://github.com/nodejs/node/pull/43363
4848

4949
- [ ] Add an async `resolve` to [`module`](https://nodejs.org/api/module.html) module
50-
50+
5151
- [ ] Consider an API for async operations before resolution begins, such as `preImport` https://github.com/nodejs/loaders/pull/89
5252

5353
After this, we should get user feedback regarding the developer experience; for example, is too much boilerplate required? Should we have a separate `transform` hook? And so on. We should also investigate and potentially implement the [technical improvements](doc/use-cases.md#improvements) on our to-do list.

doc/design/helpers.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Helpers
2+
3+
A user loader that defines a hook might need to reimplement all of Node’s original version of that hook, if the user hook can’t call `next` to get the result of the internal version. A case where this might occur is input that Node would error on, for example a `resolve` hook trying to resolve a protocol that Node doesn’t support. For such a hook, it could involve a lot of boilerplate or dependencies to reimplement all of the logic contained within Node’s internal version of that hook. We plan to create helper functions to reduce that need.
4+
5+
These will be added in stages, starting with helpers for the `resolve` hook that cover the various steps that Node’s internal `resolve` performs.
6+
7+
## `resolve` helpers
8+
9+
### `packageResolve`
10+
11+
Public reference to https://github.com/nodejs/node/blob/3350d9610864af3219de7dd20e3ac18b3c214c52/lib/internal/modules/esm/resolve.js#L847-L910.
12+
13+
Existing signature:
14+
15+
```js
16+
/**
17+
* @param {string} specifier
18+
* @param {string | URL | undefined} base
19+
* @param {Set<string>} conditions
20+
* @returns {resolved: URL, format? : string}
21+
*/
22+
function packageResolve(specifier, base, conditions) {
23+
```
24+
25+
New signature, where many supporting functions that this function calls are passed in (and if left undefined, the default versions are used):
26+
27+
```js
28+
function packageResolve(specifier, base, conditions, {
29+
parsePackageName,
30+
getPackageScopeConfig,
31+
packageExportsResolve,
32+
findPackageJson, // Part of current packageResolve extracted into its own function
33+
getPackageConfig,
34+
packageExportsResolve,
35+
legacyMainResolve,
36+
}) {
37+
```
38+
39+
The middle of the function, where it walks up the disk looking for `package.json`, would be moved into a separate function `findPackageJson` that would follow a pattern similar to this, where the various file system-related functions could all be overridden (so that a virtual filesystem could be simulated, for example).
40+
41+
### `findPackageJson`
42+
43+
Extracted from `packageResolve` https://github.com/nodejs/node/blob/3350d9610864af3219de7dd20e3ac18b3c214c52/lib/internal/modules/esm/resolve.js#L873-L887 plus the `while` condition:
44+
45+
```js
46+
function findPackageJson(packageName, base, isScoped, {
47+
fileURLToPath,
48+
tryStatSync,
49+
})
50+
```

doc/design/overview.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ There are currently [three loader hooks](https://github.com/nodejs/node/tree/mas
1313

1414
* `globalPreload`: Defines a string of JavaScript to be injected into the application global scope.
1515

16+
In order to reduce boilerplate within hooks, new [helper functions](./helpers.md) will be made available.
17+
1618
## Chaining
1719

1820
Custom loaders are intended to chain to support various concerns beyond the scope of core, such as build tooling, mocking, transpilation, etc.

0 commit comments

Comments
 (0)