Setting up tsconfig with spec/test folder

Solution 1:

I ended up defining multiple config files and use extends to simplify them.

Say I have two files: tsconfig.json and tsconfig.build.json

// tsconfig.json
{
  ...
  "exclude": [...]
}

// tsconfig.build.json
{
  ...
  "files": [ "typings/index.d.ts", "src/index.ts" ]
}

This way, I can have fine control on what to build (using tsc -p tsconfig.build.json) and what the ts language service (IDE) handles.

UPDATE: now as my projects grow, I ended up having more config files. I use the "extend" feature that is now available in TypeScript:

// tsconfig.base.json
{
  // your common settings. Mostly "compilerOptions".
  // Do not include "files" and "include" here,
  // let individual config handles that.
  // You can use "exclude" here, but with "include",
  // It's pretty much not necessary.
}

// tsconfig.json
{
  // This is used by `ts language service` and testing.
  // Includes source and test files.
  "extends": "./tsconfig.base.json",
  "atom": { ... },
  "compilerOptions": {
    // I set outDir to place all test build in one place,
    // and avoid accidentally running `tsc` littering test build to my `src` folder.
    "outDir": "out/spec"  
  }
  "include": [ ... ]
}

// tsconfig.commonjs.json or tsconfig.systemjs.json or tsconfig.global.json etc
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    // for some build this does not apply
    "declaration": true/false,
    "outDir": "dist/<cjs, sys, global, etc>",
    "sourceRoot": "..."
  },
  // Only point to typings and the start of your source, e.g. `src/index.ts`
  "files": [ ... ],
  "include": [ ... ]
 }

Solution 2:

Here is a detailed solution to manage sources and tests:

  • compilation includes sources and tests folders/files
  • build includes only sources
  • IDE (VSCode, ...)

Config

The solution is based on 2 tsconfig.json files as mentioned in other answers.

The main ./tsconfig.json (used for compilation and IDE):

{
  "compileOptions": {
    "module": "commonjs"
    "outDir": "dist"
  },
  "include": [
    "spec/**/*.spec.ts"
  ],
  "files": [
    "src/index.ts"
  ]
}

The second ./tsconfig-build.json (used for build):

{
  "extends": "./tsconfig.json",
  "exclude": [
    "spec/**/*.spec.ts"
  ]
}

Note: we exclude test files that have been included previously

Build

Build command: tsc -p tsconfig-build.json

Or npm run build if script is added in package.json:

{
  "scripts": {
    "build": "tsc -p tsconfig-build.json",
}

Solution 3:

This is somewhat dependent on whatever testing framework you're using but I like to use ts-node to compile my test files. Using mocha, your npm test script might look like:

"mocha": "mocha test/ --compilers ts:ts-node/register --recursive"

In your tsconfig.json, make sure to remove the rootDir option.

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "removeComments": true,
        "sourceMap": true,
        "outDir": "lib"
    },
    "include": [
        "src/**/*.ts"
    ],
    "exclude": [
        "node_modules",
        "lib",
        "typings/**"
    ]
}

When you try to run typescript with rootDir set to src or whatever the base folder for your application code is, it'll disallow any compilation in a directory that sits outside, such a tests. Using ts-node, you can easily keep everything separate without having to have separate TypeScript configuration files.

Solution 4:

I think you should not use 'files' option in your config. Instead you can exclude unwanted files and have it like this:

{ 
    "compilerOptions": { 
        "module": "commonjs", 
        "outDir": "dist"
    },
    "exclude": [
        "node_modules",
        "dist",
        "typings/browser.d.ts",
        "typings/browser/**"
    ]
} 

This will preserve your original structure in the 'dist' folder without mixing tests and app js files:

--dist
----spec
-------....
----src
-------....