To create a component with a custom build task, you can create a Bit App Component:
bit create bit-app my-build-task
Alternatively, to add a build task to an existing component, create a new file to the component and name it with the *.bit-app.ts
suffix.
Add an async
function named build
that accepts AppBuildContext
. Bit will execute it during build
.
The following example shows how to add an esbuild task and saving results as part of the component artifacts:
// component-name.bit-app.ts import type { AppBuildContext, AppBuildResult } from '@teambit/application'; import { build } from 'esbuild'; export async function build(context: AppBuildContext): Promise<AppBuiltResult> { const rootPath = context.capsule.path; const outputDir = join(rootPath, 'build'); const result = await build({ entryPoints: [rootPath], bundle: true, platform: 'node', outfile: outputDir, }); return { errors: result.errors.map((error) => { return new Error(error.detail); }), artifacts: [ { name: this.artifactName, globPatterns: [outputDir], }, ], }; }
To run the build task:
bit compile bit build component-name
Learn more on building app components.
Reusing build task between Bit Components
You can expose a build
function from a Bit Component, making the task reuseable.
// Reuse in another Bit Component's "*.bit-app.ts" file import { build } from '@acme/platform.tasks.my-build-task'; export default { build }
Build tasks defined in an Dev Environment run for components configured with that Dev Environment.
The build pipeline is defined in the *.bit-env.ts
file, for example:
// env-name.bit-env.ts class MyEnv extends NodeEnv { build() { return Pipeline.from([ TypescriptTask.from({ tsconfig: this.tsconfigPath, types: this.types, typescript, }), VitestTask.from({ config: require.resolve('./config/vitest.config.mjs'), }) ]); } }
You can use any of the official build tasks in your pipelines:
Generate a new Bit Component with a basic build task:
bit create build-task my-build-task
In your Development Environment add the component as a dependency and add the task to any of the pipelines:
// env-name.bit-env.ts import { MyBuildTask } from '@acme/tasks.my-build-task' class MyEnv extends NodeEnv { /** * Regular build pipeline. In most cases you may want to use this option. */ build() { return Pipeline.from([ MyBuildTask ]); } /** * Running when releaseing a new semver for a component. This is usually for production releases. */ tag() { return Pipeline.from([ // MyBuildTask ]); } /** * Running when releasing component snap. Most teams use this for staging environments. */ snap() { return Pipeline.from([ // MyBuildTask ]); } }
By default a task runs individually for each component. However, you can set a task to run for several components. Some tooling may benefit from such execution.
The below example shows how you gain access to the full list of components to build and operate on them.
import { BuildTask } from '@teambit/builder'; export class MyBuildTask implements BuildTask { readonly name = 'my build task'; execute(context: BuildTaskContext) { const capsules = context.capsuleNetwork; // build components in parrlel await Promise.all(capsules.map((capsule) => fs.write(/** example */) )) return { componentResults: [], artifacts: [], } } }
Reference cross-component build tasks
Many existing plugins already benefit from this capability, for example TypeScript, Webpack, ESLint and Vitest.
Build tasks may generate artifacts. You can store them as part of the component version.
For example:
async execute(context: BuildContext): Promise<BuiltTaskResult> { const capsules = context.capsuleNetwork.seedersCapsules; capsules.forEach((capsule) => { const componentName = capsule.component.id.name; fs.writeFileSync( path.join(capsule.path, 'output.my-artifact.txt'), `The component name is ${componentName}` ); }); return { artifacts: [ { generatedBy: this.aspectId, name: this.name, // The glob pattern for artifacts to include in the component version globPatterns: ['**/*.my-artifact.txt'], }, ], }; } }
Get breakpoint debugging for build tasks by setting your IDE launch configuration, see Debugging backend components in Bit workspaces.
To use a build task, register to the build
function of your env. One the task is registered, it will run as part of the build process of the components that use that env.
Run only the task you built by passing it's name:
bit build --tasks MyBuildTask
Running snap
and tag
build tasks
Use the --include-snap
or --include-tag
flags for the build
command in case your task was register to any of these pipelines.
To skip capsule generation and repeating build tasks, use the --reuse-capsules
flag (this can also be combined with the --tasks
flag):
bit build --tasks MyBuildTask --reuse-capsules
Get a list of all tasks configured for a component with the following command:
bit build --list-tasks <component-id>