How to integrate the TypeScript compiler into a Gradle build

When you start using TypeScript, the statically typed superset of JavaScript, you probably want to integrate the TypeScript compiler into your build process.
In my case, the application I’m working on is built using Gradle.
In this blog post I will show you how you can integrate TypeScript into your own Gradle build script.

The approach of this article leverages the TypeScript command line compiler, so the compiler (I’m using v0.9.5) must be installed on the target machine.

Integrating the TypeScript compiler into your Gradle build

First of all, we need to apply the base plugin of Gradle. If you are already applying a plugin that uses the base plugin (e.g. the java plugin), you can skip this step.

apply plugin: "base"

Next, we define a TsCompileTask class that calls the TypeScript compiler. It extends DefaultTask.
We define two properties:

  • source, a set of input files or directories to compile, which is annotated with the InputFiles annotation.
  • outputDir, a File defining the target directory for the generated JavaScript files, which is annotated with the OutputDirectory annotation.

We implement a method with the TaskAction annotation. It contains the code to collect all the source files and to hand them over (including compiler flags) to the compiler executable.

public class TsCompileTask extends DefaultTask {

	@InputFiles
	Set<file> source = [] as Set;

	@OutputDirectory
	File outputDir;

	@TaskAction
	void compile() {
		println "compiling TypeScript files..."
		project.exec {
			executable = "tsc"
			List<file> files = source.collect { File source ->
				if(!source.isDirectory())
					return source
				return project.fileTree(source) {
					include "**/*.ts"
				}.files
			}.flatten()

			args "--outDir"
			args outputDir.toString()
			args files
		}
	}
}

To use the task class, we configure the task with input and output directories.

task tsCompile(type:TsCompileTask) {
	source += file("src/main/ts")
	outputDir = file("$buildDir/ts")
}

Here is the final build script that provides the preconfigured tsCompile task.

apply plugin: "base"

public class TsCompileTask extends DefaultTask {

	@InputFiles
	Set<file> source = [] as Set;

	@OutputDirectory
	File outputDir;

	@TaskAction
	void compile() {
		println "compiling TypeScript files..."
		project.exec {
			executable = "tsc"
			List<file> files = source.collect { File source ->
				if(!source.isDirectory())
					return source
				return project.fileTree(source) {
					include "**/*.ts"
				}.files
			}.flatten()

			args "--outDir"
			args outputDir.toString()
			args files
		}
	}
}

task tsCompile(type:TsCompileTask) {
	source += file("src/main/ts")
	outputDir = file("$buildDir/ts")
}

In the example above, all TypeScript source files in the src/main/ts directory will be compiled to the ts directory of the build directory ($buildDir/ts).
You can adjust this configuration to match your needs.

As we are using the InputFiles annotation, Gradle will compile the TypeScript files only if necessary. If no source files have changed, Gradle will skip the compilation (indicated by a UP-TO-DATE message).

Integrating the compiled files into a WAR file

If you are integrating TypeScript into a Java web application, you can easily integrate the compiled files into the WAR file.
All you have to do is to configure the war task to pick uo the compiled files.
In the example below, the compiled files will be put into the js directory in the WAR file.

apply plugin: "war"

war {
	into("js") {
		from tsCompile.outputs
	}
}
Short URL for this post: http://wp.me/p4nxik-1K9
This entry was posted in Build, config and deploy, Web as a Platform and tagged , , . Bookmark the permalink.

Leave a Reply