This section is an overview of how to create a plugin. For a complete example of a plugin go to the TypeScript plugin boilerplate project.
Plugins are bits of reusable configuration. Anything that you can do in a plugin, can also be done in your config file. You can test your ideas in a config file, and move them into a plugin when ready.
The main things that plugins can do are extending the Buidler Runtime Environment, extending the Buidler config, defining new tasks, and overriding existing ones.
To learn how to successfully extend the BRE in TypeScript, and to give your users type information about your extension, take a look at src/index.ts
in the boilerplate repo and read the Extending the BRE documentation.
Make sure to keep the type extension in your main file, as that convention is used across different plugins.
An example on how to add fields to the Buidler config can be found in src/index.ts
.
Note that all config extension's have to be optional.
To show better stack traces to your users, please consider throwing BuidlerPluginError
errors, which can be found in @nomiclabs/buidler/plugins
.
If your error originated in your user's code, like a test or script calling one of your functions, you shouldn't use BuidlerPluginError
.
Keeping startup time short is vital to give a good user experience. To do so, Buidler and its plugins delay any slow import or initialization until the very last moment. To do so, you can use lazyObject
, and lazyFunction
from @nomiclabs/buidler/plugins
.
An example on how to use them is present in src/index.ts
.
Knowing when to use a dependency
or a peerDependency
can be tricky. We recommend these articles to learn about their distinctions.
If you are still in doubt, these can be helpful:
Rule of thumb #1: Buidler MUST be a peer dependency.
Rule of thumb #2: If your plugin P depends on another plugin P2, P2 should be a peer dependency of P, and P2's peer dependencies should be peer dependencies of P.
Rule of thumb #3: If you have a non-Buidler dependency that your users may require()
, it should be a peer dependency.
Rule of thumb #4: Every peerDependency
should also be a devDependency
.
Also, if you depend on a Buidler plugin written in TypeScript, you should add it's type extensions' .d.ts
file to the files
array of tsconfig.json
.
To integrate into your users' existing workflow, we recommend plugin authors to override built-in tasks whenever it makes sense.
Examples of suggested overrides are:
compile
internal tasks.check
task.clean
task.For a list of all the built-in tasks and internal tasks please take a look at task-names.ts