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:
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):
Run
bit compile sample-component
to compile the component using the compiler.
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 }]; }
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, }; }
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), }); }, };
Method Signature | Description |
---|---|
getDistDir(): string | the dist directory of the compiled files (relative path from the component root dir). |
version(): string | the compiler version (e.g, '1.0.0') |
isFileSupported(filePath: string): boolean | determines whether the compiler supports the file extension. |
getDistPathBySrcPath(srcPath: string): string | the dist path of a source file (e.g., src/index.ts -> dist/index.js ). |
shouldCopyNonSupportedFiles: boolean | should the compiler copy files that are unsupported by it, to the dist directory |
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):
- Create a new env or use an existing one.
- Set the compiler as the env's compiler.
- Create a component using that env or set an existing component to use that env.
Learn about debugging components in the workspace in this blog.
Run the following to compile the component during development (in the workspace):
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:
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:
The output should include the name of your compiler task:
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:
Run the following to get the path for capsules' root directory:
Head over to the capsule directory and search for the compiled files. For example: