This is used to aggregate all the plugins and expose them to the bundler.
Note
We use unplugin to support many different bundlers.
These are the plugins that are used internally by the factory. Most of the time they will interact via the global context.
Send some analytics data to Datadog internally.
Will send a log at the beginning of a build.
An internal queue for async actions that we want to finish before quitting the build.
This will populate
context.buildwith a bunch of data coming from the build.
A very basic report on the currently used bundler.
It is useful to unify some configurations.
Custom hooks for the build-plugins ecosystem.
If your plugin is producing something that will be shared with other plugins,
you should create a custom hook to let other plugins use it as soon as it is available.
Adds repository data to the global context from the
buildStarthook.
This is used to inject some code to the produced bundle.
Particularly useful :
- to share some global context.
- to automatically inject some SDK.
- to initialise some global dependencies.
- ...
A custom hook for the true end of a build, cross bundlers.
If you need to log anything into the console you'll have to use the global Logger.
You can get a logger by calling context.getLogger(PLUGIN_NAME);.
// ./packages/plugins/my-plugin/index.ts
[...]
export const getMyPlugins = (context: GlobalContext) => {
const log = context.getLogger(PLUGIN_NAME);
log.debug('Welcome to my plugin');
[...]
};Then you can either use one of the level logger methods:
logger.warn('This is also a warning');
logger.error('This is an error');
logger.info('This is an info');
logger.debug('This is a debug message');You can also create a "sub-logger" when you want to individually identify logs from a specific part of your plugin.
Simply use log.getLogger('my-plugin') for this:
export const getMyPlugins = (context: GlobalContext) => {
const log = context.getLogger(PLUGIN_NAME);
log.debug('Welcome to the root of my plugin');
return [
{
name: 'my-plugin',
setup: (context: PluginContext) => {
const subLog = log.getLogger('my-plugin');
subLog.info('This is a debug message from one of my plugins.');
},
},
];
};The time logger is a helper to log/report the duration of a task. It is useful to debug performance issues.
It can be found on your logger's instance.
const logger = context.getLogger('my-plugin');
const timer = logger.time('my-task', {
// Whether to start the timer immediately, at the given timestamp or not at all. Defaults to `true`.
start: boolean | number,
// Whether to log the timer or not when it starts and finishes. Defaults to `true`.
log: boolean,
// The log level to use. Defaults to `debug`.
level: LogLevel,
// Tags to associate with the timer. Defaults to `[]`.
tags: string[],
});Pause/resume the timer.
timer.pause(timeOverride?: number);
// [... do stuff ...]
timer.resume(timeOverride?: number);
// [... do more stuff ...]
timer.end(timeOverride?: number);Add tags to the timer or to active spans.
// Add tags to the entire timer
timer.tag(['feature:upload', 'operation:compress']);
// Add tags to the current active span only
timer.tag(['step:initialize'], { span: true });Use it with a specific log level.
const timer = log.time('my-task', { level: 'error' });
// [... do stuff ...]
timer.end();Initialize with tags.
const timer = log.time('my-task', { tags: ['type:report', 'priority:high'] });
// [... do stuff ...]
timer.end();Make it not auto start.
const timer = log.time('my-task', { start: false });
// [... do stuff ...]
// This will start the timer.
timer.resume();
// [... do more stuff ...]
timer.end();Make it not log.
const timer = log.time('my-task', { log: false });
// [... do stuff ...]
timer.end();All the timers will be reported in context.build.timings, with all their spans and total durations.
{
"timings": [
{
"label": "my-task",
"pluginName": "my-plugin",
"spans": [
{
"start": 1715438400000,
"end": 1715438401000,
"tags": ["step:initialize"]
}
],
"tags": ["feature:upload", "operation:compress", "plugin:my-plugin", "level:debug"],
"total": 1000,
"logLevel": "debug"
}
]
}A global, shared context within the build plugins ecosystem.
It is passed to your plugin's initialization, and is mutated during the build process.
type GlobalContext = {
// Trigger an asynchronous custom hook.
asyncHook: async (name: string, ...args: any[]) => Promise;
// Mirror of the user's config.
auth?: {
apiKey?: string;
appKey?: string;
};
// Available in the `buildReport` hook.
build: BuildReport;
// Available in the `bundlerReport` hook.
bundler: BundlerReport;
buildRoot: string;
env: string;
getLogger: (name: string) => Logger;
// Available in the `git` hook.
git?: Git;
// Trigger a synchronous custom hook.
hook: (name: string, ...args: any[]) => void;
inject: Injection;
// The list of all the plugin names that are currently running in the ecosystem.
pluginNames: string[];
// The list of all the plugin instances that are currently running in the ecosystem.
plugins: Plugin[];
// Send a log to Datadog.
sendLog: ({ message: string, context?: Record }) => Promise;
// The start time of the build.
start: number;
// The version of the plugin.
version: string;
}
Note
Some parts of the context are only available after certain hooks:
- some helper functions,
asyncHook,hook,injectandqueueare available in theinithook. buildRootis available in thebuildRoothook.context.bundler.rawConfigandcontext.bundler.outDirare available in thebundlerReporthook.context.build.*is available in thebuildReporthook.context.git.*is available in thegithook.
This hook is called when the factory is done initializing.
It is useful to initialise some global dependencies and start using helper functions that are attached to the context.
Happens before any other hook.
{
name: 'my-plugin',
init(context: GlobalContext) {
// Do something with the data
}
}