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
const Module = require('bare-module')
A package is directory with a package.json
file.
{
"name": "my-package"
}
The name of the package. This is used for addon resolution, self-referencing, and importing packages by name.
{
"version": "1.2.3"
}
The current version of the package. This is used for addon resolution.
{
"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": {
".": "./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.
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 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. |
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')
.
If a package defines only a single export, "."
, it may leave out the subpath entirely:
{
"exports": "./index.js"
}