Skip to content
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

Configure from package.json #32830

Open
ProjectCleverWeb opened this issue Aug 12, 2019 · 65 comments
Open

Configure from package.json #32830

ProjectCleverWeb opened this issue Aug 12, 2019 · 65 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@ProjectCleverWeb
Copy link

ProjectCleverWeb commented Aug 12, 2019

Search Terms

package.json, config, configuration, tsconfig

Suggestion

Allow package.json as an alternate source for tsconfig.json options. To be clear, I am requesting that you please re-evaluate #6590 - it has been 2 years since that issue was posted, so interests may have changed and I believe this feature holds good value.

UPDATE: 2022-04-28

Please vote how you would like to see this feature implemented here: #32830 (comment)

Use Cases

What do you want to use this for?

Provide a broader configuration support and decluttering the project root of configuration files that can easily be moved to package.json.

What shortcomings exist with current approaches?

Some users prefer to store their all their configuration files in 1 larger file. Right now, that is not an option.

Examples

Example of what the package.json would look like.

{
	"name": "example",
	"version": "1.0.0",
	"description": "This is an example",
	"license": "MIT",
	"tsconfig": {
		"compilerOptions": {
			"module": "commonjs",
			"moduleResolution": "node",
			"outDir": ".build",
			"pretty": true,
			"rootDir": "./",
			"sourceMap": true,
			"target": "ES5",
			"strict": true
		},
		"exclude": [
			"node_modules"
		],
		"include": [
			"index.ts",
			"src/**/*"
		]
	}
}

Checklist

My suggestion meets these guidelines:

  • ✅ This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • ✅ This wouldn't change the runtime behavior of existing JavaScript code
  • ✅ This could be implemented without emitting different JS based on the types of the expressions
  • ✅ This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • ✅ This feature would agree with the rest of TypeScript's Design Goals.
@RyanCavanaugh RyanCavanaugh added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript labels Aug 13, 2019
@VincentSurelle
Copy link

Actually tsconfig is one of the last to require a specific file.
Many other projects made it possible to pull configuration from package.json.

@probablykasper
Copy link

I feel like this feature is pretty standard already. Babel, ESLint, Vue and Browserslist support it, so that's 4 files that I can save from cluttering my repo. Would be great to be able to do that with tsconfig.json as well.

@dmnsgn
Copy link

dmnsgn commented Feb 1, 2020

Definitely, cosmiconfig is usually a good choice to simplify config resolution for tools.

@fishcharlie
Copy link
Contributor

Don't wanna add too much noise here. It was kinda mentioned by @dmnsgn with cosmiconfig, but I would love to see support for CommonJS configuration file support (ex. tsconfig.js with a module.exports definition).

I see the value in separating out these configurations away from the package.json so it doesn't get too bloated. Also, adding support for adding comments to the configuration file would be super valuable!!


Would be more than happy to help contribute to making this happen if at all possible (would need a bit of guidance maybe since I haven't contributed to TS before).

@ColtHands
Copy link

ColtHands commented Aug 14, 2020

Yes, this would be perfect for small projects, online env's or boilerplates/templates.

I've tried to this through, webpack plugins or ts-loader, but they all look for a specific file to read from and send into tsc. Only solution i found is to use dev build (webpack / node), read from package.json, create a file somewhere, read from it, and delete it on completion.

Maybe it is possible to mock file so tsc would think it reads a file, while its actually not doing that, but that requires some sort of prebuild node env and it loses all point of small config's.

Sorry for duplicate issue

@gang-qiu
Copy link

gang-qiu commented Sep 3, 2020

Cleaned out half a dozen config files from my project... the only one remaining is tsconfig. Hope someone makes this dream a reality!

@vimtor
Copy link

vimtor commented Oct 16, 2020

With shareable configs, this will be awesome ❤️

@ProjectCleverWeb
Copy link
Author

@RyanCavanaugh are we still awaiting more feedback or is that tag no longer accurate?

As far as implementation, it looks like this might be straightforward with cosmiconfig and it looks like some people may be willing to contribute code to get this feature if it is accepted. (Myself included)

@MartinJohns
Copy link
Contributor

it looks like this might be straightforward with cosmiconfig

You should note that the TypeScript compiler has no dependencies. :-) So using something like cosmiconfig is pretty surely a no-go.

@ProjectCleverWeb
Copy link
Author

@MartinJohns That's a good point!

I can't speak for anyone else, but I would still be willing to contribute to get this feature.

@alexweej
Copy link

A few people in my organization have been somewhat offended by the number of configuration files required in a skeleton project, compared to other language ecosystems. Being able to get rid of a physical tsconfig.json file would help us out a little bit.

@hubgit
Copy link

hubgit commented Jan 2, 2021

It would be nice to be able to at least specify a shared config as "typescript": "@sindresorhus/tsconfig" in package.json, like Prettier does.

@pgbradbury
Copy link

This would be a great addition, as others have stated, I have all my other configs in my package.json (prettier, eslint, jest, babel...). This would be the last of my config file clutter to knock on the head

@mahnunchik
Copy link

I'm looking forward for this feature.

@a-bendoraitis
Copy link

This would help for multi-repo cases, where I can easily share a configuration file. Right now i can use extends, but why clutter every project with additional file.. Other configuration files (eslint, prettier) already have this

@PatrykMilewski
Copy link

It would be nice to have this feature!

@jakeblaxon
Copy link

@RyanCavanaugh Any update on this? It doesn't seem too hard to implement, and it would be a great feature! Many of us are willing to contribute as well.

@jbergstroem
Copy link

Asked differently: are there counter-arguments as to why this would be a bad thing? Perhaps just pending a PR? One thing I can think of is that it would change assumptions made from third party tooling about where to look for said config (perhaps to the point of a "breaking feature"). Sounds manageable though.

@JCQuintas
Copy link

In my case this would help maintain monorepos where the config is stored in a single place and then new "child repos" extend it.

Currently all the child repos have a "tsconfig.json" that extends "node.tsconfig.json" or "react.tsconfig.json". So it is pretty much a dummy file. If it was in the package.json like eslint and jest, it would be arguably more readable imo, but also easier to maintain.

@William-McGonagle
Copy link

William-McGonagle commented Jan 16, 2022

I don't know if I'm speaking for anyone else when I say this, but I am working on a really tiny package right now (like less than 4 kb) and so it would be nice if I didn't have to add an extra file with boilerplate that would add to the repo size. I already have a package.json so it would be great if all the typescript config was just embedded into that (in addition to being able to create a config file named, tsconifg.json).

@ljharb
Copy link
Contributor

ljharb commented Jan 16, 2022

@William-McGonagle an extra file can be npmignored; putting it in package.json forces that weight to be part of your package. In other words, “an extra file” is the only way to minimize package size.

@William-McGonagle
Copy link

William-McGonagle commented Jan 16, 2022

@ljharb I get that the extra file can be npmignored, but I would just like the github repo itself to have fewer files. The only property I need is compilerOptions.declaration = true, so it would just be great, for simplicity's sake, to have it in the package.json file so that I don't have to have 2 extra files in my repo (a .npmignore and a tsconfig.json).

I know that it would add to the size of the npm package, but I have calculated it, and it would only add 54 bytes (unminified + unzipped), which is really an acceptable amount.

For me, it would be useful.

@cobaltt7
Copy link

In addition, it shouldn't be too hard to auto filter out extra package.json keys during build

@ljharb
Copy link
Contributor

ljharb commented Jan 16, 2022

@RedGuy12 it wouldn’t be, but precisely zero build tools do that that I’m aware of.

@ColtHands
Copy link

@ljharb but babel, or similar build tools have this as an option, you choose to have extra file and gitignore it, OR you can have an extra config file

@jakobrosenberg
Copy link

I’m suggesting they shouldn’t have the choice, because that will cause harm to downstream users.

A) Not all repos have downstream users.

B) The time lost by developers trying to navigate a cluttered root structure is infinitely more important than the millisecond it takes for your modem to download an extra byte.

@ljharb
Copy link
Contributor

ljharb commented Apr 28, 2022

I think you’re massively underestimating download counts and massively overestimating the cost of “clutter”.

Repos without downstream users should be using a separate file anyways for CODEOWNERS-style code review control.

@cobaltt7
Copy link

What if it's a small project that you're working on by yourself, as most projects are? You don't need special CODEOWNERS for tsconfig then.

@ljharb
Copy link
Contributor

ljharb commented Apr 28, 2022

Nor do you need to worry much about a small handful of config files. (also, it’s never by yourself; there’s always “you” and “you in 6 months”, and that guy thinks you’re a jerk already, might as well keep things more maintainable and separate)

@jakobrosenberg
Copy link

I think you’re massively underestimating download counts and massively overestimating the cost of “clutter”.

I think you're massively underestimating how many projects don't have millions of weekly downloads while massively underestimating how many users would prefer to not have you dictate their file structure.

People and repos are different and needlessly trying to enforce a one-size-fits-all doesn't work. Especially if the one-size-fit is aimed at the top 1%.

@fishcharlie
Copy link
Contributor

And TypeScript wonders why people complain about ramp up time...

Having a configuration file in the first place is annoying. But being SO rigid and strict about that configuration file is just frustrating.

Do you know how easy it is to run a JavaScript file? 'node index.js'. No configuration. Nothing.

Yet TypeScript not only insists on having configuration files, but also not allowing for the flexibility that all these developers are asking for. It's a VERY simple and reasonable request...

I'll say it again. Just use cosmiconfig.

@ProjectCleverWeb
Copy link
Author

As the original poster of this issue, let me clarify a few things:

  1. Forcing users to use a brand new style of config than what has been standard for a long time is just a bad idea no matter how you slice it. It is also well outside of the original scope of this ticket, and its discussion should be moved to a new ticket if you want to continue discussing it as a new feature.
  2. Unfortunately, cosmiconfig integration is unlikely, as TS has no dependencies ( see this comment ) and I doubt they will change that. I am all for it, but I can see why they would avoid it too.
  3. Support for things like JS/TS config files would be awesome! However, we are having trouble even getting config via package.json approved, so while it would be great if they could implement features like that, I wouldn't consider it a strict requirement of this feature request.
  4. The original intent of this ticket is to just prevent creating unnecessary JSON config files when it's already a requirement of TS for the package.json to exist. While I am not opposed to changing that somewhat, if we change it too much or too often then it will likely never be approved.

@ProjectCleverWeb
Copy link
Author

To get the consensus of those who are interested in this feature, please use the emojis on this comment to vote on which scenario you think the TS team should implement as the resolution to this feature request:

  • 😄 = Original Scope: The TS team should only worry about adding support for configuring TS via the package.json file, and anything more would be awesome but not required.
  • 🚀 = Extended Scope: The TS team really needs to replicate a handful of cosmiconfig's features (discussed below where the comments mention "!CosmicFeatures" in their comment to see what features they really want)
  • 👀 = Exception Scope: The TS team needs to either make an exception to integrate cosmiconfig or at least replicate most of its features as they are all very useful and would be worth the time to integerate.
  • 👍 = Any Scope: I'll be happy if the TS team does any of these, I just really want/need this feature.

@MartinJohns
Copy link
Contributor

The fact that TypeScript is choosing to reinvent the wheel when FAR better alternatives exist is annoying.
Just use cosmiconfig.

The fact that the JS ecosystem relies heavily on an unmaintainable dependency mess is annoying. TypeScript has zero dependencies. Adding "cosmiconfig" will add 24 dependencies. That's a maintainability and security risk.

@jakobrosenberg
Copy link

The fact that the JS ecosystem relies heavily on an unmaintainable dependency mess is annoying. TypeScript has zero dependencies. Adding "cosmiconfig" will add 24 dependencies. That's a maintainability and security risk.

I agree. Reading a config from package.json or a .js file would require very little code. No dependency needed.

@ottodevs
Copy link

ottodevs commented May 7, 2022

I am in favour of integrating every dot config files into package.json, but I see a downside, this would break compatibility with @typescript-eslint/parser, that is currently requiring a parserOptions array indicating the tsconfig path like this:

        "parser": "@typescript-eslint/parser",
        "parserOptions": {
            "tsconfigRootDir": ".",
            "project": ["./tsconfig.json"]
        },

How would this be managed?

@ProjectCleverWeb
Copy link
Author

@ottodevs Well it would need to be adjusted to use an offset like "tsconfig" in a JSON file instead of just a whole JSON file. But given it is parsing it anyway, that should be relatively easy.

Also, I should mention that just like any other new feature, the expectation is not to make this the new default, but just to provide it as an option. That would take time to catch on, the integration would notifications from its users and would have ample opportunity to implement it before the larger community adopts it.

@andyslack
Copy link

Cannot wait for this feature, I am running a framework of modules and have .tsconfig files all over the place. Centralising them into one package and referencing it from package.json would be great. We are already doing this for .eslint .prettier .jest etc.

 "tsc": {
        "extends": "./node_modules/@module/.tsconfig.js"
    }, 

Would be fab!

@Jropp
Copy link

Jropp commented Mar 7, 2023

Please add this feature!

@TiagoCavalcante
Copy link

Any news on this?

@LittleHoopoe
Copy link

+1

@philihp
Copy link

philihp commented Jun 25, 2023

Cannot wait for this feature, I am running a framework of modules and have .tsconfig files all over the place. Centralising them into one package and referencing it from package.json would be great. We are already doing this for .eslint .prettier .jest etc.

Shared configs can already be done with base configs.

If you are truly passionate in your crusade against files in root, consider

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

or pull it out of package.json at build-time.

"scripts": {
-  "build": "tsc"
+  "build": "cat package.json | jq .typescriptConfig > tsconfig.json && tsc && rm tsconfig.json"
}

or

"scripts": {
+  "prebuild": "cat package.json | jq .typescriptConfig > tsconfig.json",
   "build": "tsc",
+  "postbuild": "rm tsconfig.json",
}

I’m suggesting they shouldn’t have the choice, because that will cause harm to downstream users.

I'm with @ljharb, and I do not want to relive the madness which was how every snowflake package built with webpack/babel wanted to configure it in some different way.

@Grief
Copy link

Grief commented Mar 3, 2024

@philihp IDEs (e.g. IntelliJ) use tsconfig.json (e.g. compilerOptions.baseUrl from it for source code navigation).
What you suggest will obviously make it impossible to work with the project in IDE.
If there would be a standard way of configuration using package.json, IDEs will be able to take it into account as well as a separate file.

@ZeroVa
Copy link

ZeroVa commented Apr 2, 2024

IDEs can update plugins to support it if they want to. I would be surprised if they don’t already read data from package.json for other things (scripts, for example). If the feature isn’t even optionally there, this is just circular.

@Grief
Copy link

Grief commented Apr 2, 2024

@ZeroVa IDEs (at least jetbrains' ones) obviously read all the data from package.json, including scripts (and everything else, dependencies, jest configuration, eslint configuration etc).

There is no tsconfig in package.json, so they cannot read it, again, obviously, and this is what is the issue about.

@jakobrosenberg
Copy link

@philihp I appreciate your suggestion, but this is at its core a crusade against accidental complexity, which your build steps only add to.

I do not want to relive the madness which was how every snowflake package built with webpack/babel wanted to configure it in some different way.

Consolidating dependency configs in package.json seems to fix the madness of having each dependency configure itself in some different way.

We already use it for configuring dependencies, devDependencies, peerDependencies, optionalDependencies and bundledDependencies.

I can configure prettier, eslint and jest and all my other dependencies in package.json. AFAIK even type exports have to be configured in package.json, so how does forcing users to split their tsconfig into a separate file reduce madness?

@otabekshoyimov
Copy link

Sorry I’m not a library maintainer but I just want to say this: please enable tsconfig.json in package.json. Js ecosystem has to stop writing config files at the root. It has to be in one place: package.json. That’s it

@philihp
Copy link

philihp commented Apr 24, 2024

@jakobrosenberg eslint no longer does this in v9, please see eslint/eslint#18131

how does forcing users to split their tsconfig into a separate file reduce madness?

idiomatic convention across projects makes it easier to context switch between them, and speeds up new developer onboarding.

additional thought: you probably want to avoid too much in package.json because your CI's node_modules cache often keys off of a hash of it. This can be be really annoying in large monorepos.

@rkristelijn
Copy link

I endorse your comment @philihp BTW, but still when you don't have a large monorepo but a humble little project you want to give the developer options to still stick the tsConfig in the package.json.

For now I can think of the following workarounds/ideas until tsconfig.json is supported in package.json. I'm sharing these so maybe an actually working life hack may spin off of this.

  1. If you set a tsConfig key in package.json with the content of your tsconfig.json, you can simply 'get' it by using npm pkg get tsConfig. However I cannot think of a way to make it respond to cat tsconfig.json... like a symlink needs an actual file
  2. you can move the tsconfig.json file to a different location and specify it on every command in your scripts:
"scripts": {
  "start": "tsc -p config/tsconfig.json && node .",
  // other scripts...
}
  1. You can move the tsconfig.json file to a config directory and create a symlink in the postinstall
// package.json
"scripts": {
  "postinstall": "node config/createSymlink.js",
  // other scripts...
}
// config/createSymlink.js
const fs = require('fs');
const path = require('path');
const os = require('os');

const tsConfigPath = path.join(__dirname, 'config', 'tsconfig.json');
const symlinkPath = path.join(__dirname, 'tsconfig.json');

if (fs.existsSync(symlinkPath)) {
  fs.unlinkSync(symlinkPath);
}

if (os.platform() === 'win32') {
  // On Windows, use a junction.
  fs.symlinkSync(tsConfigPath, symlinkPath, 'junction');
} else {
  // On Unix, use a symbolic link.
  fs.symlinkSync(tsConfigPath, symlinkPath);
}

@ljharb
Copy link
Contributor

ljharb commented Jun 14, 2024

A humble little project would still be impacted by slower install times by having a larger packument because tsconfig (a large file) is inlined within it.

@pgbradbury
Copy link

pgbradbury commented Jun 14, 2024 via email

@ljharb
Copy link
Contributor

ljharb commented Jun 14, 2024

If you author a package in my dep graph, I'm forced to download your tsconfig twice - once as part of the initial packument fetching to build the graph, and another inside the package tarball. Config in package.json for a library can't be used without forcing consumers to suffer from it.

@cobaltt7
Copy link

cobaltt7 commented Jun 15, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests