* move bare ref and update links * move pear ref into subfolder * update README * tiny fix --------- Co-authored-by: Vivek Singh <vivek@peartree.to>
4.9 KiB
Bare Modules
Bare modules provide a robust system for managing code dependencies within Bare applications. This section delves into the details of Bare's module system.
npm i bare-module
Usage
const Module = require('bare-module')
External Modules for Bare
Packages
A package is directory with a package.json file.
Fields
"name"
{
"name": "my-package"
}
The name of the package. This is used for addon resolution, self-referencing, and importing packages by name.
"version"
{
"version": "1.2.3"
}
The current version of the package. This is used for addon resolution.
"type"
{
"type": "module"
}
The module format used for .js files. If not defined, .js files are interpreted as CommonJS. If set to "module" the .js files are instead interpreted as ES modules.
"exports"
{
"exports": {
".": "./index.js"
}
}
The entry points of the package. If defined, only the modules explicitly exported by the package may be imported when importing the package by name.
Subpath exports
A package may define more than one entry point by declaring several subpaths with the main export being ".":
{
"exports": {
".": "./index.js",
"./submodule": "./lib/submodule.js"
}
}
When importing the package by name, require('my-package') will resolve to <modules>/my-package/index.js whereas require('my-package/submodule') will resolve to <modules>/my-package/lib/submodule.js.
Conditional exports
Conditional exports allow packages to provide different exports for different conditions, such as the module format of the importing module:
{
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.cjs"
}
}
}
When importing the package by name, require('my-package') will resolve to <modules>/my-package/index.cjs whereas import 'my-package' will resolve to <modules>/my-package/index.mjs.
Similarly, conditional exports can be used to provide different entry points for different runtimes:
{
"exports": {
".": {
"bare": "./bare.js",
"node": "./node.js"
}
}
}
To provide a fallback for when no other conditions match, the "default" condition can be declared:
{
"exports": {
".": {
"bare": "./bare.js",
"node": "./node.js",
"default": "./fallback.js"
}
}
}
The following conditions are supported, listed in order from most specific to least specific as conditions should be defined:
| Condition | Description |
|---|---|
"bare" |
This applies when the module is being imported from another Bare module. |
"node" |
This applies when the module is being imported within a Node.js environment. |
"import" |
This applies when the module is being imported using an ES module import statement. |
"require" |
This applies when the module is being imported using the CommonJS require() function. |
"default" |
This serves as a fallback export if none of the more specific conditions (bare, node, import, require) are met. |
Self-referencing
Within a package, exports defined in the "exports" field can be referenced by importing the package by name. For example, given the following package.json...
{
"name": "my-package",
"exports": {
".": "./index.js",
"./submodule": "./lib/submodule.js"
}
}
...any module within my-package may reference these entry points using either require('my-package') or require('my-package/submodule').
Exports sugar
If a package defines only a single export, ".", it may leave out the subpath entirely:
{
"exports": "./index.js"
}