Compile Setting

Matthew Manela edited this page Feb 4, 2016 · 4 revisions

This setting lets you describe in the Chutzpah.json file how to find .js files for your source files. Most people set the Compile setting mode to External which means Chutzpah will assume that you have some other process which will compile your source files. Chutzpah will just looks for the generated .js files in the path you configure. However, you can also set it to Executable mode and you then tell Chutzpah to execute a command which can compile your source files to .js files. In both cases you need to tell Chutzpah some information about what your source and destinations files (like where to find the generated .js files). Then after running the Chutzpah can associate each source file with each output file to still give the nice behavior of mapping tests back to their original files.

You should ideally configure this compile setting to use the same mechanism you have for compiling the code in your project. This will give you a nice performance gain when running Chutzpah since it will re-use the .js files you have already built. This becomes really powerful when you are taking advantage of IDE integration features that TypeScript and CoffeeScript plugins have that provide a compile on save experience. If configured correctly Chutzpah will be able to use the the output of that feature and never need to actually invoke the compile step. This results in a very fast test running experience.

Field Default Description
Extensions [] The extensions of the files which are getting compiled (e.g. .ts).
ExtensionsWithNoOutput [] The extensions of files which take part in compile but have no build output. This is used for cases like TypeScript declaration files which share a .ts extension. They have .d.ts extension and are part of compilation but have no output. You must tell Chutzpah about these if you want the SkipIfUnchanged setting to work. Otherwise Chutzpah will think these are missing output.
Paths Assumes Chutzpah.json directory for both SourcePath and OutputPath The collection of path mapping from source directory/file to output directory/file
WorkingDirectory Chutzpah.json directory This is the working directory of the process which executes the command.
Executable null The path to an executable which Chutzpah executes to perform the batch compilation. Chutzpah will try to resolve the path relative to the settings directory. But if can’t find the file there you must give it a full path.
Arguments null The arguments to pass to the command
Timeout 30000 (5 minutes) How long to wait for compile to finish in milliseconds?
SkipIfUnchanged true Skips the execution if all files Chutzpah knows about are older than all of the output files. This is defaulted to true but if you hit issues since it is possible Chutzpah might not know about all the files your compilation is using then you can turn this off. Ideally you should tell Chutzpah about these files using the references and tests settings since this setting helps Chutzpah not need to even invoke the executable if it figures out it’s not needed.
Mode Executable Determines how this compile setting is used. By default it is in Executable mode where it will require you provide an executable which Chutzpah will run if it sees it finds missing .js for input file. If you set this to External then Chutzpah will ignore the Executable, Arguments settings and assume you have some external process which is compiling. In this case Chutzpah will use the Paths settings to try to find your .js files for the input files. If it can't find them it will trace an error but still attempt to proceed.
UseSourceMaps false Attempt to find and use source maps when generating code coverage to show coverage in terms of source files instead of generated files
IgnoreMissingFiles false Determines if Chutzpah should ignore missing files and not throw

The Paths setting contains the following properties:

Field Default Description
SourcePath Chutzpah.json directory A directory that contains source files or a source file itself
OutputPath Chutzpah.json directory The directory or file that the corresponding SourcePath compiles to
OutputPathType Folder The type (file or folder) that OutputPath refers to. If not specified Chutzpah will try to take a best guess by assuming it is a file if it has a .js extension

For the Executable, Arguments and Path fields Chutzpah lets you put in variables which get expanded at execution time. These can be system environment variables like %comspec% as well as the set of Chutzpah provided variables below:

Variable Description
%chutzpahsettingsdir% The directory the chutzpah.json is in
%clrdir% The directory to the folder where the CLR is. This folder contains programs like msbuild.exe
%msbuildexe% The path to msbuild.exe
%powershellexe% That path to powershell.exe
%cmdexe% An alias for %comspec% which is the path to cmd.exe.

Integration with compilation tooling

Many users of TypeScript and CoffeeScript use IDE tooling which will already provide compilation of those files to JavaScript. In that case you should Compile Mode setting to External. This tells Chutzpah to assume that some external force is doing the compilation and that Chutzpah can just count on the JavaScript file to exist where you said they would be.

Examples

As part of this release I have included several examples which show different combinations of these settings. To see more please browse the full code of the samples.

The below samplese assume you have tsc.exe in your system path.

Using a .bat file

This sample demonstrates compiling TypeScript files in place using a .bat filed called compile.bat.

chutzpah.json

{
 "Compile": {
   "Extensions": [".ts"],
   "ExtensionsWithNoOutput": [".d.ts"],
   "Executable": "compile.bat"
  },
 "References": [
   {"Includes": ["**/src/**.ts"], "Excludes": ["**/src/**.d.ts"] }
 ],
 "Tests": [
   { "Includes": ["**/test/**.ts"], "Excludes": ["**/test/**.d.ts"] }
 ]
}

compile.bat

@echo off
tsc src/code.ts test/test.ts --sourcemap 

A couple interesting things about this example:

  • It doesn’t set the Paths since the compile.bat command is compiling them in place relative to the chutzpah.json location.
  • It gives a relative path for compile.bat since it is in the same directory as the chutzpah.json file
  • It provides .d.ts as the ExtensionsWithNoOutput since although .d.ts are part of the compilation process they produce no output. This helps Chutzpah be smart about when it needs to run the compile executable.

Using a .ps1 file

This sample demonstrates compiling TypeScript files to a out directory using a PowerShell file.

chutzpah.json

{
 "Compile": {
   "Extensions": [".ts"],
   "ExtensionsWithNoOutput": [".d.ts"],
   "Paths": [
       { "OutputPath": "_out" } 
   ],
   "Executable": "%powershellexe%",
   "Arguments": "-NoProfile %chutzpahsettingsdir%\\compile.ps1"
  },
 "References": [
   {"Includes": ["**/src/**.ts"], "Excludes": ["**/src/**.d.ts"] }
 ],
 "Tests": [
   { "Includes": ["**/test/**.ts"], "Excludes": ["**/test/**.d.ts"] }
 ]
}

compile.ps1

tsc src/code.ts test/test.ts --sourcemap --declaration --outDir out

A couple interesting things about this example:

  • It sets the OutputPath in the Paths setting to match the outDir setting in the call to tsc.exe in compile.ps1. This tells Chutzpah where to find the .js files.
  • It uses the %powershellexe% variable that Chutzpah provides to get the full path to powershell.exe in the executable field.
  • It uses the %chutzpahsettingsdir% variable in the arguments field to build the full path to the compile.ps1.

Using an MSBuild project file

This sample demonstrates compiling TypeScript files to an out directory by executing a target in an MSBuild project file.

chutzpah.json

{
 "Compile": {
   "Extensions": [".ts"],
   "ExtensionsWithNoOutput": [".d.ts"],
   "Executable": "%msbuildexe%",
   "Arguments": "/t:CompileTS ",
   "Paths": [
       { "OutputPath": "_out" } 
   ]
  },
 "References": [
   {"Includes": ["**/src/**.ts"], "Excludes": ["**/src/**.d.ts"] }
 ],
 "Tests": [
   { "Includes": ["**/test/**.ts"], "Excludes": ["**/test/**.d.ts"] }
 ]
}

compile.proj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 
 <PropertyGroup>
   <TscExe>tsc</TscExe>
 </PropertyGroup>
 
 <Target Name="CompileTS">
   <Exec Command="$(TscExe) src/code.ts test/test.ts --declaration --sourcemap --outdir out" />
 </Target>
  
 
</Project>

A couple interesting things about this example:

  • The %msbuildexe% variable that Chutzpah provides is used in the executable field to get the full path to msbuild.exe.
  • The arguments field calls the compile.proj using a specific target (CompileTS). You may notice this command doesn’t mention the project file compile.proj. In this sample it is assuming that is the only project file. If you wanted to be explicit you could change the arguments to: compile.proj /t:CompileTS

** Mapping multiple source files to one merged output file **

This sample demonstrates having chutzpah map source paths to a single output file.

chutzpah.json

{
// Batching is required to make this work if you are included your test files in the 
// merged js file. Otherwise, Chutzpah will double count tests
"EnableTestFileBatching": true,
"Compile": {
    "Extensions": [".ts"],
    "ExtensionsWithNoOutput": [".d.ts"],
    "Executable": "compile.bat",
    "UseSourceMaps": true,
    "Paths" : [

      // Map all source files to the single merged output file
      { "OutputPath": "_out/merged.js" }
    ]
},
"References": [
    {"Includes": ["*/src/*.ts"], "Excludes": ["*/src/*.d.ts"] }
],
"Tests": [
    { "Includes": ["*/test/*.ts"], "Excludes": ["*/test/*.d.ts"] }
]
}

compile.bat

@echo off
tsc.cmd src/StringLib.ts src/MathLib.ts test/StringLibTests.ts test/MathLibTests.ts --sourcemap --declaration --outFile _out/merged.js

One catch here is that this will merge multiple test files into the same output file. This would usually cause tests to get run more than once but by using the EnableTestFileBatching that issue is avoided. Another option is to merge only source files together and leave test as individual files. You can see that approach in this sample.