Creating a Compiler Plugin
CommandKit Compiler Plugins are a powerful way to extend the functionality of your CommandKit application by modifying the way CommandKit compiles your application. They are used to add new features or modify existing ones. For example, you can use a compiler plugin to transform the source code itself (e.g. CommandKit's use cache
or use macro
directives).
Creating a Compiler Plugin
Using rolldown plugins
You can also use rolldown plugins as compiler plugins. This is useful if you want to use rolldown plugins to transform your source code.
import { defineConfig } from 'commandkit';
import { someRolldownPlugin } from 'some-rolldown-plugin';
export default defineConfig({
rolldownPlugins: [someRolldownPlugin()],
});
Using custom compiler plugins
You can also create custom compiler plugins by extending the CompilerPlugin
class. This is useful if you want to create a custom plugin that modifies the way CommandKit compiles your application.
import { defineConfig } from 'commandkit';
import { CompilerPlugin } from 'some-commandkit-compiler-plugin';
export default defineConfig({
plugins: [someCompilerPlugin()],
});
Creating a Compiler Plugin
To create a compiler plugin, you need to create a new class that extends the CompilerPlugin
class. This class should implement the transform
method, which is called by CommandKit to transform the source code. The transform
method should return the transformed source code.
import {
CompilerPlugin,
MaybeFalsey,
PluginTransformParameters,
TransformedResult,
} from 'commandkit';
export class MyPlugin extends CompilerPlugin {
// this is the name of the plugin
public readonly name = 'my-plugin';
public async activate(ctx: CompilerPluginRuntime): Promise<void> {
// this is where you can keep initialization logic
}
public async deactivate(ctx: CompilerPluginRuntime): Promise<void> {
// this is where you can keep cleanup logic
}
public async transform(
params: PluginTransformParameters,
): Promise<MaybeFalsey<TransformedResult>> {
const { contents } = params;
// this is just an example, you can do whatever you want with the contents
const transformedContents = contents.replace(
/console\.log/g,
'console.warn',
);
// return the transformed contents
return {
contents: result,
loader: params.loader,
};
}
}
Extending commandkit templates
CommandKit templates are a way to autogenerate files and other contents through commandkit create
command. CommandKit by default comes with command
and event
templates. Compiler plugins can register custom templates to be used by the commandkit create
command.
import { CompilerPlugin, CompilerPluginRuntime } from 'commandkit';
export class MyPlugin extends CompilerPlugin {
public readonly name = 'my-plugin';
public async activate(ctx: CompilerPluginRuntime): Promise<void> {
// Registers `commandkit create event <name> <path>` template
ctx.registerTemplate('event', async (args: string[]) => {
const [name, path] = args;
const template = `
export default async function on${name[0].toUpperCase() + name.slice(1)}() {
console.log('${name} event fired!');
};
`.trim();
await writeFile(join(path, 'event.ts'), template);
});
}
public async deactivate(ctx: CompilerPluginRuntime): Promise<void> {
// remove the template from the registry when the plugin is deactivated
ctx.unregisterTemplate('event');
}
}
The registerTemplate
method must be called inside the activate
method, and the unregisterTemplate
method must be called inside the deactivate
method.
Plugins may override the default templates by registering their own templates with the same name.