Live data from Hacker News

TypeScript NPM Packages Done Right

blog.liblab.com

31–40 of 81 posts

Re: TypeScript NPM Packages Done Right

#31
post #19

Earlier quoted context omitted.

Remember we’re using Node. I don’t think TypeScript compiler supports importing ESM into CommonJS files. Basically we will have to move the library to ESM and then use a bundler like esbuild to compile it to CJS as well for compatibility. It’s a mess

> It’s a mess I think everyone agrees about this. What people can’t agree about is how to fix it.

I haven’t really struggled too much here.

Maybe an aversion to bundlers exists, but I think tsup and vite are great and simple. We have turbopack on the horizon too.

For small projects I don’t even need a configuration file for tsup to target both formats. For larger more complex projects vite configs tend to be under 50 LoC.

Re: TypeScript NPM Packages Done Right

#32

Perhaps I’m missing something, but when I’ve done this in the past, I get weird package resolution because my index.js isn’t in the root (`npm publish` publishes the root and doesn’t support alternate paths to my knowledge) - in the end people have to `import x from “mylib/dist”`. I got round this with some funky step where I copy the package.json into the dist folder and rewrite some paths. Is there a better way to…

I’ve experienced this as well.

For some projects I just configure publishConfig.directory directly at the dist folder.

While this may not look as clean, it is a lot easier for me to manage everything that’s published under a single directory.

Re: TypeScript NPM Packages Done Right

#33
post #28
post #15

"module": "commonjs", Nope.

Anecdotally, ESM has been an absolute nightmare. Packages that aren’t compatible without code changes, having to add extensions to every single import unless we specify a flag (that is now deprecated), challenges with import maps and module resolution, the list goes on. So we just use CommonJS with project references and call it a day. Everything works and we don’t need to change any of our code. The way ESM was intr…

also, if one decided to publish as dual ESM + CJS package, depending on the user's toolings, one might encounter the Dual Package Hazard [1] that could be really hard to trace

[1] https://nodejs.org/api/packages.html#dual-commonjses-module-...

Re: TypeScript NPM Packages Done Right

#34
post #3

I understand the whole CommonJS Vs imports situation. I have been that vocal minority that keeps complaining about CommonJS support to library authors. But I have given it up for the greater good. we have a standard now, CommonJS needs to go, why keep pushing non standard stuff in a 2023 article.

Yes, when working with Angular, you'll see build warnings about CommonJS dependencies.

> ▲ Module 'some-library' used by 'src/app/some.component.ts' is not ESM

> CommonJS or AMD dependencies can cause optimization bailouts.

> For more information see: https://angular.io/guide/build#configuring-commonjs-dependen...

Re: TypeScript NPM Packages Done Right

#35
post #12

Also, the default target configuration is "es2016," and modern browsers only support up to "es2015." I had to recheck this was indeed an article from 2023, because this part surprised me greatly. To my understanding, es2016 only added Array.prototype.includes, the exponentiation operator (**), and preventing generator functions from being constructed. Even the slowest adopters already had these in 2017. Is the author…

No idea. Matt Pocock has a much better cheat sheet for tsconfig configurations and his is set as es2022. https://twitter.com/mattpocockuk/status/1701619240686485799

I prefer to leave lib empty, it’s always caused me problems.

Re: TypeScript NPM Packages Done Right

#36

Perhaps I’m missing something, but when I’ve done this in the past, I get weird package resolution because my index.js isn’t in the root (`npm publish` publishes the root and doesn’t support alternate paths to my knowledge) - in the end people have to `import x from “mylib/dist”`. I got round this with some funky step where I copy the package.json into the dist folder and rewrite some paths. Is there a better way to…

You missed a step in this article’s package.json. The “main” (or “module” for ESM) property defines the entry point. I’ve published dozens of packages and they all point to dist/index.js with zero issues.

Re: TypeScript NPM Packages Done Right

#37
post #19
post #18

Earlier quoted context omitted.

If you're using TypeScript, you have a build step anyway, so you can easily use ESM.

Remember we’re using Node. I don’t think TypeScript compiler supports importing ESM into CommonJS files. Basically we will have to move the library to ESM and then use a bundler like esbuild to compile it to CJS as well for compatibility. It’s a mess

Try using the tsx package for running Node in situations like this. It magically “just works”

https://www.npmjs.com/package/tsx

Re: TypeScript NPM Packages Done Right

#38
post #14

While the article is technically correct it avoids the most common issue with 'pure' typescript libraries in that you still need a bundler if you have multiple .ts files. Once you enter that territory you realize how much more complex everything becomes.

You don't necessarily need a bundler. You could use index.ts files to re-export all the exports of your source files.

Re: TypeScript NPM Packages Done Right

#39
post #24

`tsc` is extremely slow to transpile TypeScript sources into JavaScript. It's invaluable for typechecking, but for transpilation there are much better solutions like SWC or tsup [1] (which nicely wraps esbuild and Rollup). [1] https://tsup.egoist.dev/

> much better solutions like SWC Which doesn't support const enum correctly and god knows what else without erroring.

Esbuild works fine and is also much faster than TSC.

Also TS enums are flawed: https://blog.logrocket.com/why-typescript-enums-suck/

Re: TypeScript NPM Packages Done Right

#40
post #28
post #15

"module": "commonjs", Nope.

Anecdotally, ESM has been an absolute nightmare. Packages that aren’t compatible without code changes, having to add extensions to every single import unless we specify a flag (that is now deprecated), challenges with import maps and module resolution, the list goes on. So we just use CommonJS with project references and call it a day. Everything works and we don’t need to change any of our code. The way ESM was intr…

We recently switched to esm and it wasn't that painful. Ok, you have to put .js on imports, it's quite easy to search replace this with regex.

Any modules that didn't work (e.g. mocha) were switched over to more modern equivalents (vitest). This is probably a good thing.

We also export ESM and CommonJS source in our packages by first transpiling to ESM then using vite to convert to CommonJS. It works really well and allows us to use our packages in both environments.

Post reply on HN