by khalidx on 11/21/23, 8:44 AM with 235 comments
by sirius87 on 11/21/23, 2:14 PM
Meanwhile anyone using an intersection of TypeScript with jest and any of sindresorhus' libraries when he flipped to ESM for his bajillion libraries immediately felt the downside and moved hard away from ESM.
Imagine the mind-boggling hours lost just to get these export/import formats to glue.
by koolba on 11/21/23, 12:51 PM
One problem with this guide that makes that trickier is that the tsconfig.json itself imports https://github.com/sindresorhus/tsconfig/blob/5c87dc118e057d... and overrides a bunch of values.
So if you really want to understand what it's doing, you need to get rid of that dependency and inline / merge that config file. That would also add stability to your project as it's one less upstream dependency out of your control (and a big one at that as it controls how you entire project is built!).
For example the imported tsconfig.json changes these:
"compilerOptions": {
// ...
"module": "node16",
"moduleResolution": "node16",
"moduleDetection": "force",
// ...
"allowSyntheticDefaultImports": true, // To provide backwards compatibility, Node.js allows you to import most CommonJS packages with a default import. This flag tells TypeScript that it's okay to use import on CommonJS modules.
"jsx": "react",
// ...
}
But you wouldn't notice that if you just look at the gist. It'd just be a magic that you can write React code in a .tsx file. Clearly that has to be enabled somewhere.by monooso on 11/21/23, 1:50 PM
It makes me wonder why Deno [1] still seems to be such a niche choice. Most of these headaches just go away.
Does anyone here prefer Deno for new projects? And if not, why?
[1] And Bun, although that's much newer.
by rickcarlino on 11/21/23, 10:34 AM
by awongh on 11/21/23, 7:37 PM
For an ecosystem that purports to be ready for professional use it absolutely boggles my mind that the tooling is stuck at this very amateurish level.
Why isn’t there a ready preset for me to use ESM syntax with Next.js / Typescript?
What’s wrong with the culture around Node/TS/JS tooling in general that it’s so consistently broken all the time? What the hell.
by jna_sh on 11/21/23, 11:30 AM
by solatic on 11/21/23, 2:20 PM
Part of the problem is the fact that web browsers, Node.js, and other JS runtimes have slightly different needs and expectations. Part of the problem arises when you're trying to mix and match web code, Node.js code, and other JS runtime code in the same monorepo. There's no single magic-bullet configuration.
by tuyiown on 11/21/23, 1:35 PM
by preommr on 11/21/23, 3:42 PM
This attitude just doesn't work for js ecosystem. I have some shell scripts, vim config files, etc. that I don't remember what they do, but I just copy over and they work.
Coding projects are different; they break all the time. Especially with how fast the js/ts ecosystem works. One day, a crucial library just decides that it's changed something that doesn't work with the build process because there's so many variations of them that they can't possibly all be tested against.
by c-hendricks on 11/21/23, 4:41 PM
What a frustrating experience it has been.
Using unbuild "works", but
- For the life of me, I can't get unbuild to generate `.d.mts` files when my source files don't have `.mts` extensions. Luckily, when the library is used in a downstream project and a `.mjs` file is imported, TypeScript properly loads the `.d.ts` file anyways
- When it comes to a downstream project, TypeScript doesn't seem to work with export maps. People say it does, but maybe because I don't have `.d.mts` files TypeScript is saying it can't find type information? It _does_ work with simple export maps, but if I say `'./': './dist/esm/'` so the downstream project doesn't have to manually import from `dist/esm` I see the issue
- Using the "esm" module / moduleResolutions + converting my files to `.mts` + changing imports in the source to import the non-existant `.mjs` files results in a CJS bundle that tries to require a `.mjs` file, which unbuild has built with a `.js` extension, so it throws an error because it can't find the file.
- For some reason unbuild mucks with the hashbang line in my _CJS_ `bin` script, the ESM one it doesn't touch
Ugh.
by _nalply on 11/21/23, 2:42 PM
You might ask why without bundling?
Sometimes you just want to start something simple on the browser and compile to JavaScript on the fly.
I tried the dev server from Modern Web [0], and I liked it. I program in TypeScript and the browser reloads whenever I save a file. Of course I could set up a bundler and for a small program waiting times are negligible. But I hate bundlers. I know it's irrational, but nowadays I program for fun so I think I should have the choice to reject bundlers.
This fails for many Node dependencies. There is a conflict between CommonJS and ESM. I am not 100% sure that what I want to achieve is impossible without forking dependencies and making a small change.
I even found a way to have a CommonJs and ESM polyglot, but this hack is extremely ugly. I named the hack modglot [1]. I don't think this is a good idea and I don't understand enough to propose something. I am somewhat dejected about the current state of TypeScript development for the browser and paused development.
Now I am programming in Rust again just for fun, but if I return to TypeScript, probably I will try out Deno.
[0]: https://modern-web.dev/guides/dev-server/getting-started/
by paradite on 11/21/23, 12:57 PM
If you Google the error you will get stackoverflow posts with hundreds of upvotes.
And that's the main problem with using ESM - 3rd party library support. It is trivial to do hello world in ESM with Node.js, but try that with 10 dependencies and quickly you will be hit errors.
by drtgh on 11/21/23, 1:37 PM
by EdSharkey on 11/21/23, 12:34 PM
Fellow scrounging raccoons, raise your chipped mugs and cracked cups! Let us toast to our fortune, we truly are the blessed ones.
by wruza on 11/21/23, 4:38 PM
I'm maintaining a few pristine example projects to keep track of these ways and test them periodically. This iteration probably had the shortest lifetime. I didn't manage to develop even a single toy project before something got obsoleted again. Love this community. Looking forward to solve a handful of brand new issues with tsx.
I wish there was some IDEish starter pack which you could install and start writing code anytime, without investigating issues with running a damn interpreter.
by conaclos on 11/21/23, 4:17 PM
- `importsNotUsedAsValues` is deprecated [0] since TypeScript 5.2, in favor of `verbatimModuleSyntax` [1].
- I could set `module` to `Node16`. This automatically set `esModuleInterop` to true.
- Also, to catch more issues, set `allowUnreachableCode` to false and set `strict`, `noImplicitReturns`, `noImplicitOverride`, `noFallthroughCasesInSwitch`, `exactOptionalPropertyTypes` to true.
- Set `types` to the empty array `[]` to avoid loading unwanted types.
- Enable `skipLibCheck` to avoid checking imported module types.
- Not sure that `declarationMap` is still useful nowadays. TypeScript is now able to match directly against source files.
- Enable `composite` that in turns enables `incremental` and `declaration` (declaration file emit). `composite` enables project references which is useful in a monorepo setting or to separate source and test files into two projects. See [2]
- Enable `checkJs` to type-check JavaScript files
To summarize:
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"lib": ["ES2022"],
"module": "Node16",
"target": "ES2022",
"outDir": "./dist",
"composite": true,
"sourceMap": true,
"types": [],
"isolatedModules": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"verbatimModuleSyntax": true,
"allowUnreachableCode": false,
"checkJs": true,
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"strict": true
}
"include": ["./src/**/*.ts"],
"exclude": ["./src/specific-file.ts"]
}
[0] https://www.typescriptlang.org/tsconfig#importsNotUsedAsValu...[1] https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax
[2] https://www.typescriptlang.org/docs/handbook/project-referen...
by jampekka on 11/21/23, 12:41 PM
by dangoodmanUT on 11/21/23, 1:37 PM
by keb_ on 11/21/23, 10:53 AM
by pyrolistical on 11/21/23, 11:43 AM
I had to tsc then node --test the built files.
tsx also is missing the test runner https://github.com/privatenumber/tsx/issues/257
by quackware on 11/21/23, 10:36 AM
- ts-node is much slower than something like esbuild/tsx right? As long as you rely on your ide type checking or run type checking before deploying your app.
by dimgl on 11/21/23, 5:32 PM
I will say that it's kind of sad that Node.js has devolved into this.
by vasergen on 11/21/23, 12:37 PM
So true, I really wandering if there was a better alternative, they essentially broke a lot of packages and I don't know how many dev hours will be put now to fix all of this, because so many tools are broken now. Additionally to that, they did some other not backwards compatible changes, like removing __direname in ESM, which is IMHO not the best decisions, why not for example just keep it as it is, but deprecate it and have a warning message.
by apitman on 11/21/23, 5:50 PM
by bhouston on 11/21/23, 4:05 PM
https://github.com/bhouston/template-typescript-monorepo
This has a lot of features that work well together: - TypeScript - ESM - Node.JS Server + React + Cli - Monorepository - Fast Incremental Updates
Feedback welcome. I use this for about a dozen different projects now.
by bearjaws on 11/21/23, 2:16 PM
by tommy_guo on 11/21/23, 3:30 PM
I'm currently using this setup to run multiple services on AWS.
by SnoozingBoa on 11/21/23, 7:59 PM
As of November 2023, what is the canonical way to set up a Node project with Typescript and hot reload?
Minimal setup with least amount of configs and tooling. I am not after any other tools like Bun.
by diamondfist25 on 11/21/23, 11:48 PM
Ideally things are great — do ur frontend dev in js and backend in js. With TS added for better dx. Except 90% of the time ur fighting the configs of why its not importing/requiring
U change from .js, .ts, .cjs, .mjs and nothing works
by ivanjermakov on 11/21/23, 12:00 PM
by demurgos on 11/21/23, 12:48 PM
Since TS 4.5 and their support for `.mts`, I finally settled on just chaining `tsc --build && node ./build/main.mjs`.
by davidy123 on 11/21/23, 1:58 PM
by nop_slide on 11/21/23, 6:42 PM
I’m not very familiar with the ecosystem and trying to understand what pain ports people are describing here in the comments.
by cantSpellSober on 11/21/23, 3:07 PM
by austin-cheney on 11/21/23, 10:28 AM
I completely disagree. This has always felt immediately straight forward to me. I suspect this struggle, a struggle I completely don’t understand, explains the complexity of hiring for these kinds of jobs. I really felt that to get hired for these jobs you had to be willing to play stupid games and abandon all reason to worship at the pulpit of giant frameworks and third party solutions. Fortunately, I have moved on to something else.
by bovermyer on 11/21/23, 12:16 PM
by resters on 11/21/23, 2:12 PM
by rglover on 11/21/23, 4:25 PM
by demondemidi on 11/21/23, 9:00 PM
Until this github repo dries up the same way similar attempts at this have.
by w3news on 11/21/23, 12:35 PM
For type checking on development, you can do it with ESLint and JSDoc in Typescript modus. You have the same type checking like you have in ts files. You can even import types from typescript files, like .d.ts
Best of both worlds, no transformation of the code, and on development you have some help from Typescript.
by Rapzid on 11/21/23, 1:26 PM
ts-node --esm --swc
Haven't really had any issues with this in a long time.
by kshahkshah on 11/21/23, 6:14 PM
by WolfOliver on 11/21/23, 11:14 AM