run icon indicating copy to clipboard operation
run copied to clipboard

README mentions adding a tsconfig.json, but doesn't say what to put in it

Open richardbarrell-calvium opened this issue 2 years ago • 3 comments

If I add a tsconfig.json, I need to put roughly the following in it:

{
  "compilerOptions": {
    "strict": true,
    "lib": ["DOM", "DOM.Iterable", "ES6"],
    "esModuleInterop": true,
    "resolveJsonModule": true
  },
  "exclude": ["node_modules", "dist"],
  "include": [".marko-run/routes.d.ts", "src"]
}

If I omit "lib", I'll get TS errors telling me that Promise isn't defined. (You can use something more aggressive than ES2019 if you're targeting modern browsers, but ES6 happens to be the minimum for Promise.)

If I omit either "esModuleInterop" or "resolveJsonModule", I see type errors in the example project, because the file generated in .marko-run/routes.d.ts isn't parsed by typescript, so none of my per-route types seem to be visible in VS Code.

I'm going to suggest adding an example tsconfig.json file?

edit: I thought these were needed but they actually aren't:

    "allowSyntheticDefaultImports": true,
    "moduleResolution": "node",

richardbarrell-calvium avatar May 22 '23 17:05 richardbarrell-calvium

Good, point we should provide more guidance here. I played around with different configs and this is the minimal I found:

{
  "include": ["src/**/*", ".marko-run/*"]
  "compilerOptions": {
    "strict": true,
    "target": "es6",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true
  }
}

Top-level

  • include - By default TS won't match files/directories starting with . so adding ".marko-run/*" is necessary. If you are using VSCode with the Marko plugin, it will automatically pull in this file and make the TS default include generally good enough.
  • exclude - This option filters out files from those matched by include, so as long as your don't match anything you don't want, you can omit this option.

Compiler Options

  • strict: true - This should always be set to true when using TS! 🙃
  • target: "es6" - Like you said, this is the minimum target for Promise and async (ES5+). This also causes module to be set as "es6" istead of "commonjs" which we want.
  • moduleResolution: "node" - By default this is "classic" unless you set module to "nodenext" or "node16" but those values cause other issues. My reading of TS's docs suggest setting module to "esnext" will set this to "node" but that is not what I observe happening. Explicitly setting this seems to be the most reliable.
  • allowSyntheticDefaultImports: true - This is necessary to import default @marko/run as a namespace in the .marko-run/routes.d.ts file. I think I could actually change that to us a * import instead and this option won't be necessay. Note: setting esModuleInterop to true will also enable this option so that would work too.
  • resolveJsonModule: true - This is only necessary if you have +meta.json files

Let me know if these work for you and I will update the examples so they don't use the base tsconfig.json and make them more stand-alone.

rturnq avatar May 24 '23 18:05 rturnq

That looks right to me, but maybe put libs: ['dom'] in as well anyway? I'm thinking that as soon as you write any code in practice, you're going to be wanting to use DOM APIs from event handlers.

richardbarrell-calvium avatar May 30 '23 13:05 richardbarrell-calvium

@rturnq I can confirm that your suggested minimal tsconfig seems to work fine for me, thank you. 👍

I have other issues that might cause tsconfig.json recommendations to be revisited, but I'll file those separately when I get the brain cycles available.

richardbarrell-calvium avatar May 30 '23 13:05 richardbarrell-calvium