Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript compiler options - trying to get "flat" output to outDir

I have a src directory with my source code and unit tests, and a test directory containing a separate speed test.

When I build my project with tsc, I get a directory structure like this:

dist/
  src/
    index.js
    ...
  test/
    speed-test.js

I'd prefer, however, to get "flat" output to my dist directory, like this:

dist/
  index.js
  ...
  speed-test.js
  ...

If I delete speed-test.ts from the test directory, tsc doesn't add a src directory to dist. The extra directory structure only gets added when there's a need (or at least, when tsc decides there's a need) to distiguish the sources of the compiled code.

I'm sure that's very useful at times to avoid file name conflicts, but that's not important for me in this case, and I'd prefer not to get this extra "help".

Here's my tsconfig.json:

{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "outDir": "./dist",
    "noImplicitAny": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "noImplicitReturns": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "resolveJsonModule": true,
    "allowSyntheticDefaultImports": true
  }
}

I tried adding a "rootDirs" options of ["src", "test"], but that didn't help.

Is there anyway for me to get the output structure I'm looking for?

like image 599
kshetline Avatar asked Sep 30 '19 17:09

kshetline


People also ask

What is TSC command in TypeScript?

Running tsc locally will compile the closest project defined by a tsconfig. json , you can compile a set of TypeScript files by passing in a glob of files you want. sh. # Run a compile based on a backwards look through the fs for a tsconfig.json. tsc.

What compiler does TypeScript use?

Compiler. The TypeScript compiler, named tsc , is written in TypeScript. As a result, it can be compiled into regular JavaScript and can then be executed in any JavaScript engine (e.g. a browser). The compiler package comes bundled with a script host that can execute the compiler.

What is TSC TypeScript compiler?

TypeScript is a superset of Javascript and supports the Object-Oriented Concept. In TypeScript, whenever we compile our code of file type . ts it gets converted into a . js file by using tsc compiler. It means that the TypeScript code get trans-compiled into plain JavaScript.


1 Answers

Why nested output folders inside outDir?

If I delete speed-test.ts from the test directory, tsc doesn't add a src directory to dist.

TypeScript determines one parent folder containing all your source files. This folder is set as rootDir in tsconfig.json or calculated automatically by the compiler.

For example, if you include ./test/speed-test.ts in the compilation (./ = project root), which imports other source files from ./src, its parent folder will be ./ and the compiled version will have the path <outDir>/test/speed-test.js.

How to make the output folder flat?

We need two things: 1.) TS Project References 2.) rootDirs.

Project References will create independent sub-projects, each with its own rootDir configuration. This has several advantages like increased compile-time performance. And we can structure the output folder (outDir) more flexibly.

rootDirs will tell the compiler that src and test are merged to a single folder in the course of the compilation. Now we can write import paths, that are validated from the compiler as if both would form a single folder. Consider ./test/speed-test.ts needs ./src/main.ts - you then can write following import with existing folder structure:

// ./test/inside speed-test.ts
import {something} from "./main" // main.ts is still inside "./src"

Note: TypeScript doesn't re-write import paths, rootDirs only affects the input type validation.

tldr: Code

.
├── package.json
├── src
│   ├── main.test.ts
│   ├── main.ts
│   └── tsconfig.json
├── test
│   ├── speedtest.ts
│   └── tsconfig.json
├── tsconfig-base.json
└── tsconfig.json

./src/main.ts:

export const foo = "foo"

./src/tsconfig.json:

{
  "extends": "../tsconfig-base.json",
  "compilerOptions": {
    "outDir": "../dist",
    "composite": true, // needed for references sub-projects
    "rootDir": ".",
    "tsBuildInfoFile": "../dist/srcbuildinfo"
  }
}

./test/speedtest.ts:

import { foo } from "./main"; // important(!): pretend, `src/main` is same folder
console.log(foo);
// ... do performance tests ...

./test/tsconfig.json:

{
  "extends": "../tsconfig-base.json",
  "compilerOptions": {
    "outDir": "../dist",
    "rootDir": ".",
    "composite": true, 
    "tsBuildInfoFile": "../dist/testbuildinfo",
    "rootDirs": ["../src", "../test"] // important (!)
  },
  "references": [
    {
      "path": "../src" // test project depends on src
    }
  ]
}

./tsconfig.json:

{
  "files": [], // this root tsconfig just exists to compose sub-projects
  "references": [
    {
      "path": "./src"
    },
    {
      "path": "./test"
    }
  ]
}

tsconfig-base.json contains all own config values. Compiling with tsc -b -v will place all files under ./dist, same import paths as specified in the source:

dist
├── main.d.ts
├── main.js
├── main.test.d.ts
├── main.test.js
├── speedtest.d.ts
├── speedtest.js
├── ...

Lastly, if you need more infos on Project References - here is another code example.

like image 62
ford04 Avatar answered Oct 22 '22 01:10

ford04