[HN Gopher] A Node, TypeScript, TS-Node and ESM experience that ...
___________________________________________________________________
A Node, TypeScript, TS-Node and ESM experience that works
Author : khalidx
Score : 176 points
Date : 2023-11-21 08:44 UTC (14 hours ago)
(HTM) web link (gist.github.com)
(TXT) w3m dump (gist.github.com)
| austin-cheney wrote:
| _The experience of using Node.JS with TypeScript, ts-node, and
| ESM is horrible._
|
| 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.
| Yiin wrote:
| I'd love to see you live stream a process of creating a project
| consisting of several different apps using same ts config and
| shared libs folder from scratch using these tools.
| austin-cheney wrote:
| In my personal projects I use _"type": "module"_ in the
| package.json.
|
| In my tsconfig.json I use {
| "compilerOptions": { "alwaysStrict": true,
| "module": "ES2020", "moduleResolution": "node",
| "outDir": "./js/lib", "noEmit": true,
| "noImplicitAny": true, "pretty": false,
| "strictFunctionTypes": true, "target": "ES2020",
| "types": ["node"], "typeRoots":
| ["./node_modules/@types"] }, "exclude": [
| "js", "lib/terminal/test/storageTest/temp",
| "**/node_modules", "**/.*/" ],
| "include": [ "**/*.ts" ] }
|
| Internally in your apps never never use relative file system
| paths.
| khalidx wrote:
| Is alwaysStrict the same as strict? I think this skips a
| lot of the strict options that are usually the case for
| using TypeScript in the first place.
| austin-cheney wrote:
| According to the TypeScript documentation for
| tsconfig.json the alwaysStrict option forces the compiled
| out to strict mode such that the JIT interpreter parses
| it as such. This happens anyways when using ES6 modules,
| but it also ensures the TypeScript compiler parses each
| file in strict mode regardless of having the "use strict"
| pragma at the top.
|
| https://www.typescriptlang.org/tsconfig#alwaysStrict
| khalidx wrote:
| I just dug a bit deeper as I couldn't remember the
| differences. They're not referring to the same things.
|
| "alwaysStrict", which adds "use strict", is different
| than TypeScript "strict" mode, which constrains the
| language.
|
| Setting "strict" to "true" enables "alwaysStrict", but
| not the other way around. I'd remove "alwaysStrict" and
| go with "strict" as it covers more things.
| rickcarlino wrote:
| I've found TSX to be a better alternative to ts-node. It seems to
| have more sensible defaults in 2023.
| https://github.com/privatenumber/tsx
| lloydatkinson wrote:
| I was about to say exactly this. If you're writing Node scripts
| there's no reason to use ts-node as tsx, by default, does the
| correct thing and works correctly with ES modules.
|
| Of course, Deno offers a better experience for scripts or
| programs.
| khalidx wrote:
| I tried `tsx` but it didn't work for some reason (can't
| remember why right now). Also, if you've been using `ts-node`
| and feel comfortable with it, this setup should work for you
| instead of switching your toolchain.
| privatenumber wrote:
| tsx v4 was released a couple weeks ago which addressed many
| incompatibility issues. Hope you have a chance to give it
| another shot :)
| vmfunction wrote:
| or esno, which is tsx with esbuild.
| lhnz wrote:
| I'm using `esyes` [0] by Yehuda Katz and the logic is simple
| and it works very well.
|
| [0] https://github.com/starbeamjs/esyes
| vmfunction wrote:
| thanks for sharing! Didn't know about this one.
| madeofpalk wrote:
| tsx is "tsx with esbuild" though?
| domh wrote:
| I use node-dev which seems to have good ts support. node-dev
| with --respawn is a good cheap way to watch and rerun ts files
| on change!
| herpdyderp wrote:
| Tsx is great but doesn't work in all situations unfortunately.
| Some broken cases that I remember off the top of my head are
| Playwright and test coverage.
| privatenumber wrote:
| Maintainer of tsx here.
|
| tsx should be able to handle Playwright as of v4+, and
| hopefully the test coverage you're referring to.
|
| Before, it was compiling ESM syntax to CJS as an effort to
| ease the ecosystem's CJS -> ESM migration, and hiccuping
| whenever it encountered `eval()`. Now it includes smarter
| checks to determine if a file needs to be compiled at all and
| skips processing most dependencies.
|
| Hope it works well for you!
| e1g wrote:
| Can confirm we use tsx with playwright with no issues.
| Thanks!
| herpdyderp wrote:
| I see v4 was published just 12 days ago. I'll have to give
| it another shot! Thanks!
| bruh2 wrote:
| Love this project, used it quite a bit. However I always opt
| for using esno[1] instead, merely because of the name; having
| two tools share the same name throws me off.
|
| [1] https://github.com/esbuild-kit/esno
| madeofpalk wrote:
| > From v0.15, esno is essentially an alias of tsx
|
| heh. It really is https://github.com/esbuild-
| kit/esno/blob/master/esno.js
| quackware wrote:
| - Why include files, exports, and types in your package.json when
| you are just using ts-node to transpile on the fly?
|
| - 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.
| khalidx wrote:
| The "exports" and other sections are recommended things you'll
| need in your `package.json` file to support ESM. Sensible
| defaults. Also just points to an index.ts file (that you'll
| likely have in your project if you are developing a package).
|
| Also, this project can be compiled with `tsc` or a bundler, of
| course.
|
| In terms of speed, this should consistently start up an app or
| CLI in <3 seconds (depending on size of course).
| keb_ wrote:
| Also see TSM: https://github.com/lukeed/tsm
| WolfOliver wrote:
| Agree it is a little tricky to get startet. But once configured,
| it helps a lot
| jna_sh wrote:
| This is not a guide, it's three config files
| khalidx wrote:
| You're right, but what guide is easier than "Just add the
| following files and run npm run dev. You'll be good to go!".
| bilekas wrote:
| I'm personally against that belief as it doesn't really teach
| anything. Just adds a list of bootstrapping that you don't
| understand.
| jenscow wrote:
| There's only so much spoon-feeding that can be done. We
| already have so much information at our fingertips.
|
| If people just want to copy+paste it then mark a jira issue
| as complete, that's up to them.
|
| However, for those of us who want to understand - sometimes
| it's better to see a working example and pick at it.
| codingdave wrote:
| I find that almost all devs have a layer at which they
| don't understand what is going on. Everything we do is
| built on the shoulders of giants, as evidenced by how
| little we think about the 0s and 1s that are the actual end
| result of our work.
|
| So I don't see a problem with any dev having a line of non-
| understanding as they work. Some peoples lines are lower
| than others, but we all work that way. So it is all good.
| bilekas wrote:
| Absolutely, but don't call it a guide. When it's not.
| SPBS wrote:
| Sometimes the most valuable guide is a working example. Lord
| knows, there are so many docs out there that keep prattling on
| and on instead of showing me the code.
| chii wrote:
| a working example that you don't understand and just copy
| over and over again into new projects.
|
| This eventually turns into an incantation and magic. It's how
| crap gets built up and poor decisions get propagated.
| azangru wrote:
| > a working example that you don't understand and just copy
| over and over again into new projects.
|
| Once you have a working example, you can go through it line
| by line and figure out what it is doing.
| Feathercrown wrote:
| Which the author would be kind to do and post with the
| example.
| mst wrote:
| Honestly, I've always preferred to have somebody's
| example plus the reference documentation.
|
| Learning not only what it does but where it's documented
| - and having to go look for myself to do so - fixes it in
| my memory a lot better.
|
| I have a years old set of npm/etc. configs in a project I
| noodle on occasionally, and when I re-open them to look I
| remember exactly what they do -because- I started from a
| boilerplate and then went and learned how all of it
| works.
|
| That doesn't mean an explanation wouldn't still be
| helpful for a bunch of people who aren't me, but honestly
| having the tsconfig commented like that is more than
| sufficient for -me- to be happy.
| DangitBobby wrote:
| 99% of the working examples I encounter in JS config don't
| work by the time I get to them.
| pyrolistical wrote:
| this setup doesn't work with node test runner.
|
| I had to tsc then node --test the built files.
|
| tsx also is missing the test runner
| https://github.com/privatenumber/tsx/issues/257
| e1g wrote:
| With tsx instead of ts-node, it works just fine -
| node --import=tsx --test __tests__/\*/\*.test.ts
| pyrolistical wrote:
| Including failed tests?
| ivanjermakov wrote:
| And if you publush it, imports are going to be from
| 'pkg/dist/foo'..
| bovermyer wrote:
| In order to be a guide, I feel like it would need to explain
| _why_ each thing is there and what it does.
| EdSharkey wrote:
| A gist, the digital equivalent of scribblings on a stained
| cocktail napkin, lays bare the great mystery. The great dragon is
| slain! His precious treasure is of no value whatsoever.
|
| Fellow scrounging raccoons, raise your chipped mugs and cracked
| cups! Let us toast to our fortune, we truly are the blessed ones.
| w3news wrote:
| Why not using Node how it is designed, than ESM works great.
|
| 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.
| vasergen wrote:
| > The experience of using Node.JS with TypeScript, ts-node, and
| ESM is horrible.
|
| 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.
| khalidx wrote:
| I agree that the migration experience has been subpar! I
| dropped ESM migration of my packages 2-3 times before finally
| picking it up again and wrapping it up in a simple guide.
| Hopefully with the config I shared you'll find that you can use
| all those out-of-reach ESM packages now! Also, I provided
| examples for getting __dirname and __filename -like behavior.
| azangru wrote:
| > a better alternative
|
| Deno?
| jampekka wrote:
| https://gist.github.com/joepie91/bca2fda868c1e8b2c2caf76af7d...
| khalidx wrote:
| Strong agree. This has caused a major rift in the Node
| ecosystem (and for its packages).
|
| All we can do is adapt and keep building. Using Node v20 (LTS)
| currently with the config linked in the parent post.
| demurgos wrote:
| I always found it easier to avoid `ts-node` as it introduced a
| bunch of small compat issues.
|
| Since TS 4.5 and their support for `.mts`, I finally settled on
| just chaining `tsc --build && node ./build/main.mjs`.
| azangru wrote:
| And for development?
| demurgos wrote:
| With TS, I get type checking in the IDE; I don't need to
| rebuild every few seconds.
|
| When I actually need to build and test, it's very fast (<2
| seconds). I use Yarn workspaces/subprojects and TypeScript
| references with incremental builds so it's not really an
| issue.
|
| Here is the `package.json` [0] for a serialization lib I did,
| you can check the `scripts` section: it's very minimal and
| I'm quite happy with it. I'm an old Gulp maintainer, so for a
| long time I had heavy Gulp config with a lot of processing.
| Over the years I could get rid of it. ESM was the last thing
| holding me back; and now I'm so happy that I can just use a
| few simple commands.
|
| [0]: https://github.com/demurgos/kryo/blob/master/packages/kr
| yo/p...
| khalidx wrote:
| I generally agree with your statement, but have found ts-node
| incredibly valuable especially when developing servers or CLIs
| where I want to start/restart the process many times without a
| build step every time.
| SahAssar wrote:
| Node has a built in watch mode and so does tsc. So if you
| start both you should get what you want.
| beepbooptheory wrote:
| or: `tsc --build --watch` and then just have another terminal
| to run.
| demurgos wrote:
| Yes, TS now fully supports ESM so the watch mode works great.
| I'm not used to using it when working in Node, but other
| people I work with use it all the time.
| koolba wrote:
| Many people in this thread are rightly complaining that this does
| not answer the "why does this work". Having a working example is
| a good start for that though as at least you have a known target
| and as you change things (and break things), you can see what
| those options did.
|
| 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_.
| btown wrote:
| https://documentation.divio.com/ is a good overview of the
| "four types of documentation" paradigm: tutorials, how-to
| guides, explanations, and reference have to all exist.
|
| One of my major gripes with the JS/TS ecosystem is that
| "explanations" are sorely lacking. See
| https://www.typescriptlang.org/tsconfig for the relevant
| documentation for tsconfig files. Tutorials are on the page,
| how-to guides abound on the wider internet (like the OP), and
| the linked TSConfig Reference and JSON Schema (used in code
| completion in IDEs) are together absolutely massive.
|
| But an explanation is missing! There is no official
| documentation about how different options interact to say: as
| I'm walking a file tree as the Typescript compiler, this is how
| I will interpret a certain file I encounter, what will be
| outputted, and how that will be interpreted by bundlers and
| browsers, especially in an ESM world.
|
| https://medium.com/extra-credit-by-guild/tsconfig-json-demys...
| is in the right direction, but outdated as ESM has become much
| more popular in the past 3 years, and still organized by option
| (so it's already somewhat in the "reference" world).
|
| IMO even independent of documentation, the industry's move to
| ESM is problematic:
| https://gist.github.com/joepie91/bca2fda868c1e8b2c2caf76af7d...
| describes many of the issues. But they're certainly exacerbated
| by good explanation-style documentation that helps people
| understand how ESM works under the hood!
| paddy_m wrote:
| What programming languages and libraries are well explained
| in this aspect?
| Macha wrote:
| Python, Rust. Given that Python was one of the first open
| source projects to choose such a model, and Rust explicitly
| adopted such a model, that's probably not so surprising.
|
| (Somebody is going to bring up the Python packaging
| clusterfuck as a retort to this, but the fact that Python
| packaging is both assumed and held at a distance is a
| larger problem than just documentation)
| mst wrote:
| I once did a conference talk on the different types - called
| it Euclid, Socrates and Mill and analogised a good tutorial
| to Euclid's Elements, the explanation part to Socrates and
| howto/cookbook type stuff to John Stewart Mill.
|
| (don't remember if there's a decent video out there but I
| figure you probably don't need to listen to me waffle to see
| how the analogies might work ;)
| mook wrote:
| It's not even that great, typescript doesn't even have a good
| reference. There are random features that are only documented
| on release notes.
|
| Working with TS has been somewhat frustrating.
| jakebailey wrote:
| > One of my major gripes with the JS/TS ecosystem is that
| "explanations" are sorely lacking. See
| https://www.typescriptlang.org/tsconfig for the relevant
| documentation for tsconfig files. Tutorials are on the page,
| how-to guides abound on the wider internet (like the OP), and
| the linked TSConfig Reference and JSON Schema (used in code
| completion in IDEs) are together absolutely massive.
|
| > But an explanation is missing! There is no official
| documentation about how different options interact to say: as
| I'm walking a file tree as the Typescript compiler, this is
| how I will interpret a certain file I encounter, what will be
| outputted, and how that will be interpreted by bundlers and
| browsers, especially in an ESM world.
|
| Perhaps you missed it, but Andrew (from the TS team) recently
| finished a massive overhaul of our module docs: https://www.t
| ypescriptlang.org/docs/handbook/modules/introdu...
|
| The "theory" page describes TypeScript's perspective on
| modules. The "reference" page documents things from the "as
| I'm walking a file tree" perspective (among many other
| details). The "guides" page also provides recommendations for
| certain kinds of projects.
| paradite wrote:
| I am pretty sure "type": "module" doesn't work with React
| Native/Expo and jest (in 2022 last time I tried).
|
| 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.
| Rapzid wrote:
| Module resolution "bundler".
|
| ts-node --esm --swc
|
| Haven't really had any issues with this in a long time.
| tuyiown wrote:
| Add eslint and jest to pull your hairs of you head. I managed to
| get it right last week, but I'm pretty confident that next
| upgrade I'll have to revise most of it.
| rickstanley wrote:
| Have you considered using Vitest? Its performance has had a
| significant impact on my workflow and the workflow of my
| colleagues. It supports ESModules by default.
| tuyiown wrote:
| Ah! thanks a lot, I'll give it a good look next round, but I
| won't have much difficulty moving from jest, because its old
| roots triggers too much unexpected and hard to anticipate
| constraints.
| drtgh wrote:
| Node.js, TypeScript (compiled script...), ESM modules, versions,
| and the dependencies tree hell... You guys are adopting the
| masochism, the problem is that you are dragging the rest of us
| into that hell.
| bovermyer wrote:
| I'm going through a special version of this hell right now at
| work. I'm updating old Lambdas that are on the node.js 12
| runtime.
|
| Some of them have internal dependencies that just _no longer
| exist_, or aren't compatible with Node past 14.
|
| Meanwhile, all I had to do to update old Python Lambdas was
| just update the runtime itself.
| postalrat wrote:
| https://www.google.com/search?q=python+version+hell
| bovermyer wrote:
| Note that in my original comment, I didn't say Python
| doesn't have version problems. I said my (specifically my)
| Lambda version migration problems were much worse with
| Node.js than Python.
|
| Also, I'm vaguely offended that you used a "let me Google
| that for you" reply as your sole comment. Did you really
| have nothing more intelligent to add than low-effort snark?
| Go back to Reddit.
| postalrat wrote:
| A lot of people have versioning problems in all
| languages. You said "Meanwhile, all I had to do to update
| old Python Lambdas was just update the runtime itself. ".
| You know that isn't always true in Python that you just
| update the runtime and nothing goes wrong.
| dclowd9901 wrote:
| It's only the module resolution bullshit. Typescript is
| amazing, but module resolution between the browser and node is
| so terribly fraught it kills the whole experience.
| postalrat wrote:
| What is the alternative? Commenting on hn and reddit?
| dangoodmanUT wrote:
| This is why I use bun now! It just works, NodeJS is such a shit
| show right now, feels like the python 2->3 move.
| davidy123 wrote:
| I tried to use Bun but it doesn't support some low level Node
| APIs properly, in my case for Playwright. Keeping an eye on it
| though, what I saw seeemed promising.
| sroussey wrote:
| Make an issue. I did so for various compat issues and they
| are fixed now.
| davidy123 wrote:
| There are already long running issues on this topic.
| https://github.com/oven-sh/bun/issues/2492
| jzig wrote:
| I've been curious about using Bun. Could you point to an
| example of something like Node backend code that's written in
| TS using Bun?
| monooso wrote:
| I see (and have participated in) a lot of this "just copy this
| thing, trust me it works" type of content related to Node and
| TypeScript.
|
| 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.
| mark_and_sweep wrote:
| Being using Deno for new projects for years now. Not looking
| back.
| robbywashere_ wrote:
| What are the advantages of deno over node?
| flohofwoe wrote:
| Not the parent, but one very nice aspect is that an entire
| working Deno installation is just one file: the actual deno
| executable.
|
| ...when installing via homebrew on Mac you get 3 more files
| which look like shell-completion definitions:
| bin/deno etc/bash_completion.d/deno
| share/fish/vendor_completions.d/deno
| share/zsh/site-functions/_deno
| e1g wrote:
| Both Node.js and Bun are also single executables. Node.js
| doesn't (yet) transpile TS for you, and that's a single
| dependency away.
| flohofwoe wrote:
| Yeah I was confused that the Node installation directory
| was showing me 18k files in several thousand directories,
| but these seem to be global npm installs which npm seems
| to put into the node installation directory (which tbh is
| weird, I would expect those somewhere in my user
| directory).
| flohofwoe wrote:
| I prefer Deno over Python now for "cross-platform shell
| scripting", because the "import directly from a github
| repository" is very nice for that use case. Haven't tried it
| yet as direct replacement for npm/node.js though (mainly
| because I'm unsure yet how well it works as a drop-in
| replacement when other people continue using npm and node.js).
| vinibrito wrote:
| Deno still has quirks, like not running on ARM processors.
| mmastrac wrote:
| I work on Deno, specifically the CLI. We support both Mac and
| Linux ARM, though the Linux ARM builds are currently produced
| by a third party contributor.
|
| If you have specific issues with ARM, I'm certainly
| interested in fixing those. I don't have any timeline for
| when we'll add Linux ARM as a binary release target but I'm
| happy to ensure any ARM-only bugs get the proper attention.
| no_wizard wrote:
| Does that mean deploying Deno to AWS Graviton is an issue
| currently?
|
| Thats the use case I have in mind to cut costs
| mmastrac wrote:
| I haven't specifically tested it but it _should_ be
| supported. I don't have easy access to graviton instances
| at this moment, but I've previously used
| https://github.com/LukeChannings/deno-arm64 with great
| success.
|
| As long as your ARM OS is 64-bit, Deno should function
| properly. 32-bit _might_ be supported, but TBH we don't
| do any testing of those configurations as far as I'm
| aware.
| flohofwoe wrote:
| Weird, when I run 'file deno' on my ARM Mac I get:
| deno: Mach-O 64-bit executable arm64
|
| ...also haven't experienced any problems so far.
| spion wrote:
| How about in Docker on ARM Mac?
| mmastrac wrote:
| No official docker images, but lukechannings maintains
| ARM/Linux builds and an unofficial docker container that
| are well supported:
|
| https://hub.docker.com/repository/docker/lukechannings/de
| no
| willsmith72 wrote:
| I've tried both, and love their potential.
|
| I would highly advise any startup considering using them to
| reconsider. You don't want your business to being running into
| rough edges all day. You don't want to be reinventing things
| all day.
|
| They're fun, and especially deno is really fun. It feels more
| like go, where you control everything.
|
| But they're still not nearly as productive as node
| monooso wrote:
| Can you expand on what you mean by "not nearly as productive
| as node"? I've found the opposite to be true, because of the
| simplified tooling.
|
| That said, most of my Deno projects have been fairly basic,
| so I'm curious if there's a point at which the early wins
| give way to hidden pain points.
| ravenstine wrote:
| Yeah, I use it for anything new, though so far it's been
| primarily hobby projects, including a sort of larger one I
| haven't gotten off the ground yet.
|
| I wouldn't necessarily suggest that a newbie programmer go
| right to Deno yet because today you still have to be prepared
| to deal with some differences and quirks.
|
| But here is why I like Deno:
|
| - Typescript pretty much Just Works (TM) out of the box without
| having to think about it
|
| - More web/browser APIs right out of the box with less Node-
| specific weirdness. Anything that is Deno-specific (such as
| anything that lives on the Deno global) is, in my opinion,
| better designed than Node's APIs.
|
| - Requiring file extensions in import specifiers makes total
| sense to me. Some people think this is stupid, but I see no
| reason not to make them actual file paths and not this sort of
| pseudo file path that omits the extension.
|
| - I like how Deno can bundle your application into a single
| executable.
|
| - Testing framework and linter are built right in. Which is
| great because, let's face it, most of us have been using such
| things for a very long time now.
|
| - Being able to pull in modules from the web without NPM is
| fantastic.
|
| - Node.js and NPM compatibility has gotten _way_ better
| recently.
|
| - Binary data is handled as Uint8Array rather than using a non-
| standard Buffer like in Node. Makes total sense. Skip the
| middle-man and just give me the bytes in a widely compatible
| form.
|
| - Granular security with strict permissions by default is
| really nice. Sometimes I do want to import a module but then
| have a guarantee that third-party code won't phone home. It's
| also flexible enough that you can allow your own code to reach
| your own domains but then some module you import from elsewhere
| doesn't send data to some other domain. I'd still choose to not
| use such modules, but it's good that you can mitigate the risk
| of malicious code without having to do anything.
|
| And sure, Node has improved a lot since the inception of Deno
| and will continue to improve. It can probably do some of these
| things and may end up having more parity with Deno. I don't
| think that Node is bad. I still use Node, primarily at work,
| and in cases where a package has maintainers that refuse to
| support Deno (ex. Playwright).
| conaclos wrote:
| I would love to use Deno, however it is not totally compatible
| with the TypeScript ecosystem: it is not possible to import a
| TypeScript file using the `js` extension. This is a dealbreaker
| for me because by adopting the `ts` extension you make your
| code deno-specific; You can no longer use TSC, ESbuild and the
| like.
| wrs wrote:
| Not sure what you mean? Our whole codebase is .ts files, and
| we use tsc and esbuild without apparent difficulty.
| conaclos wrote:
| I mean, if you have a file `mod.ts`, in Deno you cannot
| import `mod.ts` using the following import:
| import {} from "./mod.js"
|
| You have to write: import {} from
| "./mod.ts"
|
| ESbuild doesn't transform source imports. Thus, by
| transpiling your code using ESbuild, you get an erroneous
| import that leads to a runtime error in browsers and Node.
| The case is worse for TypeScript, because it refuses to
| tarnspile this code.
|
| By the way, bundling with ESbuild is possible, however when
| you write a library you generally want to transpile the
| code, not to bundle it.
| pipe01 wrote:
| I use esbuild to import .ts regularly, I'm not sure how
| you came to that conclusion
| iainmerrick wrote:
| ESbuild has handled ".ts" imports for as long as I've
| used it.
|
| TSC recently added a flag that allows ".ts" imports too.
| bartlomieju wrote:
| Bartek from the Deno team here. We are working on making this
| possible with a flag in the upcoming release.
| methodical wrote:
| This may be a luddite-esque take, but personally, I'm very
| hesitant to use Bun on any meaningful project at the moment. It
| screams too-good-to-be-true right now. I also believe that I
| may have heard of some people running across issues with it
| recently, although I maybe conflating my memory of it with
| something else. That, and, while I understand the namespace
| pollution with JS packages, saying that I use "Bun" for my
| projects is a bit of a turn-off, to be quite honest. I may try
| it for some pet project in the near-term future but if I was to
| make a choice for anything else I see operating long term I'd
| be much more inclined to use Deno, although I still think even
| that is probably a bit less established then I'd prefer, so I'd
| probably still use Node until Deno matures a bit more.
| plopz wrote:
| i think its reasonable to hesitate on using something less
| than 2 years old. it does a lot of things that look good to
| me, but im happy to wait a few years and see. it still needs
| to get buy in from people who maintain packages, for example
| just try using puppeteer with it. and its also not clear to
| me how its going to make money.
| davedx wrote:
| Because deno is strongly opinionated on things other than the
| language and module system. I don't want to use golang style
| dependencies. I don't want all the upsells that come with using
| deno. It's an island unto itself.
| monooso wrote:
| Upsells?
| yencabulator wrote:
| They are pushing their SaaS pretty hard, these days.
| imbnwa wrote:
| Bun is gonna prolly end up doing the same thing though
| keb_ wrote:
| Deno is great, and I use it where I can, but a lot of front-end
| tooling still treats it like a second-class citizen including
| esbuild.
| talkingtab wrote:
| Prefer not to use Deno.
|
| First, my personal choice is not to use TypeScript. For me it
| just adds a layer of complexity that adds very little. That I
| am a sole developer certainly is a factor in that decision. And
| history. I worked with Java for a long time, with all the
| safety it provides, only to find that PHP and JavaScript
| programmers could ship in 1/4 the time with the same level of
| functionality. I find that passing named parameters:
| `foo({animal: "duck"})` makes my plain old javascript much more
| robust, with very little cost.
|
| So strike #1 against Deno is that it puts typescript much more
| in the foreground.
|
| Strike #2 is that Node works. Not because it is right, but
| because services make sure they work with node. They don't put
| the same effort into making things work with Deno.
|
| I needed to write code using Deno that talked to a Digital
| Ocean managed Postgres database. I spent three days. Then I
| decided not to use Deno. Was this Deno's fault? No. But if you
| need to get things done and one in 1000 of those things works
| in Node but not in Deno, then the choice is straight forward.
|
| I'm not saying these are good reasons, but I did try Deno and
| wanted it to work.
| petre wrote:
| While I mostly agree with you, I hope deno removes at least
| part of the nodejs mess when becomes ready for prime time.
| It's already better designed in so many ways. Then I can
| safely ignore the typescript functionality that, like you
| said, ads too little value for me. This is mostly wishful
| thinking. If deno doesn't deliver, maybe bun will. The funny
| thing is they are trying to improve deno by adding
| compatibility to the same nodeisms that make node such a
| messy experience, like package.json and node_modules. Once
| these will get used out of habbit, there is no going back.
| davidy123 wrote:
| I'm going to keep hitting reload on this page until someone
| solves some of the worst problems of my work life right now;
| getting a npm monorepo with typescript, eslint and jest working
| smoothly. Thank you to whoever(s) that is. I'm trying to make a
| public project, but building/developing with it is successive
| layers of sometimes-works voodoo that have nothing to do with the
| project goals. Somewhat compounded when members of nx (nee lerna)
| popped in to try to help, adding another layer of sometimes-
| works. As it is, DX depends on a fast computer to basically
| rebuild the whole thing each time, or running build & test in a
| dozen workspaces, because I haven't found any other reliable
| "workflow."
| searchableguy wrote:
| We gave up and switched to vitest.
| flohofwoe wrote:
| +1 for vitest :D I was amazed that it "just worked" after
| struggling for hours getting jest to work because of silly
| file extension problems (really... what's up with that...
| wouldn't that be easy to fix if the Node.js and Typescript
| teams would talk for 5 minutes and agree on one approach?)
| davidy123 wrote:
| I don't use Vite though. Aside from typescript, I'm trying to
| be as vanilla/unopinionated as possible, using Web Components
| for example. And there are hundreds of Jest tests I don't
| want to port.
| flohofwoe wrote:
| You can use vitest like a standalone testing tool, it will
| install vite as dev-dependency but you don't need to build
| your whole project around vite.
|
| In my case it was literally a drop-in-replacement for jest,
| done in two minutes and without a config file. A simple
| config file only was required a bit later when I added
| test- and coverage-reporting as junit.xml and cobertura
| format for Gitlab CI.
|
| Didn't even have to change a single line of testing code (I
| didn't use Jest's mocking magic in that project though).
| davidy123 wrote:
| Thank you, it sounds pretty good, especially solving the
| modules problem. I will look into it when finished
| current sprint.
| tommy_guo wrote:
| This is the current setup I'm using for my TypeScript monorepo:
| https://github.com/tommyguo/node_monorepo. I tried avoiding
| Lerna because I didn't feel like I needed it. Happy to hear
| feedback!
| davidy123 wrote:
| Thank you, I will take a look after current sprint.
| dimgl wrote:
| We dropped Jest and switched to Vitest across the entire stack.
| It's a shame what happens to these projects over time...
| resters wrote:
| I thought there were "presets" that NPM and Yarn knew about to do
| this kind of thing...
| sirius87 wrote:
| The current ESM experience makes it seem like decision-makers in
| the node.js project were wilfully oblivious to how large the
| TypeScript community was and how it was being used in node
| modules and projects. It really does feel like the maintainers
| focus was on JS and harmony with TypeScript's evolution was low
| on the priority list.
|
| 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.
| madeofpalk wrote:
| I really enjoy frontend/node/typescript development. I roll my
| eyes whenever the HN-types complain about CSS or frontend
| development being a hellhole. Mostly the comments I see seem
| ignorant or impatient ("Why doesn't this thing work without be
| bothering to learn it?")
|
| _However_ , the intersection of typescript, nodejs, and ES
| modules is consistently the most frustrating experience I ever
| have. Trying to figure out which magic incantation of
| tsconfig/esbuild/tsc/node options will let me just write code
| and run it is a fools errand. You might figure something out,
| and then you try to use Jest and then you descend into madness
| again.
|
| The biggest tip I can give people is to ditch ts-node and just
| use (the awkwardly named) tsx
| https://github.com/privatenumber/tsx, which pretty much just
| "mostly works" for running Typescript during dev for node.
|
| The problem mostly seems to stem for all the stakeholders being
| pretty dogmatic to whatever _their_ goals are, rather than the
| pragmatic option of just meeting people where they are. I
| really wish the Node, Typescript, Deno /Bun, and maybe some
| bundler people would come together and figure out how to make
| this easier for people.
| sirius87 wrote:
| Totally agree.
|
| It's doubly frustrating because a standard for authoring
| modules across browser and server platforms such as ESM is a
| good thing. But it's a bit arrogant to expect module authors
| across TS and JS ecosystems to ship overnight. Beginners may
| just turn to Deno or Bun simply because hundreds of coding
| tutorials and snippets no longer work.
|
| Or, when you finally get a TS config that works but then you
| import @aws-sdk/* or prisma seeds and then you _really_ rip
| your hair out.
| quickthrower2 wrote:
| I am finding whatever NextJS does "just works" and I hit
| issues when I roll my own stuff. But I have't dug deeply
| into how they do it yet.
| Shacklz wrote:
| Couldn't agree more. Love the frontend-space, love the
| ecosystem, but hate the whole ESM vs. CJS fiasco with a
| passion.
|
| To some degree, I think the typescript-team itself also has
| to take some blame here. I understand their point that they
| do not want to do any rewrites, and to some degree it makes
| sense, but if the ecosystem as a whole really wants to move
| forward to a common understanding of how it _should_ work,
| someone needs to do the heavy lifting for dev-experience, and
| right now they 're best-equipped to actually solve the
| problem, or at the very least help us a lot in doing so.
|
| Their dogmatic approach makes sense for the scope they set
| out with when starting with typescript but in my eyes refuses
| a bit the reality the ecosystem currently finds itself in.
| And I'm saying this as an absolute ts-fanboy; it's one of the
| very few things about typescript that I take an issue with.
| eyelidlessness wrote:
| I'm curious what it is you think TypeScript could do, or
| could do differently, to address the situation. Or what you
| think they've been dogmatic about, and what reality they've
| refused [to see? to accept? to fix? unclear what you mean]?
| galactus wrote:
| So much this.
| teaearlgraycold wrote:
| Once Bun is feature complete I'm jumping ship
| johnfn wrote:
| Agreed with everything, except this:
|
| > I really wish the Node, Typescript, Deno/Bun, and maybe
| some bundler people would come together and figure out how to
| make this easier for people.
|
| Bun _has_ solved this. Bun is straight-up magic; they 've
| implemented tons of hacks and heuristics so everything just
| works. Bun can even handle ridiculous or otherwise invalid
| code, like having import and require in the same file.
| madeofpalk wrote:
| My point here is that Bun should go teach Node how to be
| pragmatic and build a good developer experience
| johnfn wrote:
| Oh, yeah, totally agreed then.
| yencabulator wrote:
| > tons of hacks and heuristics
|
| So, business as usual in the Javascript space. That's how
| the ecosystem got here, and why nothing works reliably.
| johnfn wrote:
| Like I said in my comment, Bun works just fine. You seem
| to have taken 5 words I said out of context to justify
| something that I didn't say. It's not true that "nothing
| works reliably". Bun works reliably.
| edgyquant wrote:
| I've never heard of bun before today. Why is it so low key
| and what's it main selling point?
| kristiandupont wrote:
| What are your main sources of tech news? Bun has been
| quite a darling here for a while..
| phatskat wrote:
| My own primary news source these days is HN and I've
| missed anything about it, your comment isn't really
| helpful.
| kaliqt wrote:
| How hard would it be to migrate a node project to Bun
| though? I want to move, but I'm not sure.
| johnfn wrote:
| Should be a drop-in replacement.
| mardef wrote:
| Bun has solved this, unless you have developers on Windows.
| brundolf wrote:
| For projects where I can, I've moved to Deno and never looked
| back. It's blissful over there
| yencabulator wrote:
| Except when you need libraries from npm, and then you have
| a choice 1) use npm: imports and watch things not work 2)
| use esm.sh imports and watch supposedly-immutable URLs
| change their contents all the time, _and_ be ready to pile
| on kludges to get transitive dependencies to behave.
| bartlomieju wrote:
| Bartek from the Deno team here. You can also use
| `package.json` and bare specifiers with Deno. We also
| recently added `--unstable-byonm` flag (Bring Your Own
| Node Modules) that allows you to manage `node_modules/`
| be the package manager of your choice. In other words,
| you should be able to drop Deno into an existing Node
| project.
| brundolf wrote:
| I have had mixed results when using NPM libraries, but I
| also haven't run into any cases yet where I absolutely
| needed them
|
| Some stuff you might reach out to NPM for is built into
| Deno's standard library. Other stuff has become built-in
| JS language features over the years. And the ecosystem,
| while nowhere near as big as NPM's, seems to have all the
| most important stuff at this point, at least for back-end
| work
|
| And if I have to fill gaps by reinventing some small
| wheels here and there, or by interning and converting an
| NPM library, that's still worth it to me to avoid all the
| tooling headaches
| lacrosse_tannin wrote:
| How about not using Jest?
| zerobrainwash wrote:
| Relieved to hear I'm not the only one. I always blamed myself
| for not understanding it deeply enough. But admittedly, it is
| a shit snow and the most frustrating part of development.
| qudat wrote:
| > I roll my eyes whenever the HN-types complain about CSS or
| frontend development being a hellhole. Mostly the comments I
| see seem ignorant or impatient ("Why doesn't this thing work
| without be bothering to learn it?")
|
| I'd also argue that outsiders looking into all the complexity
| are ignoring the complexity within their own specialization:
| https://bower.sh/front-end-complexity
|
| It's hypocritical thinking.
| cjr wrote:
| Hard agree, especially with your first two paragraphs :)
|
| The biggest tip I would add is to bin jest and start using
| vitest.
| rtpg wrote:
| Honestly I think the blame[0] is to share across the board. I
| have read through a bunch of typescript lang issues on this
| topic, and the general issue is that Typescript doesn't want
| tsc to do certain kinds of rewrites during compilation (code
| transpilations that go beyond the most simple things).
|
| This makes sense but honestly means a lot of QoL fixes are
| kinda impossible to do. At this point I, personally, would
| almost want tsc (the compiler component) to stop being almost a
| good bundler and remove some features. Every project I've
| worked on that uses tsc directly ends up needing a "come to
| Jesus" moment where a "real" bundler gets introduced and
| suddenly a lot of stuff becomes easier. Doubly frustrating for
| me to feel this because tsc does a lot of stuff and it is hard
| to imagine how Typescript the language moves forward without
| Typescipt the compiler. I just really don't want to type `.js`
| for files that are, pre-build, `.ts`.
|
| [0]: "blame" here meant in the weakest sense of "there are
| people who could make decisions in another way to make this
| better". Not so much in assigning moral blame
| iainmerrick wrote:
| I still don't fully understand why TypeScript needed to be
| involved in the discussion at all. TSC tries to do far too
| much and doesn't do most of it very well. The tsconfig format
| is restrictive and annoying.
|
| TS would be a lot better if it were just a type checker and
| nothing else (which is more or less what you get when you
| switch to a proper bundler).
| mofle wrote:
| TypeScript had years to prepare for ESM, but they did not. Same
| with Jest. ESM was developed in the open and anyone could
| participate, including the TypeScript team. You are talking
| like ESM just happened overnight. It had been in development
| for 10 years.
|
| Node.js released initial ESM support [1] in Node.js 12.17 in
| May 2020, 2 years later (!), TypeScript finally added support
| for ESM [2].
|
| Here's a straight forward guide on how to use TypeScript with
| ESM:
| https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3...
|
| [1]: https://nodejs.org/en/blog/release/v12.17.0
|
| [2]: https://devblogs.microsoft.com/typescript/announcing-
| typescr...
| sirius87 wrote:
| Curious to see how this one decision plays out for nodejs IF
| -
|
| - module authors increasingly adopt ESM
|
| - TypeScript experience with Deno is butter smooth
|
| - npm packages work with Deno
|
| - performance characteristics are similar
|
| - DX for beginners just works (compared to thousands of stale
| articles with `require('pkg')` and `npm install pkg@latest`
| for nodejs)
| wwwigham wrote:
| > ESM was developed in the open and anyone could participate,
| including the TypeScript team.
|
| This point stings for me, personally, since _I_ was the
| TypeScript language dev _in_ this wg trying to make our
| concerns noted, because we certainly did participate. However
| the group largely deadlocked on shipping with ecosystem
| compatibility measures, and what you see in node today is the
| "minimal core" the group could "agree" on (or be bullied into
| by group politic - this was getting shipped weather we liked
| it or not, as the last holdouts). The group was dissolved
| shortly after shipping it, making said "minimal core" the
| whole thing (which was the stated goal of some engineers who
| have since ascended to node maintainer status and are now the
| primary module system maintainers), with the concerns about
| existing ecosystem interoperability brought up left almost
| completely unaddressed. It's been a massive "I told yo so"
| moment (since a concern with shipping the "minimal core" was
| that they would _never_ be addressed), but it 's not like
| that helps anyone.
|
| Like this shipped, because _in theory_, it'd be a non-
| breaking from a library author perspective to get node's CJS
| to behave reasonably with ESM (...like it does in `bun`, or
| any one of the bundler-like environments available like `tsx`
| or `webpack` or `esbuild`), and _in theory_ they're open to a
| PR for a fix... I wish anyone who tries good luck in getting
| such a change merged.
| stephen wrote:
| Fwiw I appreciate your effort! That sounds really
| frustrating.
|
| I agree the recent bun/tsx/esbuild (but bun especially) has
| shown the node CJS/ESM fiasco was a bit of an emperor-
| wearing-no-clothes moment, where I think us every-day JS
| programmers just trusted the node devs at their word, that
| CJS/ESM had to be this painful...
|
| But now, seeing that it doesn't have to be that way, it's
| like wait a sec...the last ~5 years of pain could have been
| avoided with some more pragmatic choices? Oof.
| eyelidlessness wrote:
| > TypeScript had years to prepare for ESM, but they did not.
|
| How did they not? This is confusing to me, as I've been
| authoring and emitting ESM in TS for quite a few years now.
| joshkel wrote:
| As someone who uses Jest and alternatively enjoys and is
| frustrated by it, this isn't all Jest's fault. Node is just
| now releasing fixes for [significant memory leaks](https://gi
| thub.com/jestjs/jest/issues/11956#issuecomment-180...) around
| ESM support within the [VM
| APIs](https://nodejs.org/api/vm.html) that Jest depends on.
| wruza wrote:
| _when he flipped to ESM for his bajillion libraries_
|
| But that was just a short migration period. It's only been
| three years and we almost fixed all these issues. This one is
| probably the last one, this month.
| sirius87 wrote:
| FWIW it wasn't meant to sound critical of him, his
| contributions are much loved and his attempt to push to ESM
| was also in good spirit with his helpful gist on the issues,
| but ESM was no silver bullet for the wide mix of imported
| modules in some projects.
|
| I remember spending a weekend simply inlining all his module
| code directly into a project to sidestep the type module
| change. Fun.
| wruza wrote:
| Not fun really. I am critical (of everyone involved). We
| were asked to migrate under a promise it'll be over soon.
| "It only needs a little kick", they said, ignoring everyone
| and vandalizing the loved contributions. Years passed and
| we:
|
| - still stumble upon it even in _fresh projects_
|
| - have no esm-only bundle-less projects in practice,
| because it's still impractical
|
| - learned a bookshelf each about the thing that should just
| work
|
| - watch entire toolchains decay into a shitton of date-
| dependent issues
|
| - have no clear troubleshooting paths, even when we have a
| clue what's wrong
|
| They forcefully promised some bright future, we helplessly
| agreed.
|
| Where the bright?
|
| Three years later, I lost half an evening to [1] again. My
| love and politeness reserves are depleted.
|
| [1] https://news.ycombinator.com/item?id=38365983
| jampekka wrote:
| Makers of ESM were wilfully oblivious to sanity. CommonJS
| was/is one of the, if not the, best module and dependency
| systems out there.
|
| https://gist.github.com/joepie91/bca2fda868c1e8b2c2caf76af7d...
| brundolf wrote:
| Being imperative instead of declarative, it hinders a host of
| key optimizations like parallel loading and dead code
| elimination
| jampekka wrote:
| This is discussed in the link I posted. Bundlers manage to
| statically analyze CommonJS just fine. With
| require("stringliteral") and exports.thing = thing, that
| cover 99.9% or so usage, this is just as easy to statically
| analyze as ESM.
|
| Saying that you need declarative for static analysis is
| like saying tail call optimization is impossible.
|
| And if a stricter module system would be still required, it
| could have been quite easy to make compatible with, well,
| require.
| petre wrote:
| Require is fine but I totally hate the CJS exports. Feels
| like writing '90s era Perl code. On the other hand ESM
| dynamic imports like
| import('this').then(r => that())
|
| rather suck.
| madeofpalk wrote:
| I find this mostly unconvincing (except for the part where
| all the tools messed this up and made the problem more
| difficult).
|
| It's not clear to me how you get top-level await with CJS
| with significant drawbacks OR breaking changes that would
| just end up back up in ESM land.
| jampekka wrote:
| The convoluted byzantine mess that is ES top level await is
| a self-inflicted problem stemming from the ESM bizarre pipe
| dream that static import won't be a blocking operation for
| code that depends on the imported code.
|
| With blocking require there's of course no problem with top
| level await. And having a thenable import doesn't even need
| any language level support.
|
| Yeah, you can parallelize static imports. But you can just
| as well doing this by having a semantically blocking
| require that is free to of course do whatever it wants as
| long as the execution is sequential in effect.
|
| If there's some dynamic trickery the implementation can't
| figure out, just revert to blocking and nag in the console.
| ptx wrote:
| The post dismisses native browser support (a huge benefit of
| ES modules) as "an utterly useless feature" that's
| "unavoidably slow" because of the additional roundtrips
| needed as the dependency tree is traversed.
|
| But this problem has been solved by modulepreload[0], also
| natively supported in the browser, which lets you specify the
| modules upfront in the HTML, avoiding the need for additional
| roundtrips. Tooling could help with generating the list of
| preloads but is not necessary.
|
| [0] https://developer.mozilla.org/en-
| US/docs/Web/HTML/Attributes...
| jampekka wrote:
| Tooling could also analyze the dependencies and create
| appropriate bundles of the code to avoid roundtrips.
| Actually such tooling has existed for over a decade and are
| used by practically all but simplest Javascript
| applications.
|
| I'm all for development without a compilation step. I've
| written hacks to resolve node modules and transpile in
| browser to avoid compilation. Implementing prefetching even
| with this hack would be less hacky than going full circle
| and injecting HTML tags to do the prefetching.
|
| ESM is like XML: The problem it solves is not hard, and it
| doesn't solve the problem well. Actually ESM it isn't even
| close to solving the problem after trying for almost 15
| years.
| ptx wrote:
| As you say, tooling can solve the problem. But with ES
| modules and modulepreload, we can now (contrary to what
| the post argues) also solve it without the tooling, which
| is an improvement.
|
| Yes, all but the simplest applications currently use the
| tooling-based solutions, because there was no other way.
| But now that we have an alternative solution, perhaps all
| but the most complex applications will manage just fine
| without tooling, using just the built-in module support.
| alexcroox wrote:
| Experienced that this week! Upgraded to node 20 and typescript
| and his p-limit lib was the source of a lot of pain. No matter
| how much I changed the tsconfig I just couldn't get it to work
| with the subpath imports his lib used. Ended up downgrading the
| lib to previous major and moving on.
| andrewaylett wrote:
| The good news is that one may use `expect` with Node's built-in
| test runner -- the result feels fairly similar to using expect
| with Jest.
|
| Indeed, Node's test support can handle dynamic test creation,
| so one can do crazy things like
| https://github.com/andrewaylett/prepackage-checks/blob/main/...
| -- that dynamically asynchronously executes NPM builds from
| subdirectories, loading and running per-build expectations.
| unflxw wrote:
| My impression is that Node.js has to be dragged kicking and
| screaming into any modern JavaScript development practices, and
| each time, they try to support as little of it as possible as
| they can get away with.
|
| They have only last year actually rolled out a release that
| uses ESM modules by default, when the bulk of the community has
| adopted TypeScript and moved on to using ESM imports (even if
| they are importing CJS modules under the hood)
|
| They were really late to async/await, and even more so to
| promises. The chaotic situation where each dependency bundled
| its own promise library remained in Node.js years after
| browsers shipped built-in promises. And it still hasn't
| trickled down to their standard library, most of which is still
| callback-based and needs to be "promisified" manually. Even
| their support for fetch, which is eight years old at this
| point, is still marked as experimental.
| w3news wrote:
| That it why i use native functions. No typescript syntax, no
| jest. For testing i use just the native test runner, and that
| works great with ESM. Jest has indeed still not good ESM
| support, you can do some Babel trics, but makes the process too
| complex. Best is to find an alternative, like the native test
| runner. Also typescript try some things that are not stable at
| ecma. It was too soon with the import/export, and dont use the
| native way. Also commonjs is still the default at typescript
| after compiling, but Node is moving to ESM as a default. I hope
| typescript will use more native functions that are already
| available and dont use their own way.
|
| For me typescript syntax and jest is a no go.
|
| Typescript is useful to check types, but i write just
| JavaScript with JSDoc, and check it with eslint in typescript
| modus.
| bearjaws wrote:
| Main reason I even tried bun out. Honestly 'just works', I've
| only had one issue so far and it was with a unpopular compiled
| module.
| sroussey wrote:
| I love it. Had some issues with terminal stuff, now fixed.
|
| Just works, indeed.
|
| But I have a difficult time trying to get a project make to
| node/ts.
| mst wrote:
| I'm really enjoying bun for my own stuff but tsx looks more
| promising for work projects.
| solatic wrote:
| Having tried to wrangle all of this both professionally and for a
| side project, the link is an over-simplification. No, it won't
| "just work".
|
| 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.
| _nalply wrote:
| One problem I encountered with ESM TypeScript development on the
| browser without bundling: many Node packages aren't set up for
| that.
|
| 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/
|
| [1]: https://github.com/nalply/modglot
| cantSpellSober wrote:
| Does Node.js plan to transpile TS out-of-the-box soon? (Picking
| up a legacy project, can't swap out for Deno or another runtime
| just yet)
| khalidx wrote:
| This would be a nice direction for the Node community. I wish
| for this. Especially since so many other platforms are
| supporting it out of the box.
| tommy_guo wrote:
| Sharing https://github.com/tommyguo/node_monorepo if this helps
| folks. It's a Typescript monorepo template with everything you
| need included.
|
| I'm currently using this setup to run multiple services on AWS.
| preommr wrote:
| > Just add the following files and run npm run dev. You'll be
| good to go!
|
| 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.
| bhouston wrote:
| I did some experiments myself and settled on this template
| repository:
|
| 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.
| conaclos wrote:
| Some comments and suggestions:
|
| - `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...
| rglover wrote:
| Hear me out: if you need to do this just to use a tool
| effectively, maybe it's a bad tool.
| wruza wrote:
| We're open to suggestions!
| rglover wrote:
| In this specific context: just use plain JavaScript with
| default args and your own, inline type checker functions. No
| need for stuff like this and you can customize type checks to
| your heart's content.
| wruza wrote:
| Ah, I upgraded just yet, realized node 20 broke the way ts-node-
| esm loader works. Had to downgrade to 18, because there's no
| functionality I really need from 20. Also Vite complained when I
| tried node 19, because it requires <=18 && >=20 for some reason
| (probably good one).
|
| 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.
| jb_hs wrote:
| My guess is node 19 isn't an LTS version and it's hard enough
| to maintain just the LTS versions. Probably a requirement that
| will save a lot of pain...
| c-hendricks wrote:
| I've been trying to upgrade a couple of libraries we use
| internally at work to output CJS + ESM, from a typescript
| project, and have the output be 1-to-1 files (so, no bundling /
| rollup / whatever you want to call it).
|
| 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.
| moltar wrote:
| Try tsup it does just work unless your package is doing
| something funny.
|
| Then do a check with attw cli tool and it'll report your compat
| mistakes with links to explainer docs.
| c-hendricks wrote:
| That's what I tried using before and I had even less luck /
| had to do more fandangling, but thanks for the suggestion.
|
| Like I said, these are libraries whose "build" before was
| just `tsc`, there's nothing funny going on.
| dimgl wrote:
| +1 to what one of the commenters is saying. You can skip all of
| this and just use `tsx`. I currently sponsor that project. That's
| how impactful it was on all of my development.
|
| I will say that it's kind of sad that Node.js has devolved into
| this.
| apitman wrote:
| Typescript is a huge improvement over JS, but I never use it. My
| rule of thumb is that if TS provides a tangible benefit, I have
| too much complexity on the frontend.
| kshahkshah wrote:
| Now add eslint and prettier :)
| nop_slide wrote:
| Could someone succinctly describe the situation between node ts
| and esm?
|
| I'm not very familiar with the ecosystem and trying to understand
| what pain ports people are describing here in the comments.
| awongh wrote:
| I just got started with a Next.js project coming from React with
| JS and.... another JS/TS rant incoming.....
|
| 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.
| eddd-ddde wrote:
| Try QwikJS. It solves what you ask for, create a project and
| you are ready to go.
|
| Qwik feels so right to use, if you have 5 minutes you should
| read about it: https://qwik.builder.io/docs/concepts/think-
| qwik/
| SnoozingBoa wrote:
| Here comes a question what many of the people reading the
| comments are thinking:
|
| 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.
| ycombinatornews wrote:
| Snowpack, parcel, esbuild. Minimal setup each. YMMV based on
| how you plan to distribute the build results (package, site or
| app) after.
| vlod wrote:
| Maybe I'm not getting it, but I just set up an express.js app
| this last weekend with nothing much more than tsc
| (typescript) and ts-node.
|
| Do you need all that other stuff for a simple node app?
| demondemidi wrote:
| "...for a few months."
|
| Until this github repo dries up the same way similar attempts at
| this have.
___________________________________________________________________
(page generated 2023-11-21 23:03 UTC)