@leightonrthomas/manifest v3.1.0
Manifest
Manifest is a JavaScript command-line tool that compiles your services from a definition file (in one of the accepted formats - js, xml, yaml) into regular JavaScript that's ready to be imported and used in your application, and leaves it entirely up to you how and where those services are stored. It also allows for powerful custom build-steps to be run, allowing you to dynamically change services in any way you want.
Manifest currently uses ES6 module syntax in its output.
Installation
npm install --save --dev @leightonrthomas/manifest
yarn add --dev @leightonrthomas/manifest
Manifest only needs to be installed in --dev
mode, as it will just produce an output file that can be used anywhere.
Example
From this service definition:
my_service_1:
from: "!./../../MyFile/MyExport"
arguments:
- "@my_service_2"
- 4
my_service_2:
public: false
from: "!./../../MyFile/MyOtherExport"
my_service_3:
from: "!SomePackage/SomeExport"
and this configuration:
module.exports = {
buildSteps: [],
outputTypeDefinitions: true,
};
Manifest will produce a JavaScript file that can be imported and used as such:
// Name of the output file is configurable
import { container } from './my_output.js';
console.log(container.has("my_service_1")); // true
console.log(container.has("my_service_2")); // false
console.log(container.has("my_service_3")); // true
console.log(container.get("my_service_1")); // MyExport { prop1: MyOtherExport, prop2: 4 }
console.log(container.get("my_service_3")); // SomeExport { }
container.get("my_service_2"); // throws an Error, "Invalid or unknown service identifier provided: my_service_2"
Manifest will also export TypeScript definitions if outputTypeDefinitions
is set to true
, producing something like:
/**
* ! WARNING !
* -----------
* This file was automatically generated by Manifest and should not be modified!
* If container definitions need to change, re-build the container using Manifest.
*/
import {MyExport as E0} from './../../MyFile';
import {MyOtherExport as E1} from './../../MyFile';
import {SomeExport as E2} from 'SomePackage';
declare enum Service
{
["my_service_1"] = "my_service_1",
["my_service_3"] = "my_service_3",
}
declare interface Container
{
has(id: string): boolean;
get(id: Service.my_service_1): E0;
get(id: Service.my_service_3): E2;
}
The TypeScript output will only contain services marked as public
.
Commands
manifest build
argument | description |
---|---|
config | The path (from current working directory) to the configuration .js file |
input | The path (from current working directory) to the input service definitions file |
output | The path (from current working directory) to the output file where the services will be written to |
This command will build the services and output them to a file.
If TypeScript definition output is enabled in your configuration, it will just use the output
argument with .js
replaced by .d.ts
.
⚠️ Manifest will always overwrite the output files! ⚠️
manifest lint
argument | description |
---|---|
config | The path (from current working directory) to the configuration .js file |
input | The path (from current working directory) to the input service definitions file |
This command will lint the service definition (input argument), effectively building the services without writing them to a file so that you can confirm everything is set up correctly.
Features
- Circular reference detection
- Service definitions can be written in XML (xsd, example), YAML (schema, example) and JavaScript (example)
- Powerful pre-build steps that can be used to dynamically manipulate services before they're written to a JavaScript output file
- The ability to use any custom container using the
customContainer
option in configuration - Automatic TypeScript definition output for type safe service retrieval
TO-DO
- Add better documentation
Inspiration
Manifest is inspired by Symfony's dependency injection container package for PHP.