microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.19k stars 12.38k forks source link

Standard package.json key for .ts files #12561

Open appsforartists opened 7 years ago

appsforartists commented 7 years ago

A common TypeScript module structure looks like this:

src/index.ts
dist/index.js
dist/index.d.ts

and a package.json that looks like this:

  "main": "dist/index.js",
  "types": "dist/index.d.ts",

There's a convention to use the package.json key jsnext:main to point to a variant of main that uses ES2015 module syntax. Can we develop a similar convention to point at .ts files, e.g. typescript:main?

Consider a TypeScript project that is sharded across many microlibraries (e.g. my-project-core, my-project-thing-plugin, my-project-other-thing-plugin). I'd like to be able to configure my bundler to import from src/*.ts files for any module whose name starts with my-project. Otherwise, it will be looking in dist/*.js and I'll have to rebuild the plugins any time I make changes in them.

Of course, I could use jsnext:main for this purpose now, but any consumers who aren't using TypeScript would get syntax errors for any files that contained TS-specific syntax like types. Similarly, I could make up my own package.json key and configure my bundler to look there first, but it behooves the community to have a convention here. That will allow bundlers like Webpack, Browserify, Rollup, and Pundle to look in the right place by default.

appsforartists commented 7 years ago

This may be a Feature Request more than a Question. tsc and/or Language Services should follow the same rule, otherwise autocomplete across packages would be broken until a new build occurs.

blakeembrey commented 7 years ago

Side note (in case anyone else references the OP): the types field would usually point to dist/index.d.ts and not src.

appsforartists commented 7 years ago

@blakeembrey fixed.

appsforartists commented 7 years ago

I have this working in both Pundle (http://codereview.cc/D2470) and Webpack (http://codereview.cc/D2472).

And I'm considering opening PRs against RxJS, Cycle, xstream, and Angular to test it with common packages.

DanielRosenwasser commented 7 years ago

I don't see the harm in it, but I'm not sure whether or not I understand the implications.

Consider a TypeScript project that is sharded across many microlibraries (e.g. my-project-core, my-project-thing-plugin, my-project-other-thing-plugin). I'd like to be able to configure my bundler to import from src/*.ts files for any module whose name starts with my-project. Otherwise, it will be looking in dist/*.js and I'll have to rebuild the plugins any time I make changes in them.

The thing is that if I'm not mistaken, this will still require a full type-check across all of your code (though it can avoid scanning/parsing/binding/sometimes emitting for individual files). @mhegazy is that correct?

mhegazy commented 7 years ago

I do not think sharing sources between projects is something i would recommend. .d.ts files are meant for the sharing scenario. jsxnext:main is meant for bundelers, and is already well defined; but this is a different scenario.

trusktr commented 4 years ago

@mhegazy Sharing sources is the only way to get around the problems listed in #35822.

appsforartists commented 10 months ago

I'm looking at adding Vite to my workflow, and once again this seems like a good solution.

Here's the problem: Vite shortcircuits typechecking to make UI iteration faster. To do that, it needs to know what sources you have under control, so it can watch them for changes without waiting for tsc to run. I still want tsc to do typechecking, I just don't want it on the critical path for experimenting with UI. My current setup has gotten slow enough that I find myself waiting for tsc when I'm testing visual changes.

It appears Vite has a resolve: mainFields: [] setting to control which part of package.json it uses for resolution. If I add something like "typescript": "src/index.ts" to my package.jsons (and to my Vite config), I can tell Vite how to navigate the source in my monorepo, while still leaving "module": "dist/index.js" for TypeScript to generate for downstream consumers.

cc @yyx990803 @patak-dev

appsforartists commented 10 months ago

That's how I ended up adding Vite to my monorepo.

When vite serve is running, I include typescript in mainFields, and I've added a "typescript": "src/index.ts" entry to the package jsons in the monorepo. That puts all the JS I've authored on the Vite fast path during development, but keeps tsc in the loop to typecheck before publishing.

Here's an example.