Create a compiler

Bit compilers compile component source files during the component development and during the component build process. They are often used to integrate popular compilers such as Typescript, Babel, and Sass into Bit, but can also be used to implement custom compilers.

Run the following to fork a demo compiler that you can use as a template for your own compiler:

$bit
Copiedcopy

Alternatively, run the following to create a workspace with a compiler, an env that uses the compiler, and a sample component that uses that env (replace my-org.my-scope with your own bit.cloud org/username and scope name):

$bit
Copiedcopy

Run bit compile sample-component to compile the component using the compiler.

Compilation during development

Implement the transpileFile method to compile component source files during development. The component source files are provided to the compiler as a string (fileContent). The compiler should return a corresponding array of compiled files, each with its own content and path (for example, index.ts --> index.js, index.d.ts, index.js.map).

transpileFile( fileContent: string, options: TranspileFileParams ): TranspileFileOutput {
  const filePath = options.filePath;
  // implement the compiler logic here
  return return [{ outputText: compiledContent, outputPath: compiledRelPath }];
}
CopiedCopy

Compilation during build

Implement the build method to compile component source files during build.

The build method is similar to a standard build task. It receives the entire build context and should return an array of artifact description (the compiled/copy files) and build metadata (compilation timestamps, errors, warnings, etc).

build receives the entire build context. However, our compiler only needs to go over un-compiled components, not their (already compiled) dependencies, which are also part of the "network of capsules" that participate in the build process. Use the context.capsuleNetwork.getCapsulesToCompile() method to get only the relevant capsules.

The build implementation should compile all the relevant files by iterating over each capsule (isolated component), and again over each supported file in these capsules. Note that capsules contain the filepaths, but not their content (the reading of the files should be implemented by you).

async build(context: BuildContext): Promise<BuiltTaskResult> {
    const componentsResults = await this.compileCapsules(
      context.capsuleNetwork
    );
    return {
      /**
       * the compiler description of artifacts (the compiled/copied files)
       */
      artifacts: [
        {
          generatedBy: this.id,
          name: 'typescript-compiled-output',
          /**
           * a glob pattern to determine which files should be stored in the component version (snap).
           * in this case, all files compiled or copied to the dist dir should be stored as the component artifacts.
           * @see https://bit.dev/reference/build-pipeline/implement-build-task#save-new-artifacts-in-the-component-version
           */
          globPatterns: [`${this.getDistDir()}/**`],
        },
      ],
      /**
       * compiler build metadata (timestamps, errors, warnings, etc)
       */
      componentsResults,
    };
  }
CopiedCopy

To make the compiler available as a standard build task that can be registered by env, wrap it with the compiler-task build task. The compiler-task wraps the compiler build method with a standard build task interface, and some additional logic that's required for compilation during build.

/* @filename: ts-compiler-task.ts */

import { TaskHandler } from '@teambit/builder';
import { CompilerTask } from '@teambit/compilation.compiler-task';
import { TSCompiler } from './ts-compiler';

export type TypeScriptTaskOptions = {
  description?: string;
  name?: string;
};

export const TypescriptTask = {
  from: (options: TypeScriptTaskOptions): TaskHandler => {
    const name = options.name || 'TypescriptCompile';
    const description =
      options.description || 'compiles components using Typescript';

    return CompilerTask.from({
      name,
      description,
      compiler: TSCompiler.from(options),
    });
  },
};
CopiedCopy

Additional methods and properties

Method SignatureDescription
getDistDir(): stringthe dist directory of the compiled files (relative path from the component root dir).
version(): stringthe compiler version (e.g, '1.0.0')
isFileSupported(filePath: string): booleandetermines whether the compiler supports the file extension.
getDistPathBySrcPath(srcPath: string): stringthe dist path of a source file (e.g., src/index.ts -> dist/index.js).
shouldCopyNonSupportedFiles: booleanshould the compiler copy files that are unsupported by it, to the dist directory

Use the compiler

Compilers are used by components via the components' envs. To use your compiler, follow these steps (or use the workspace starter at the top of this page):

  1. Create a new env or use an existing one.
  2. Set the compiler as the env's compiler.
  3. Create a component using that env or set an existing component to use that env.

Test the compiler

Learn about debugging components in the workspace in this blog.

Compilation during development

Run the following to compile the component during development (in the workspace):

$bit
Copiedcopy

Learn more about running the compiler in the Running compilers page.

When compiling components in the workspace, the compilation output is written into the dist directory of the component's corresponding package. For example:

└── my-workspace └── node_modules └── @my-org └── my-scope.my-component ├── dist │ ├── index.js │ └── my-component.js ├── index.ts ├── package.json └── my-component.ts

Compilation during build

When compiling components during build, the compilation output is written into the dist directory of the component's corresponding package in the capsule.

Verify your compilation task is set correctly by listing the relevant component build tasks:

$bit
Copiedcopy

The output should include the name of your compiler task:

Build Pipeline Tasks:
teambit.harmony/aspect:CoreExporter
teambit.compilation/compiler:MyCompiler
...

Run the following to tun the compilation in the capsule. Specify the compilation task name to skip other tasks:

$bit
Copiedcopy

Run the following to get the path for capsules' root directory:

$bit
Copiedcopy

Head over to the capsule directory and search for the compiled files. For example:

└── my-org.my-scope_mt-component@0.0.1 ├── dist │ ├── my-component.js │ └── index.js ├── index.ts ├── package.json └── my-component.ts