13

My package looks like this:

┌ tsconfig.json
├ src/
│ ├ index.ts         (import './dependence.ts')
│ └ dependence.ts
└ example/
  ├ index.html
  └ script.ts        (import '../src/index.ts')

I would like

  • ./src/*.ts to be compiled in ./dist/*.js
  • ./example/*.ts to be compiled in ./example/*.js

after running tsc, I expect my package to look like this:

┌ tsconfig.json
├ src/
│ ├ index.ts         (import './dependence.ts')
│ └ dependence.ts
├!dist/
│ ├!index.js         (import './dependence.js')
│ └!dependence.js
└ example/
  ├ index.html
  ├ script.ts        (import '../src/index.ts')
  └!script.js        (import '../dist/index.js')

I'm a little confused about all tsconfig options.
I have tried many things with options like baseUrl, paths, rootDir, outDir, rootDirs, ... without success.

2
  • What do these exclamation points mean? Is that to draw attention to the change? Commented May 22, 2023 at 21:08
  • 2
    @DanielKaplan yes, they are there to highlight the files that have been generated Commented May 22, 2023 at 23:24

1 Answer 1

15
+100

Easy. Use separate tsconfig files, one in each source dir to establish each as a separate project and use Typescript project references to establish the dependency between the example project and the src project.

  1. src/tsconfig.json:
{
    "compilerOptions": {
       "rootDir": ".",
       "outDir": "../dist/",
       "composite": true  // required if another project has a reference to this one.
    },
} 
  1. example/tsconfig.json:
{
    "compilerOptions": {
      "rootDir": ".",
      "outDir": ".",  // because you want example to compile in place
    },
    "references": [   // declare the dependencies
      { "path": "../src" }  
    ]
}
  1. use tsc -b instead of tsc -p for incremental (i.e. faster) builds:

    Running tsc --build (tsc -b for short) will do the following:

    • Find all referenced projects
    • Detect if they are up-to-date
    • Build out-of-date projects in the correct order

    e.g.

    • tsc -b src to just build src
    • tsc -b example will build both because of the dependency
    • tsc -b src example if you feel like being explicit
  2. if you want to share some or most settings between projects to be DRY or to enforce consistency, you can:

    • put another tsconfig in the root and move all the common settings to it.
    • change each child config to extend the root config:
      "extends": "../tsconfig.json"
      
      adjusting the path if the child config is deeper in the tree.
  3. You can take step 4 one further and use it as "a 'solution' tsconfig.json", as described in this section of the Project References documentation. This should enable you to build everything from your overall project root with tsc -b .

I think I covered everything you need. There's a detailed explanation of outDir and project references in this answer. Let me know if I'm missing something or if you have any questions.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks! This work with the two tsconfig.json files but if I add the 3rd one in the root directory, root settings are ignored. Which command should I run? Should I add references between the root conf and the child confs?
@Yukulélé, Root settings are not ignored. Settings closest to the code (i.e. in the same directory) will override any settings farther up the directory tree. So if you want common settings, you need to take out the settings in the non-root configs that you want to inherit from the root config. It's all in the docs. You should read them.
References are only for projects that have a build dependency on another project. If you only use the root config for shared settings, then no, it doesn't need references. You could setup the root config to be a build target, with src and example as dependencies, and just say tsc -b . to build the root. But you really should understand how all this works before setting that up. Please read the docs. Otherwise keep it simple as I helped you with above.
@Yukulélé my bad! I forgot that tsconfig doesn't automatically inherit configs up the tree (like some other systems). I updated my answer... See #4.
Did you read my second comment and follow the directions in the handbook? i.e. did you "set files to an empty array" in the root config. Did you set up the composite and references properties correctly (all three of your tsconfigs will need different combinations of these two).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.