- CJS source code using require()
|
+ CJS source code using require() |
ESM: consumers import your package |
CJS source and only ESM distribution |
@@ -41,7 +41,7 @@ There are other options available, mostly for historical purposes.
CJS source and both CJS & ESM distribution |
- ESM source code using import |
+ ESM source code using import |
CJS: consumers require() your package (and you use top-level await ) |
ESM source with only CJS distribution |
From b5085f2412ef371a47292061e8f2697f0508eaa5 Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Sat, 14 Dec 2024 20:58:15 +0100
Subject: [PATCH 35/41] fixup!: remove missed drinks
---
apps/site/pages/en/learn/modules/package-configuration.mdx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/site/pages/en/learn/modules/package-configuration.mdx b/apps/site/pages/en/learn/modules/package-configuration.mdx
index c4fb787f319ab..b9421bc825287 100644
--- a/apps/site/pages/en/learn/modules/package-configuration.mdx
+++ b/apps/site/pages/en/learn/modules/package-configuration.mdx
@@ -355,7 +355,7 @@ Similar to [CJS source and both CJS & ESM distribution](#cjs-source-and-both-cjs
#### Publish only a CJS distribution with property exports
-The "Mojito" of packages: Tricky to make and needs good ingredients.
+Tricky to make and needs good ingredients.
This option is almost identical to the [CJS source with CJS & ESM distribution's property exports](#attach-named-exports-directly-onto-raw-exports-endraw-) above. The only difference is in package.json: `"type": "module"`.
@@ -396,7 +396,7 @@ If your files explicitly _all_ use `.cjs` and/or `.mjs` file extensions (none us
#### Publish a CJS distribution with an ESM wrapper
-The "Pornstar Martini" of packages: There's a lot going on here. Unlike the cocktail, this is usually not the best.
+There's a lot going on here, and this is usually not the best.
This is also almost identical to the [CJS source and dual distribution using an ESM wrapper](#use-a-simple-esm-wrapper), but with subtle differences `"type": "module"` and some `.cjs` file extenions in package.json.
@@ -436,7 +436,7 @@ This is also almost identical to the [CJS source and dual distribution using an
#### Publish both full CJS & ESM distributions
-The "Tokyo Tea" of packages: Chuck in a bunch of stuff (with a surprise) and hope for the best. This is probably the most common and easiest of the ESM to CJS & ESM options, but you pay for it. This is rarely a good idea.
+Chuck in a bunch of stuff (with a surprise) and hope for the best. This is probably the most common and easiest of the ESM to CJS & ESM options, but you pay for it. This is rarely a good idea.
In terms of package configuration, there are a few options that differ mostly in personal preference.
From d34fd0b6dba565cfb8355d6cbc2c36c4a6c0e4c3 Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Wed, 18 Dec 2024 20:49:04 +0100
Subject: [PATCH 36/41] fixup!: rename to "publishing a package"
---
apps/site/navigation.json | 6 +++---
.../{package-configuration.mdx => publishing-a-package.mdx} | 4 ++--
packages/i18n/locales/en.json | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
rename apps/site/pages/en/learn/modules/{package-configuration.mdx => publishing-a-package.mdx} (99%)
diff --git a/apps/site/navigation.json b/apps/site/navigation.json
index 570387e158cec..39eb9df019b4c 100644
--- a/apps/site/navigation.json
+++ b/apps/site/navigation.json
@@ -313,9 +313,9 @@
"modules": {
"label": "components.navigation.learn.modules.links.modules",
"items": {
- "packageConfiguration": {
- "link": "/learn/modules/package-configuration",
- "label": "components.navigation.learn.modules.links.packageConfiguration"
+ "publishingAPackage": {
+ "link": "/learn/modules/publishing-a-package",
+ "label": "components.navigation.learn.modules.links.publishingAPackage"
},
"publishingNodeApiModules": {
"link": "/learn/modules/publishing-node-api-modules",
diff --git a/apps/site/pages/en/learn/modules/package-configuration.mdx b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
similarity index 99%
rename from apps/site/pages/en/learn/modules/package-configuration.mdx
rename to apps/site/pages/en/learn/modules/publishing-a-package.mdx
index b9421bc825287..2eeacf2a231fb 100644
--- a/apps/site/pages/en/learn/modules/package-configuration.mdx
+++ b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
@@ -1,10 +1,10 @@
---
-title: Package Configuration
+title: Publishing a package
layout: learn
authors: JakobJingleheimer
---
-# Package configuration
+# Publishing a package
All the provided `package.json` configurations (not specifically marked “does not work”) work in Node.js 12.22.x (v12 latest, the oldest supported line) and 17.2.0 (current latest at the time)[^1], and for grins, with webpack 5.53.0 and 5.63.0 respectively. These are available: [nodejs/package-examples](https://github.com/nodejs/package-examples/blob/main/config).
diff --git a/packages/i18n/locales/en.json b/packages/i18n/locales/en.json
index 71e466c094a61..6a07b3f089af0 100644
--- a/packages/i18n/locales/en.json
+++ b/packages/i18n/locales/en.json
@@ -90,7 +90,7 @@
"modules": {
"links": {
"modules": "Modules",
- "packageConfiguration": "Package configuration",
+ "publishingAPackage": "Publishing a package",
"publishingNodeApiModules": "How to publish a Node-API package",
"anatomyOfAnHttpTransaction": "Anatomy of an HTTP Transaction",
"abiStability": "ABI Stability",
From 4bd694ecb80149d2da5e54a445a21ca33d9b4c1f Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Wed, 18 Dec 2024 20:50:16 +0100
Subject: [PATCH 37/41] fixup!: move "general notes" to bottom
---
.../en/learn/modules/publishing-a-package.mdx | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/apps/site/pages/en/learn/modules/publishing-a-package.mdx b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
index 2eeacf2a231fb..e598f5363f2e5 100644
--- a/apps/site/pages/en/learn/modules/publishing-a-package.mdx
+++ b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
@@ -52,16 +52,6 @@ There are other options available, mostly for historical purposes.
-### General notes
-
-[Syntax detection](https://nodejs.org/api/packages.html#syntax-detection) is _**not**_ a replacement for proper package configuration; syntax detection is not fool-proof and it has [significant performance cost](https://github.com/nodejs/node/pull/55238).
-
-When using [`"exports"`](https://nodejs.org/api/packages.html#conditional-exports) in package.json, it is generally a good idea to include `"./package.json": "./package.json"` so that it can be imported ([`module.findPackageJSON`](https://nodejs.org/api/module.html#modulefindpackagejsonspecifier-base) is not affected by this limitation, but `import` may be more convenient).
-
-`"exports"` can be advisable over [`"main"`](https://nodejs.org/api/packages.html#main) because it prevents external access to internal code (so you can be relatively sure users are not depending on things they shouldn't). If you don't need that, `"main"` is simpler and may be a better option for you.
-
-The `"engines"` field provides both a human-friendly and a machine-friendly indication of which version(s) of Node.js the package is compatible. Depending on the package manager used, an exception may be thrown causing the installation to fail when the consumer is using an incompatible version of Node.js (which can be very helpful to consumers). Including this field will save a lot of headache for consumers with an older version of Node.js who cannot use the package.
-
### CJS source and distribution
You _technially_ may not need _any_ package configuration beyond [`"name"`](https://nodejs.org/api/packages.html#name). But the less arcane, the better: Essentially just declare the package’s exports via the `"exports"` field/field-set.
@@ -518,6 +508,16 @@ The configuration for this is the same as [CJS source and both CJS & ESM distrib
If you're a security researcher needing to investigate Node.js prior to v12.22.x, feel free to contact us for help configuring.
+## General notes
+
+[Syntax detection](https://nodejs.org/api/packages.html#syntax-detection) is _**not**_ a replacement for proper package configuration; syntax detection is not fool-proof and it has [significant performance cost](https://github.com/nodejs/node/pull/55238).
+
+When using [`"exports"`](https://nodejs.org/api/packages.html#conditional-exports) in package.json, it is generally a good idea to include `"./package.json": "./package.json"` so that it can be imported ([`module.findPackageJSON`](https://nodejs.org/api/module.html#modulefindpackagejsonspecifier-base) is not affected by this limitation, but `import` may be more convenient).
+
+`"exports"` can be advisable over [`"main"`](https://nodejs.org/api/packages.html#main) because it prevents external access to internal code (so you can be relatively sure users are not depending on things they shouldn't). If you don't need that, `"main"` is simpler and may be a better option for you.
+
+The `"engines"` field provides both a human-friendly and a machine-friendly indication of which version(s) of Node.js the package is compatible. Depending on the package manager used, an exception may be thrown causing the installation to fail when the consumer is using an incompatible version of Node.js (which can be very helpful to consumers). Including this field will save a lot of headache for consumers with an older version of Node.js who cannot use the package.
+
## Down the rabbit-hole
Specifically in relation to Node.js, there are 4 problems to solve:
From 64ed71944741e08f10e2e78b9c1a420efcb433d8 Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Wed, 18 Dec 2024 21:15:26 +0100
Subject: [PATCH 38/41] fixup!: wordsmith
---
apps/site/pages/en/learn/modules/publishing-a-package.mdx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/site/pages/en/learn/modules/publishing-a-package.mdx b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
index e598f5363f2e5..19405f31f4f3f 100644
--- a/apps/site/pages/en/learn/modules/publishing-a-package.mdx
+++ b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
@@ -54,7 +54,7 @@ There are other options available, mostly for historical purposes.
### CJS source and distribution
-You _technially_ may not need _any_ package configuration beyond [`"name"`](https://nodejs.org/api/packages.html#name). But the less arcane, the better: Essentially just declare the package’s exports via the `"exports"` field/field-set.
+The most minimal configuration may be only [`"name"`](https://nodejs.org/api/packages.html#name). But the less arcane, the better: Essentially just declare the package’s exports via the `"exports"` field/field-set.
**Working example**: [cjs-with-cjs-distro](https://github.com/JakobJingleheimer/nodejs-module-config-examples/tree/main/packages/cjs/cjs-distro)
@@ -113,7 +113,7 @@ Note that ESM now _is_ “backwards” compatible with CJS: a CJS module now _ca
### CJS source and only ESM distribution
-This takes a small bit of finesse but is also pretty straight-forward.
+This takes a small bit of finesse but is also pretty straight-forward. This may be the choice pick of older projects targetting newer standards, or authors who merely prefer CJS but are publishing for a different environment.
**Working example**: [cjs-with-esm-distro](https://github.com/JakobJingleheimer/nodejs-module-config-examples/tree/main/packages/cjs/esm-distro)
@@ -140,7 +140,7 @@ The [`.mjs`](https://nodejs.org/api/esm.html#enabling) file extension is a trump
### CJS source and both CJS & ESM distribution
-You have a few options:
+In order to _directly_ supply both audiences (so that your distribution works "natively" in either), you have a few options:
#### Attach named exports directly onto `exports`
From 7b692f979c5859f872b25a033f999854d1b30474 Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Wed, 18 Dec 2024 21:17:10 +0100
Subject: [PATCH 39/41] fixup!: move pros/cons after examples
---
.../en/learn/modules/publishing-a-package.mdx | 54 +++++++++----------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/apps/site/pages/en/learn/modules/publishing-a-package.mdx b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
index 19405f31f4f3f..420784a2c1c8e 100644
--- a/apps/site/pages/en/learn/modules/publishing-a-package.mdx
+++ b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
@@ -146,16 +146,6 @@ In order to _directly_ supply both audiences (so that your distribution works "n
Classic but takes some sophistication and finesse.
-Pros:
-
-- Smaller package weight
-- Easy and simple (probably least effort if you don't mind keeping to a minor syntax stipulation)
-- Precludes [the Dual-Package Hazard](#the-dual-package-hazard)
-
-Cons:
-
-- Requires very specific syntax (either in source code and/or bundler gymnastics).
-
**Working example**: [cjs-with-dual-distro (properties)](https://github.com/JakobJingleheimer/nodejs-module-config-examples/tree/main/packages/cjs/dual/property-distro)
```json displayName="Minimal package.json"
@@ -177,6 +167,16 @@ Cons:
}
```
+Pros:
+
+- Smaller package weight
+- Easy and simple (probably least effort if you don't mind keeping to a minor syntax stipulation)
+- Precludes [the Dual-Package Hazard](#the-dual-package-hazard)
+
+Cons:
+
+- Requires very specific syntax (either in source code and/or bundler gymnastics).
+
Sometimes, a CJS module may re-assign `module.exports` to something else (be it an object or a function) like this:
```cjs
@@ -201,14 +201,6 @@ module.exports.qux = function qux() {};
Complicated setup and difficult to get the balance right.
-Pros:
-
-- Smaller package weight
-
-Cons:
-
-- Likely requires complicated bundler gymnastics (we could not find any existing option to automate this in Webpack).
-
**Working example**: [cjs-with-dual-distro (wrapper)](https://github.com/JakobJingleheimer/nodejs-module-config-examples/tree/main/packages/cjs/dual/wrapper-distro)
```json displayName="Minimal package.json"
@@ -240,6 +232,14 @@ Cons:
}
```
+Pros:
+
+- Smaller package weight
+
+Cons:
+
+- Likely requires complicated bundler gymnastics (we could not find any existing option to automate this in Webpack).
+
When the CJS output from the bundler evades the named exports detection in Node.js, a ESM wrapper can be used to explicitly re-export the known named exports for ESM consumers.
When CJS exports an object (which gets aliased to ESM's `default`), you can save references to all the members of the object locally in the wrapper, and then re-export them so the ESM consumer can access all of them by name.
@@ -258,15 +258,6 @@ export { a, b, c /* … */ };
Chuck in a bunch of stuff and hope for the best. This is probably the most common and easiest of the CJS to CJS & ESM options, but you pay for it. This is rarely a good idea.
-Pros:
-
-- Simple bundler configuration
-
-Cons:
-
-- Larger package weight (basically double)
-- Vulnerable to [the Dual-Package Hazard](#the-dual-package-hazard)
-
**Working example**: [cjs-with-dual-distro (double)](https://github.com/JakobJingleheimer/nodejs-module-config-examples/tree/main/packages/cjs/dual/double-distro)
```json displayName="Minimal package.json"
@@ -298,6 +289,15 @@ Cons:
}
```
+Pros:
+
+- Simple bundler configuration
+
+Cons:
+
+- Larger package weight (basically double)
+- Vulnerable to [the Dual-Package Hazard](#the-dual-package-hazard)
+
Alternatively, you can use `"default"` and `"node"` keys, which are less counter-intuitive: Node.js will always choose the `"node"` option (which always works), and non-Node.js tooling will choose `"default"` when configured to target something other than node. **This precludes the dual-package hazard.**
```json displayName="Minimal package.json"
From 1ffb083659074ea763ec0760271fc73a07a702cf Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Wed, 18 Dec 2024 21:20:07 +0100
Subject: [PATCH 40/41] fixup!: explain "attach onto `exports`"
---
apps/site/pages/en/learn/modules/publishing-a-package.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/site/pages/en/learn/modules/publishing-a-package.mdx b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
index 420784a2c1c8e..4e22abff552ea 100644
--- a/apps/site/pages/en/learn/modules/publishing-a-package.mdx
+++ b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
@@ -144,7 +144,7 @@ In order to _directly_ supply both audiences (so that your distribution works "n
#### Attach named exports directly onto `exports`
-Classic but takes some sophistication and finesse.
+Classic but takes some sophistication and finesse. This means adding properties onto the existing `module.exports` (instead of re-assigning `module.exports` as a whole).
**Working example**: [cjs-with-dual-distro (properties)](https://github.com/JakobJingleheimer/nodejs-module-config-examples/tree/main/packages/cjs/dual/property-distro)
From cda5e86dd90a579f00c899b9b8fee10ee7ad6fae Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Wed, 18 Dec 2024 21:21:48 +0100
Subject: [PATCH 41/41] fixup!: temp restore examples repo
---
apps/site/pages/en/learn/modules/publishing-a-package.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/site/pages/en/learn/modules/publishing-a-package.mdx b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
index 4e22abff552ea..5c0b82e6f89dc 100644
--- a/apps/site/pages/en/learn/modules/publishing-a-package.mdx
+++ b/apps/site/pages/en/learn/modules/publishing-a-package.mdx
@@ -6,7 +6,7 @@ authors: JakobJingleheimer
# Publishing a package
-All the provided `package.json` configurations (not specifically marked “does not work”) work in Node.js 12.22.x (v12 latest, the oldest supported line) and 17.2.0 (current latest at the time)[^1], and for grins, with webpack 5.53.0 and 5.63.0 respectively. These are available: [nodejs/package-examples](https://github.com/nodejs/package-examples/blob/main/config).
+All the provided `package.json` configurations (not specifically marked “does not work”) work in Node.js 12.22.x (v12 latest, the oldest supported line) and 17.2.0 (current latest at the time)[^1], and for grins, with webpack 5.53.0 and 5.63.0 respectively. These are available: [JakobJingleheimer/nodejs-module-config-examples](https://github.com/JakobJingleheimer/nodejs-module-config-examples).
For curious cats, [How did we get here](#how-did-we-get-here) and [Down the rabbit-hole](#down-the-rabbithole) provide background and deeper explanations.