https://github.com/voxpelli/plugin-importer
Recursively imports a plugin tree in order of dependencies
https://github.com/voxpelli/plugin-importer
plugin-system
Last synced: 9 months ago
JSON representation
Recursively imports a plugin tree in order of dependencies
- Host: GitHub
- URL: https://github.com/voxpelli/plugin-importer
- Owner: voxpelli
- License: mit
- Created: 2023-07-30T16:21:31.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2025-04-03T19:46:21.000Z (about 1 year ago)
- Last Synced: 2025-05-17T04:36:18.853Z (11 months ago)
- Topics: plugin-system
- Language: JavaScript
- Homepage:
- Size: 40 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Plugin Importer
Recursively imports a plugin tree in order of dependencies
[](https://www.npmjs.com/package/plugin-importer)
[](https://www.npmjs.com/package/plugin-importer)
[](https://github.com/neostandard/neostandard)
[](https://github.com/voxpelli/badges-cjs-esm)
[](https://github.com/voxpelli/types-in-js)
[](https://bsky.app/profile/voxpelli.com)
[](https://mastodon.social/@voxpelli)
## Usage
### Simple
```javascript
import { resolvePlainPlugins } from 'plugin-importer';
const loadedPlugins = await resolvePlainPlugins([
'./test-dependency',
'module-dependency',
], {
meta: import.meta, // Ensures local paths are resolved in relation to this file
});
```
### Powerful
```javascript
import { loadPlugins, resolvePluginsInOrder } from 'plugin-importer';
/**
* @param {unknown} module
* @param {import('plugin-importer').ProcessPluginContext} context
* @returns {SupersetOfPluginDefinition}
*/
function processPlugin (module, { normalizedPluginName, pluginDir }) {
// Whatever other stuff you want to do to resolve the SupersetOfPluginDefinition
}
const pluginLoader = loadPlugins(processPlugin, {
meta: import.meta, // Ensures local paths are resolved in relation to this file
});
// loadedPlugins will be an ordered array of SupersetOfPluginDefinition,in order of who depends on whom
const loadedPlugins = await resolvePluginsInOrder(
[
'./test-dependency',
'module-dependency',
],
pluginLoader
);
```
## Exports
### Core exports
* `assertToBePluginDefinition(value)` – throws if `value` isn't a valid `PluginDefinition` (and correctly narrows the type when used with TypeScript)
* `isPluginDefinition(value)` – returns `true` if `value` is a valid `PluginDefinition` (and correctly narrows the type when used with TypeScript)
* `loadPlugins(processPlugin, [LoadPluginsOptions])` – creates the plugin loader responsible for loading a valid plugin
* `resolvePluginsInOrder(plugins, pluginLoader, [allowOptionalDependencies])` – resolves and loads plugins and returns them with the plugin depended upon first and the plugins depending on them last
### Plain plugins exports
* `loadPlainPlugins([LoadPluginsOptions])` – like `loadPlugins`, but geared to load pure `PluginDefinition` rather than supersets
* `processPlainPlugin` – the `processPlugin` that's used in `loadPlainPlugins`, should never be needed to be called diretcly
* `resolvePlainPlugins(dependencies, [LoadPluginsOptions])` – shortcut for calling `resolvePluginsInOrder` with `loadPlainPlugins`
### Utils exports
* `getExtensionlessBasename(value)` – like [`path.basename(value)`](https://nodejs.org/api/path.html#pathbasenamepath-suffix) but removes file extensions
* `importAbsolutePath(absolutePath)` – like [`import(absolutePath)`](https://nodejs.org/api/esm.html#import-expressions) but made to easily work with absolute paths on Windows
## Types
* `LoadPluginsOptions` – the optional options for `loadPlugins`. Contains:
* `cwd` – the working directory to load relative plugin paths from
* `meta` – convenience option for setting `cwd` by giving an [`import.meta`](https://nodejs.org/api/esm.html#importmeta)
* `prefix` – a prefix that will be added to dependency names. Eg `example-prefix` would be added to `foo` to make `example-prefix-foo` and to `@voxpelli` to make `@voxpelli/example-prefix`, but eg. `example-prefix-foo` would not be prefixed as it already has the prefix and `@voxpelli/foo` would neither get prefixed. This is along the lines of what `eslint` does with [`eslint-config`](https://eslint.org/docs/latest/extend/shareable-configs#creating-a-shareable-config) prefixes
* `PluginDefinition` – the basic definition of a plugin. All loaded plugins are expected to conform to this or a superset of this.
* `ProcessPluginContext` – the context given to `processPlugin`