Hacker News new | ask | show | jobs
by rezonant 710 days ago
Please do not start publishing raw Typescript into the NPM registry thinking that all the reasons we have not done that in the past do not continue to apply.

I shouldn't have to say this, but at least 27 people upvoted this article, so here we are.

isolatedDeclarations is most useful for large codebases and other situations where performing a full Typescript compilation is prohibitively expensive. This is not the vast majority of cases. It is the declarations analog of transpileOnly, which skips all type checks and simply strips Typescript's special syntax.

The author seems to assume use of JSR, which is an alternative to the NPM registry which automatically compiles Typescript. Not being terribly familiar with it, it's possible this is more relevant to users of that registry, but it's not clear why this is an issue when the registry itself is handling transpiling and declaration generation.

EDIT: To be clear, I think it's totally fine to publish your TS source in addition to your JS and d.ts outputs, just don't publish TS only packages, please.

3 comments

Author here. Agree! The whole npm ecosystem is based around npm packages shipping JS files and doing anything else would break it. I've updated the article to hopefully make it less confusing. The takeaway should definitely not to only publish TS files to npm.

I mainly work with Deno which can run TS files natively (disclaimer: I'm employed by them). This changes the parameters a little as all registries for Deno could always ships the TS sources directly. But when publishing to npm you always have to publish the JS sources to work with runtimes like Node that don't support running TS natively.

> that all the reasons we have not done that in the past do not continue to apply.

Your plea would be better if you mentioned what the actual reasons are.

Sure-- the first issue is that NPM is a JavaScript registry, and it's bad form to restrict usage of your library to Typescript projects, or require non TS users to go through hoops to use your code. Additionally, if your own project executes as JavaScript (the vast majority of cases other than sort of Deno), your project will need to do special work to have JS files produced for the TS only library-- by default this won't happen so imports to the library will fail at runtime. When you do add node_modules/some-package to your TS project, this will change the structure of the files emitted into your output directory (assuming you use one, which is highly recommended), creating weird pathing like dist/src/main.js. Also the module would end up in dist/node_modules/some-package, which would be fine as long as the package isn't using non-code files within its module, which it likely is. And of course, you'd be missing all export information within that folder, which is likely to break imports, so you'll need to copy the package.json....

This is all a massive breach of encapsulation.

Is it possible to consume a TS only library distributed via NPM in a Node.js Typescript project? Yes, certainly. Is it ergonomic for consumers? No, certainly not.

Overall, it will be a bad experience for a lot of environments where JS files are expected to be present but aren't. Deno is probably the only environment that can consume NPM packages where it could conceivably work.

Id love it of npm added support for additional artifacts — separate tarballs for source, code, binaries, source maps, docs etc
Fair, but if you don't fall into the pit of despair by consuming micro libraries (ie "is-true" or "leftpad"), the overhead of having source and source maps present on a developer environment or even a server deployment is not terrible. If you are bundling for web delivery, those files will be omitted automatically by nature of the bundling process.

While it would be nice to have native support for package components, personally I think the best path is to ship all of it (save perhaps documentation, where there's currently no ergonomic way for a consumer to make use of it) in the main package.

The above is assuming "docs" mean some kind of external documentation, you absolutely should not strip out your docblocks when you package your code. Ditto for minification: Just don't. If the end user needs to optimize for size, they will be minifying anyway, all packaging minification does is create painful debugging and code reading experiences for consumers.