TypeStrong / ts-node

TypeScript execution and REPL for node.js
https://typestrong.org/ts-node
MIT License
12.73k stars 529 forks source link

Feature Request: Add support for "Solution Style" tsconfig.json file #1057

Open xiaoxiangmoe opened 4 years ago

xiaoxiangmoe commented 4 years ago

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#support-for-solution-style-tsconfigjson-files

// tsconfig.json
{
  files: [],
  references: [
    { path: "./scripts/tsconfig.scripts.json" },
    { path: "./frontend/tsconfig.frontend.json" },
    { path: "./backend/tsconfig.backend.json" },
  ],
}
// scripts/tsconfig.scripts.json
{
  "compilerOptions": {
    "strict": true,
    "esModuleInterop": true,
    "module": "CommonJS",
    "lib": ["ESNext"],
    "forceConsistentCasingInFileNames": true,
    "importsNotUsedAsValues": "error"
  },
  "include": ["./**/*.ts"]
}

yarn ts-node scripts/foo.ts should auto use ./scripts/tsconfig.scripts.json

bradennapier commented 3 years ago

yeah this is SORELY missed - moving to using references basically made all development scripts break now :-\

cspotcode commented 3 years ago

In the short-term I recommend turning on transpileOnly mode. You can configure this flag directly in your solution-style tsconfig file.

bradennapier commented 3 years ago

Can't if you use compile transformers.

cspotcode commented 3 years ago

You might be able to get something working by nesting other options -- not transpileOnly -- within the "ts-node" sub-object of your root tsconfig file. I'm not sure without seeing how your project is set up, but it might work.

Can you share more details about your use-case? Which compile transformers are you using, and how do they relate to your development scripts? Is it possible or impossible to write an alternative tsconfig file that ts-node reads?

Either way, the best chance of getting this implemented is if someone sends us a pull request. Without going into detail, the current state of the world is affecting my free time.

bradennapier commented 3 years ago

Yeah I kind of use my tsconfig.base.json in some cases, i will play around with that. While not ideal it may do the job.

I am using the transform-paths plugin in order to rewrite imports according to paths and baseUrl

"plugins": [
      {
        "transform": "@zerollup/ts-transform-paths"
      }
    ]
cspotcode commented 3 years ago

@bradennapier

Keep in mind you can specify alternative compiler options nested inside your tsconfig's "ts-node" object. So you can let ts-node use the default tsconfig file, but hand it a custom set of compilerOptions.

A few more questions: Does that plugin require typechecking, or is it compatible with transpileOnly mode? It's rewriting import paths, right? Are you using ttypescript? Have you looked at using https://www.npmjs.com/package/tsconfig-paths for your development scripts, and if so, what are the blockers with that approach?

bradennapier commented 3 years ago

@cspotcode first of all thanks a ton for your help here and taking the time - much appreciated!

I believe tsconfig-paths is required at runtime, no? The benefit of ts-transform-paths was that it simply rewrites the paths of the imports so nothing is required at runtime to support the absolute-style paths. I could be incorrect, it has been awhile?

However, potentially could use that for dev and use the transformer for production - which may be why you said for your development scripts :-P

I do not think the transformer works with transpileOnly - there is an issue https://github.com/zerkalica/zerollup/issues/31

Keep in mind you can specify alternative compiler options nested inside your tsconfig's "ts-node" object. So you can let ts-node use the default tsconfig file, but hand it a custom set of compilerOptions.

I will have to play around with that as well

cspotcode commented 3 years ago

@bradennapier You're correct: tsconfig-paths is required at runtime. And yes, I was suggesting it as a fix for your development scripts. Though I understand that using 2 different tools is adding complexity.

Thanks for linking that ticket. ttypescript supports an alternative interface where it passes CompilerOptions to the transformer factory instead of Program. I wonder, can the transformer be updated to use that interface? But the CompilerOptions might suffer from the same problem, missing paths. https://github.com/cevek/ttypescript/tree/master/packages/ttypescript#compileroptions

bradennapier commented 3 years ago

It wouldn't even be that terrible to need to define paths as a config option or something if it would make things work nicely :-P but yeah, that is past my understanding of the ts compiler. https://github.com/bradennapier/eslint-plugin-ts-import is about the extent of my compiler experience and I ended up just using tsconfig-paths in the end to make it easy on me :-)

bradennapier commented 3 years ago

@cspotcode well looksl ike i pretty quickly ran into https://github.com/dividab/tsconfig-paths/issues/133 with that attempt :-P -- we use esModuleInterop and due to that when I am using this it seems to fail to resolve anything that requires it :-\ - it is different issue here but i thnk it may be due to similar issue? Maybe not though :-P


After spending the last 2 hours on that .. I guess the compilerOptions do not work with extends - so when I am using extends in the tsconfig with --script-mode it ends up not finding any of the compilerOptions so esModuleInterop is not true. Seems I would have to copy the compilerOptions to all 35 referenced projects?

cspotcode commented 3 years ago

@bradennapier are you referring to how tsconfig-paths reads compilerOptions, or how ts-node reads compilerOptions?

Copying a config flag to 35 referenced projects is honestly not that hard, pragmatically speaking. If that's all it takes to get you unblocked, you should go for it.

bradennapier commented 3 years ago

using --script-mode fixed my issue when combined with --transpile-only. Although ts-node-dev doesn't support it so I am submitting a PR (and their --dir is configured as a boolean so that doesnt work either).

Think I am finally close :-) thanks again.

https://github.com/whitecolor/ts-node-dev/pull/183 -- with that PR i am fully unblocked and working with transpileOnly in dev mode <3


In case anyone runs into this and needs help with it - I needed to do the following:

// ./register.js
const path = require('path');
const { loadConfig, register } = require('tsconfig-paths');

const dirName = path.dirname(process.argv[process.argv.length - 1]);
const config = loadConfig(dirName);

// dev support for absolute path resolution while allowing transpileOnly to work
register({
  baseUrl: config.absoluteBaseUrl,
  paths: config.paths
});

then in my package.json script I can do something like:

ts-node-dev -s -H -T -r ./register --respawn -- src/services/rest-api/index.ts

Note for the -s option to work the PR I linked above is going to need to be merged. Since it doesn't take any building you can prob just install that directly from git though: yarn add --dev git://github.com/bradennapier/ts-node-dev.git#feature/script-mode"

JasonKleban commented 3 years ago

https://github.com/TypeStrong/ts-node/issues/897#issuecomment-752735006