Skip to content

chore(create-vite): move common ts settings to base tsconfig #19228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

fmal
Copy link

@fmal fmal commented Jan 19, 2025

Description

Discussed this briefly with @ArnaudBarre on Discord, this is a proposal to avoid duplication between tsconfigs.

Some Vite starter templates with typescript include tsconfig.json that references tsconfig.app.json and tsconfig.node.json. A lot of settings between app and node configs are repeated. This PR moves shared config props to root tsconfig.json and makes tsconfig.app.json and tsconfig.node.js inherit compilerOptions from it.

This works because references are excluded from inheritance (see https://www.typescriptlang.org/tsconfig/#extends)

@fmal fmal force-pushed the fmal/patch-94089 branch from bd2a88d to 0a13901 Compare January 19, 2025 11:02
@dominikg
Copy link
Contributor

if this is motivated by DRY principles, i would ask to reconsider. Sharing compilerOptions between different config files that target different parts of an application should only be done because they are connected in that sense and you want to be able to have this file as a shared source of truth to prevent having to edit a compiler option in 2 places instead of one.

Creating a more complex extends chain is not only less tracable for human reading but also adds (a little) overhead to tsconfck for parsing these.

@dominikg
Copy link
Contributor

Also keep in mind that these starters are intended to be a minimal starting point and carry little to no opinion and avoid complexity where possible.

@alexandrsashin
Copy link

@dominikg
In some cases (for example, when libraries like Cypress use tsconfig.json and expect certain settings), errors can occur when migrating to Vite that are not immediately obvious.

cypress-io/cypress#30313 (comment)

In templates where the server-side is minimal, I would agree that it's beneficial to reuse common tsconfig.json configurations via extends.

@dominikg
Copy link
Contributor

this PR does not change the tsconfig values, it just changes how they are organized. In case cypress has an issue with our templates typescript setup please file a separate report with a reproduction.

Looking at the setup in this PR again it also introduces an indirect loop where a referenced tsconfig extends the config it was referenced from. see aleclarson/vite-tsconfig-paths#132 (comment) for my opinion on a setup like this.

There's just too much complexity in this approach for a basic starter setup and a little duplication is better in this case, easier to read and understand for humans, less hassle for tools to deal with, less prone to breaking something in the node config when someone adjusts the app config etc.

@alexandrsashin
Copy link

@dominikg
After your detailed explanation, I now better understand the reasoning behind the solution. I like it.

However, in the real world, "extends": "./tsconfig.json" and "extends": "../../tsconfig.json" are quite common.
For example, in templates for React Router with a custom server (https://github.com/remix-run/react-router-templates/blob/main/node-custom-server/tsconfig.vite.json)

{
  "extends": "./tsconfig.json",
  "include": [
    ".react-router/types/**/*",
    "app/**/*",
    "app/**/.server/**/*",
    "app/**/.client/**/*",
    "server/**/*"
  ],
  "compilerOptions": {
    "composite": true,
    "strict": true,
    "lib": ["DOM", "DOM.Iterable", "ES2022"],
    "types": ["vite/client"],
    "target": "ES2022",
    "module": "ES2022",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "baseUrl": ".",
    "rootDirs": [".", "./.react-router/types"],
    "paths": {
      "~/*": ["./app/*"]
    },
    "esModuleInterop": true,
    "resolveJsonModule": true
  }
}

or in monorepos (https://github.com/antonkalik/lerna-monorepo-boilerplate/blob/main/packages/vite-common/tsconfig.json)

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist",
    "declarationDir": "./dist/types"
  },
  "include": ["src/**/*.ts", "src/**/*.tsx"]
}

Maybe it would be worth adding a couple of sentences to the Vite documentation about choosing such a tsconfig.json configuration. That way, we could refer to it whenever similar questions come up.

@dominikg
Copy link
Contributor

dominikg commented Mar 2, 2025

Do you have examples of past questions around tsconfig where it is clear that vite docs are lacking? In my opinion it would be better if typescript itself had more examples/guides/best practices for users to set up their tsconfigs for different needs?

create-vite is kept minimal and unopinionated on purpose, monorepos are out of scope for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants