You can extend Stryker with 6 plugin kinds:
export enum PluginKind {
ConfigEditor = 'ConfigEditor',
TestRunner = 'TestRunner',
TestFramework = 'TestFramework',
Transpiler = 'Transpiler',
Mutator = 'Mutator',
Reporter = 'Reporter'
}
They are loaded using the plugins
configuration option
Each plugin has it's own job to do. For inspiration, checkout the stryker monorepo.
Creating plugins is best done with typescript, as that will help you a lot with type safety.
We provide the @stryker-mutator/api
dependency for the types and basic helper functionality. Install it with: npm install @stryker-mutator/api
.
Next, you need to create a class that is the actual plugin. For example:
import { Transpiler } from '@stryker-mutator/api/transpile';
import { File, StrykerOptions } from '@stryker-mutator/api/core';
class FooTranspiler implements Transpiler {
public transpile(files: ReadonlyArray<File>): Promise<ReadonlyArray<File>> {
// TODO: implement
}
}
In this example, a Transpiler plugin is constructed. Each plugin kind has it's own interface, so it's easy to create.
After that, you're ready to declare your plugin.
You can either declare it as a factory method or a class.
A class example:
import HtmlReporter from './HtmlReporter';
import { PluginKind, declareClassPlugin } from '@stryker-mutator/api/plugin';
export const strykerPlugins = [
declareClassPlugin(PluginKind.Reporter, 'html', HtmlReporter)
];
A factory method example:
import { declareFactoryPlugin, PluginKind } from '@stryker-mutator/api/plugin';
import { babelTranspilerFactory } from './BabelTranspiler';
export const strykerPlugins = [
declareFactoryPlugin(PluginKind.Transpiler, 'babel', babelTranspilerFactory)
];
Stryker uses typed-inject as a dependency injection framework. You can use it as well in your plugin
See this example below. Here, a Logger
, StrykerOptions
and the produceSourceMaps
boolean is injected.
import { Transpiler } from '@stryker-mutator/api/transpile';
import { File, StrykerOptions } from '@stryker-mutator/api/core';
import { tokens, commonTokens } from '@stryker-mutator/api/plugin';
class PassThroughTranspiler implements Transpiler {
public static inject = tokens(commonTokens.options, commonTokens.produceSourceMaps);
public constructor(private log: Logger, options: StrykerOptions, produceSourceMaps: boolean) {
public transpile(files: ReadonlyArray<File>): Promise<ReadonlyArray<File>> {
this.log.info('called with %s', files);
return files;
}
}
This is type-safe. When you declare your plugin, TypedInject will validate that you don't inject something that cannot be resolved at runtime.
If you need more help, please let us know on gitter