197

I'm fairly new to TypeScript, and right now I have .ts files in several places throughought my project structure:

app/
 |-scripts/
    |-app.ts
    |
    |-classes/
    |  |-classA.ts
    |  |-classB.ts
    |  
    |-controllers/
    |  |-controllerA.ts
    |  |-controllerB.ts
    |  
    |-otherStuff/
       |-otherstuffA.ts

Right now, when my files are compiled, they are compiled to the same directory that the .ts fles are in:

app/
 |-scripts/
    |-app.ts
    |-app.js
    |
    |-classes/
    |  |-classA.ts
    |  |-classB.ts
    |  |-classA.js
    |  |-classB.js
    |  
    |-controllers/
    |  |-controllerA.ts
    |  |-controllerB.ts
    |  |-controllerA.js
    |  |-controllerB.js
    |  
    |-otherStuff/
       |-otherstuffA.ts
       |-otherStuffA.js

While I like the way that the .js files keep the same directory structure as the .ts files, I don't want to track the .js files in my VCS, so I'd like to keep all of my JavaScript files in a separate directory tree (that I can then add to .gitignore), like so:

app/
 |-scripts/
 |  |-app.ts
 |  |
 |  |-classes/
 |  |  |-classA.ts
 |  |  |-classB.ts
 |  |  
 |  |-controllers/
 |  |  |-controllerA.ts
 |  |  |-controllerB.ts
 |  |  
 |  |-otherStuff/
 |     |-otherstuffA.ts
 |
 |-js/
    |-app.js
    |
    |-classes/
    |  |-classA.js
    |  |-classB.js
    |
    |-controllers/
    |  |-controllerA.js
    |  |-controllerB.js
    |
    |-otherStuff/
       |-otherstuffA.js

Is there a setting or option somewhere that will tell the TypeScript compiler to do this? Also, I'm not sure if it's relevant, but I am using WebStorm.

Liam
  • 27,717
  • 28
  • 128
  • 190
TheGuyWithTheFace
  • 2,615
  • 3
  • 13
  • 16
  • I think things get complicated when you have Editor Configuration/tsconfig/webpack config... ( just telling about my feeling...) – Yarco Sep 01 '17 at 04:33
  • It sounds to me like what you really want is just a .gitignore file that ignores js files. so anything like *.js should be sufficient – Patronics Dec 17 '22 at 21:47
  • 1
    @Patronics I can't speak for OP, but in my project which is still transitioning from js to ts, there are js source files alongside ts source files, and it is only the generated js files that I would want excluded from source control. So, for TypeScript to output its generated files elsewhere would be helpful. – maurice Jan 14 '23 at 21:52

9 Answers9

242

Since Typescript 1.5, this can also be set in the tsconfig.json file:

"compilerOptions": {
    "outDir": "DIRECTORY"
    ...

original answer

Use the option --outDir on tsc (configured within the File Watcher in IntelliJ)

From the command line documentation

--outDir DIRECTORY Redirect output structure to the directory.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Bruno Grieder
  • 28,128
  • 8
  • 69
  • 101
  • 2
    This is exactly what I was looking for! Thanks a lot, I can't believe I didn't see it before... – TheGuyWithTheFace Jun 27 '14 at 16:04
  • 4
    I believe that now you can also use the `--rootDir` flag to pass a common root folder to the transpiler. This avoid having it find a common root folder. – guzmonne Nov 12 '15 at 02:15
  • 2
    why does this option need to be system or amd? I don't want the build to dependent on them. – Nikos Dec 19 '16 at 23:23
  • 2
    Except, this seems to break it in 2.0? http://stackoverflow.com/a/40149682/550975 – Serj Sagan Feb 22 '17 at 03:35
  • 4
    Does this still work? It does not seem to work when building through webpack. – mattnedrich Mar 23 '17 at 22:07
  • Yes this works fine with the latest version, but obviously replace DIRECTORY with something like "build". Also as mentioned by @josh further down, don't forget to exclude that directory in the tsconfig.json file as well. – Michael Oct 06 '20 at 06:50
34

Or, add "outDir": "build"to tsconfig.json file

Qingshan
  • 388
  • 3
  • 5
  • 37
    Note: `"outDir": "build"` goes in the `"compilerOptions"` object of your tsconfig.json, not as a top-level property. – Jamie Oct 11 '16 at 19:34
  • For this to work in IntelliJ, I had to click on Typescript in the bottom right of the window, then compile, then `tsconfig.json`. Only then did the `build` folder appear. – Chris Jan 10 '23 at 20:13
9

Though these answers are correct you should consider whether you actually just want to hide your .js files from your IDE.

In Visual Studio Code, go to File > Preferences > Settings or your .vscode\settings.json file and enter:

"files.exclude": {
    "**/.git": true,
    "**/.DS_Store": true,
    "**/*.js" : {
        "when": "$(basename).ts"
    },
    "**/*.js.map": {
        "when": "$(basename)"
    }
}

The above hides .js files where a corresponding .ts file exists.

Dave Clark
  • 2,243
  • 15
  • 32
  • 2
    I know this is from a while back, but I was curious, is there an advantage to not using a build folders or were you just offering an alternative? – theaceofthespade Mar 28 '18 at 10:55
  • 1
    @theaceofthespade It is useful if you want to include or read files in your source folder relative to `__dirname`. (For example a `.graphql` schema file) – janispritzkau Feb 14 '19 at 07:55
3

Intellij Users, compile Typescript to multiple output directories

For Intellij users this may be useful. This was how I got this to work using the built in Typescript Compiler.

Environment Info

Example Directory Structure

BEFORE COMPILE
----------------------------------------
-> JS
   -> app
      -> config.js  //this is not generated
   -> libs
      -> jquery.js  //this is not generated
   -> plugins
-> TS
   -> app
      -> main.ts
   -> libs
      -> jquery.d.ts
   -> plugins
      -> somePlugin.ts

AFTER COMPILE
----------------------------------------
-> JS
   -> app
      -> config.js  //this is not generated
      -> main.js
   -> libs
      -> jquery.js  //this is not generated
   -> plugins
      somePlugin.ts
-> TS
   -> app
      -> main.ts
   -> libs
      -> jquery.d.ts    //this is where I kept my definition files
   -> plugins
      -> somePlugin.ts

Intellij Setup

  • File -> Settings -> Typescript
  • Node Interpreter: Your NodeJS Install Path
  • Compiler Version: typically located at C:\yourUserName\AppData\Roaming\npm\node_modules\typescript\lib
  • Command Line Options: -m amd -t ES6 -outDir E:\myapp\js
  • Check compile main file only and point it to your entry file. E:\myapp\ts\main.ts If this is not checked then all of your files will try to output to your outDir path.

enter image description here

khollenbeck
  • 16,028
  • 18
  • 66
  • 101
3

I setup package.json like this so that typing npm run start outputs everything to build. The source files are kept in src. The outfile is specified by --outDir build.

{
  "name": "myapp",
  "version": "0.0.1",
  "scripts": {
    "tsc": "tsc",
    "tsc:w": "tsc -w --outDir build",
    "lite": "lite-server",
    "start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
  },
  "license": "private",
  "dependencies": {
    "angular2": "2.0.0-beta.0",
    "systemjs": "0.19.6",
    "es6-promise": "^3.0.2",
    "es6-shim": "^0.33.3",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.0",
    "zone.js": "0.5.10"
  },
  "devDependencies": {
    "concurrently": "^1.0.0",
    "lite-server": "^1.3.1",
    "typescript": "^1.7.3"
  }
}

You can exclude your build directory in tsconfig.json, though it probably isn't necessary, since there is only JS there:

{
  "compilerOptions": {
    "target": "ES5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "exclude": [
    "node_modules",
    "build"
  ]
}
R891
  • 2,550
  • 4
  • 18
  • 30
  • 1
    Thanks, very important point to exclude the build directory if you choose to add that, otherwise the build and watch commands will constantly complain, due to the .d.ts files. – Michael Oct 06 '20 at 06:48
2

If you like to map the directory structure of the app/scripts folder in js, I'd suggest using the following settings for your file watcher:

Arguments: --sourcemap --outDir $ProjectFileDir$/js/$FileDirPathFromParent(scripts)$ $FileName$
Working Directory: $FileDir$
Output Paths To Refresh: $ProjectFileDir$/js/$FileDirPathFromParent(scripts)$/$FileNameWithoutExtension$.js:$ProjectFileDir$/js/$FileDirPathFromParent(scripts)$/$FileNameWithoutExtension$.js.map
lena
  • 90,154
  • 11
  • 145
  • 150
  • 1
    This indeed solves the problem with a file watcher, but since this feature is deprecated and replaced with the TypeScript Compiler, how is it done with the compiler? – Nitzan Tomer Jul 29 '15 at 20:20
0

Im using Atom with the atom-typescript extension and my tsconfig.json looks like this:

{
  "compilerOptions": {
    "outDir":"js"
  }
}
Daveman
  • 1,075
  • 9
  • 26
-1

The following command did it for me:
tsc index.ts --outDir .temp && node .temp/index.js && rm -rf .temp

code
  • 5,690
  • 4
  • 17
  • 39
  • 3
    Do you think you could explain this answer a little more? – RamenChef Oct 14 '22 at 20:45
  • `--outDir` puts the output into a directory called `.temp`. `node .temp/index.js` runs the compilation result of `index.ts`. `rm -rf .temp` deletes the `.temp` directory and all the compiled files in it. – sezanzeb Dec 02 '22 at 13:50
-2

Regarding Grunt, currently to save your dev folder project structure in production and not get an unexpected result after files have compiled, please refer to the option:

compilerOptions: { 
 rootDir: 'devFolder'
 // ...
}

See the rootDir option in official grunt-ts docs.

I hope it will help someone if they get stuck and get a weird result in production.

Maximillian Laumeister
  • 19,884
  • 8
  • 59
  • 78