@@ -183,25 +183,75 @@ versions of Node.js, but its capabilities are limited: it only defines the main
183
183
entry point of the package.
184
184
185
185
The ` "exports" ` field provides an alternative to ` "main" ` where the package
186
- main entry point can be defined while also encapsulating the package, preventing
187
- any other entry points besides those defined in ` "exports" ` . If package entry
188
- points are defined in both ` "main" ` and ` "exports" ` , the latter takes precedence
189
- in versions of Node.js that support ` "exports" ` . [ Conditional Exports] [ ] can
190
- also be used within ` "exports" ` to define different package entry points per
191
- environment, including whether the package is referenced via ` require ` or via
192
- ` import ` .
186
+ main entry point can be defined while also encapsulating the package,
187
+ ** preventing any other entry points besides those defined in ` "exports" ` ** .
188
+ This encapsulation allows module authors to define a public interface for
189
+ their package.
193
190
194
191
If both ` "exports" ` and ` "main" ` are defined, the ` "exports" ` field takes
195
- precedence over ` "main" ` .
192
+ precedence over ` "main" ` . ` "exports" ` are not specific to ES modules or
193
+ CommonJS; ` "main" ` will be overridden by ` "exports" ` if it exists. As such
194
+ ` "main" ` cannot be used as a fallback for CommonJS but it can be used as a
195
+ fallback for legacy versions of Node.js that do not support the ` "exports" `
196
+ field.
197
+
198
+ [ Conditional Exports] [ ] can be used within ` "exports" ` to define different
199
+ package entry points per environment, including whether the package is
200
+ referenced via ` require ` or via ` import ` . For more information about supporting
201
+ both CommonJS and ES Modules in a single package please consult
202
+ [ the dual CommonJS/ES module packages section] [ ] .
203
+
204
+ ** Warning** : Introducing the ` "exports" ` field prevents consumers of a package
205
+ from using any entry points that are not defined, including the ` package.json `
206
+ (e.g. ` require('your-package/package.json') ` . ** This will likely be a breaking
207
+ change.**
208
+
209
+ To make the introduction of ` "exports" ` non-breaking, ensure that every
210
+ previously supported entry point is exported. It is best to explicitly specify
211
+ entry points so that the package’s public API is well-defined. For example,
212
+ a project that previous exported ` main ` , ` lib ` ,
213
+ ` feature ` , and the ` package.json ` could use the following ` package.exports ` :
196
214
197
- Both ` "main" ` and ` "exports" ` entry points are not specific to ES modules or
198
- CommonJS; ` "main" ` will be overridden by ` "exports" ` in a ` require ` so it is
199
- not a CommonJS fallback.
215
+ ``` json
216
+ {
217
+ "name" : " my-mod" ,
218
+ "exports" : {
219
+ "." : " ./lib/index.js" ,
220
+ "./lib" : " ./lib/index.js" ,
221
+ "./lib/index" : " ./lib/index.js" ,
222
+ "./lib/index.js" : " ./lib/index.js" ,
223
+ "./feature" : " ./feature/index.js" ,
224
+ "./feature/index.js" : " ./feature/index.js" ,
225
+ "./package.json" : " ./package.json"
226
+ }
227
+ }
228
+ ```
229
+
230
+ Alternatively a project could choose to export entire folders:
231
+
232
+ ``` json
233
+ {
234
+ "name" : " my-mod" ,
235
+ "exports" : {
236
+ "." : " ./lib/index.js" ,
237
+ "./lib" : " ./lib/index.js" ,
238
+ "./lib/" : " ./lib/" ,
239
+ "./feature" : " ./feature/index.js" ,
240
+ "./feature/" : " ./feature/" ,
241
+ "./package.json" : " ./package.json"
242
+ }
243
+ }
244
+ ```
200
245
201
- This is important with regard to ` require ` , since ` require ` of ES module files
202
- throws an error in all versions of Node.js. To create a package that works both
203
- in modern Node.js via ` import ` and ` require ` and also legacy Node.js versions,
204
- see [ the dual CommonJS/ES module packages section] [ ] .
246
+ As a last resort, package encapsulation can be disabled entirely by creating an
247
+ export for the root of the package ` "./": "./" ` . This will expose every file in
248
+ the package at the cost of disabling the encapsulation and potential tooling
249
+ benefits this provides. As the ES Module loader in Node.js enforces the use of
250
+ [ the full specifier path] [ ] , exporting the root rather than being explicit
251
+ about entry is less expressive than either of the prior examples. Not only
252
+ will encapsulation be lost but module consumers will be unable to
253
+ ` import feature from 'my-mod/feature' ` as they will need to provide the full
254
+ path ` import feature from 'my-mod/feature/index.js ` .
205
255
206
256
#### Main Entry Point Export
207
257
@@ -1746,6 +1796,7 @@ success!
1746
1796
[dynamic instantiate hook]: #esm_code_dynamicinstantiate_code_hook
1747
1797
[import an ES or CommonJS module for its side effects only]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Import_a_module_for_its_side_effects_only
1748
1798
[special scheme]: https://url.spec.whatwg.org/#special-scheme
1799
+ [the full specifier path]: #esm_mandatory_file_extensions
1749
1800
[the official standard format]: https://tc39.github.io/ecma262/#sec-modules
1750
1801
[the dual CommonJS/ES module packages section]: #esm_dual_commonjs_es_module_packages
1751
1802
[transpiler loader example]: #esm_transpiler_loader
0 commit comments