@@ -298,14 +298,14 @@ package. It is not a strong encapsulation since a direct require of any
298
298
absolute subpath of the package such as
299
299
` require('/path/to/node_modules/pkg/subpath.js') ` will still load ` subpath.js ` .
300
300
301
- #### Subpath exports
301
+ ### Subpath exports
302
302
303
- When using the ` "exports" ` field, custom subpaths can be defined along
304
- with the main entry point by treating the main entry point as the
305
- ` "." ` subpath:
303
+ > Stability: 1 - Experimental
306
304
307
- <!-- eslint-skip -->
308
- ``` js
305
+ When using the ` "exports" ` field, custom subpaths can be defined along with the
306
+ main entry point by treating the main entry point as the ` "." ` subpath:
307
+
308
+ ``` json
309
309
{
310
310
"main" : " ./main.js" ,
311
311
"exports" : {
@@ -315,8 +315,7 @@ with the main entry point by treating the main entry point as the
315
315
}
316
316
```
317
317
318
- Now only the defined subpath in ` "exports" ` can be imported by a
319
- consumer:
318
+ Now only the defined subpath in ` "exports" ` can be imported by a consumer:
320
319
321
320
``` js
322
321
import submodule from ' es-module-package/submodule' ;
@@ -330,30 +329,46 @@ import submodule from 'es-module-package/private-module.js';
330
329
// Throws ERR_PACKAGE_PATH_NOT_EXPORTED
331
330
```
332
331
333
- Entire folders can also be mapped with package exports:
332
+ ### Subpath export patterns
334
333
335
- <!-- eslint-skip -->
336
- ``` js
334
+ > Stability: 1 - Experimental
335
+
336
+ Explicitly listing each exports subpath entry is recommended for packages with
337
+ a small number of exports. But for packages that have very large numbers of
338
+ subpaths this can start to cause package.json bloat and maintenance issues.
339
+
340
+ For these use cases, subpath export patterns can be used instead:
341
+
342
+ ``` json
337
343
// ./node_modules/es-module-package/package.json
338
344
{
339
345
"exports" : {
340
- " ./features/" : " ./src/features/"
346
+ "./features/* " : " ./src/features/*.js "
341
347
}
342
348
}
343
349
```
344
350
345
- With the above, all modules within the ` ./src/features/ ` folder
346
- are exposed deeply to ` import ` and ` require ` :
351
+ The left hand matching pattern must always end in ` * ` . All instances of ` * ` on
352
+ the right hand side will then be replaced with this value, including if it
353
+ contains any ` / ` separators.
347
354
348
355
``` js
349
- import feature from ' es-module-package/features/x.js ' ;
356
+ import featureX from ' es-module-package/features/x' ;
350
357
// Loads ./node_modules/es-module-package/src/features/x.js
358
+
359
+ import featureY from ' es-module-package/features/y/y' ;
360
+ // Loads ./node_modules/es-module-package/src/features/y/y.js
351
361
```
352
362
353
- When using folder mappings, ensure that you do want to expose every
354
- module inside the subfolder. Any modules which are not public
355
- should be moved to another folder to retain the encapsulation
356
- benefits of exports.
363
+ This is a direct static replacement without any special handling for file
364
+ extensions. In the previous example, ` pkg/features/x.json ` would be resolved to
365
+ ` ./src/features/x.json.js ` in the mapping.
366
+
367
+ The property of exports being statically enumerable is maintained with exports
368
+ patterns since the individual exports for a package can be determined by
369
+ treating the right hand side target pattern as a ` ** ` glob against the list of
370
+ files within the package. Because ` node_modules ` paths are forbidden in exports
371
+ targets, this expansion is dependent on only the files of the package itself.
357
372
358
373
#### Package exports fallbacks
359
374
@@ -1741,7 +1756,8 @@ The resolver can throw the following errors:
1741
1756
> 1. Set _mainExport_ to _exports_ \[_ " ." _ \].
1742
1757
> 1. If _mainExport_ is not ** undefined ** , then
1743
1758
> 1. Let _resolved_ be the result of ** PACKAGE_TARGET_RESOLVE ** (
1744
- > _packageURL_, _mainExport_, _" " _, ** false ** , _conditions_).
1759
+ > _packageURL_, _mainExport_, _" " _, ** false ** , ** false ** ,
1760
+ > _conditions_).
1745
1761
> 1. If _resolved_ is not ** null ** or ** undefined ** , then
1746
1762
> 1. Return _resolved_ .
1747
1763
> 1. Otherwise , if _exports_ is an Object and all keys of _exports_ start with
@@ -1775,29 +1791,43 @@ _isImports_, _conditions_)
1775
1791
> 1. If _matchKey_ is a key of _matchObj_ , and does not end in _ " *" _ , then
1776
1792
> 1. Let _target_ be the value of _matchObj_ \[_matchKey_ \].
1777
1793
> 1. Let _resolved_ be the result of ** PACKAGE_TARGET_RESOLVE ** (
1778
- > _packageURL_, _target_, _" " _, _isImports_, _conditions_).
1794
+ > _packageURL_, _target_, _" " _, ** false ** , _isImports_, _conditions_).
1779
1795
> 1. Return the object _ { resolved, exact: ** true ** }_ .
1780
- > 1. Let _expansionKeys_ be the list of keys of _matchObj_ ending in _ " /" _ ,
1781
- > sorted by length descending .
1796
+ > 1. Let _expansionKeys_ be the list of keys of _matchObj_ ending in _ " /" _
1797
+ > or _ " * " _ , sorted by length descending .
1782
1798
> 1. For each key _expansionKey_ in _expansionKeys_ , do
1799
+ > 1. If _expansionKey_ ends in _ " *" _ and _matchKey_ starts with but is
1800
+ > not equal to the substring of _expansionKey_ excluding the last _ " *" _
1801
+ > character , then
1802
+ > 1. Let _target_ be the value of _matchObj_ \[_expansionKey_ \].
1803
+ > 1. Let _subpath_ be the substring of _matchKey_ starting at the
1804
+ > index of the length of _expansionKey_ minus one .
1805
+ > 1. Let _resolved_ be the result of ** PACKAGE_TARGET_RESOLVE ** (
1806
+ > _packageURL_, _target_, _subpath_, ** true ** , _isImports_,
1807
+ > _conditions_).
1808
+ > 1. Return the object _ { resolved, exact: ** true ** }_ .
1783
1809
> 1. If _matchKey_ starts with _expansionKey_ , then
1784
1810
> 1. Let _target_ be the value of _matchObj_ \[_expansionKey_ \].
1785
1811
> 1. Let _subpath_ be the substring of _matchKey_ starting at the
1786
1812
> index of the length of _expansionKey_ .
1787
1813
> 1. Let _resolved_ be the result of ** PACKAGE_TARGET_RESOLVE ** (
1788
- > _packageURL_, _target_, _subpath_, _isImports_, _conditions_).
1814
+ > _packageURL_, _target_, _subpath_, ** false ** , _isImports_,
1815
+ > _conditions_).
1789
1816
> 1. Return the object _ { resolved, exact: ** false ** }_ .
1790
1817
> 1. Return the object _ { resolved: ** null ** , exact: ** true ** }_ .
1791
1818
1792
- ** PACKAGE_TARGET_RESOLVE ** (_packageURL_, _target_, _subpath_, _internal_ ,
1793
- _conditions_)
1819
+ ** PACKAGE_TARGET_RESOLVE ** (_packageURL_, _target_, _subpath_, _pattern_ ,
1820
+ _internal_, _conditions_)
1794
1821
1795
1822
> 1. If _target_ is a String , then
1796
- > 1. If _subpath_ has non - zero length and _target_ does not end with _ " / " _ ,
1797
- > throw an _Invalid Module Specifier_ error .
1823
+ > 1. If _pattern_ is ** false ** , _subpath_ has non - zero length and _target_
1824
+ > does not end with _ " / " _ , throw an _Invalid Module Specifier_ error .
1798
1825
> 1. If _target_ does not start with _ " ./" _ , then
1799
1826
> 1. If _internal_ is ** true ** and _target_ does not start with _ " ../" _ or
1800
1827
> _ " /" _ and is not a valid URL , then
1828
+ > 1. If _pattern_ is ** true ** , then
1829
+ > 1. Return ** PACKAGE_RESOLVE ** (_target_ with every instance of
1830
+ > _" *" _ replaced by _subpath_, _packageURL_ + _" /" _)_ .
1801
1831
> 1. Return ** PACKAGE_RESOLVE ** (_target_ + _subpath_,
1802
1832
> _packageURL_ + _" /" _)_ .
1803
1833
> 1. Otherwise , throw an _Invalid Package Target_ error .
@@ -1809,8 +1839,12 @@ _conditions_)
1809
1839
> 1. Assert : _resolvedTarget_ is contained in _packageURL_ .
1810
1840
> 1. If _subpath_ split on _ " /" _ or _ " \\ " _ contains any _ " ." _ , _ " .." _ or
1811
1841
> _ " node_modules" _ segments , throw an _Invalid Module Specifier_ error .
1812
- > 1. Return the URL resolution of the concatenation of _subpath_ and
1813
- > _resolvedTarget_ .
1842
+ > 1. If _pattern_ is ** true ** , then
1843
+ > 1. Return the URL resolution of _resolvedTarget_ with every instance of
1844
+ > _ " *" _ replaced with _subpath_ .
1845
+ > 1. Otherwise ,
1846
+ > 1. Return the URL resolution of the concatenation of _subpath_ and
1847
+ > _resolvedTarget_ .
1814
1848
> 1. Otherwise , if _target_ is a non - null Object , then
1815
1849
> 1. If _exports_ contains any index property keys , as defined in ECMA - 262
1816
1850
> [6.1 .7 Array Index ][], throw an _Invalid Package Configuration_ error .
@@ -1819,16 +1853,18 @@ _conditions_)
1819
1853
> then
1820
1854
> 1. Let _targetValue_ be the value of the _p_ property in _target_ .
1821
1855
> 1. Let _resolved_ be the result of ** PACKAGE_TARGET_RESOLVE ** (
1822
- > _packageURL_, _targetValue_, _subpath_, _internal_, _conditions_).
1856
+ > _packageURL_, _targetValue_, _subpath_, _pattern_, _internal_,
1857
+ > _conditions_).
1823
1858
> 1. If _resolved_ is equal to ** undefined ** , continue the loop .
1824
1859
> 1. Return _resolved_ .
1825
1860
> 1. Return ** undefined ** .
1826
1861
> 1. Otherwise , if _target_ is an Array , then
1827
1862
> 1. If _target .length is zero , return ** null ** .
1828
1863
> 1. For each item _targetValue_ in _target_ , do
1829
1864
> 1. Let _resolved_ be the result of ** PACKAGE_TARGET_RESOLVE ** (
1830
- > _packageURL_, _targetValue_, _subpath_, _internal_, _conditions_),
1831
- > continuing the loop on any _Invalid Package Target_ error .
1865
+ > _packageURL_, _targetValue_, _subpath_, _pattern_, _internal_,
1866
+ > _conditions_), continuing the loop on any _Invalid Package Target_
1867
+ > error .
1832
1868
> 1. If _resolved_ is ** undefined ** , continue the loop .
1833
1869
> 1. Return _resolved_ .
1834
1870
> 1. Return or throw the last fallback resolution ** null ** return or error .
0 commit comments