Learn how to setup Node.js with TypeScript while supporting native ES modules. Use the new NodeNext option to easily interop between CommonJS and ES modules in the same project. Full Lesson and Source Code fireship.io/le...
Thanks for this! Setting up a new Node project in 2023 is: 1 hour setting up the build environment 1 hour setting up linting 1 hour getting webpack to work 1 more hour optimizing everything 3 hours researching Deno / Bun / Vite, then deciding it's not worth it 1 hour wondering if you're better off with plain JS 1 hour remembering what you wanted to build
This guy is always reminding me why I 1. Hate the JS ecosystem with a passion 2. Admire the JS developers that maintain their sanity and build stuff with it
@@alanbixby I tend to lean into ts-node, but now it's sounding like a nightmare yet again lol; I'll have to look into esbuild kit I guess lol; yet another tool :RIP: They used to say to never use ts-node for production, then you could; all the answers are an answer in one point in time and then never again down the road as they become the "wrong answer" lol I'm just glad to have node 18 here and the older versions dying off 🎉 It's all still a pain though.
@@lsudo tsx is a CLI program, short for typescript execute. it uses esbuild to transpile all imports to js in memory on demand really fast. it also supports jsx/tsx the language extension, which is a bit confusing at first.
Every year for advent of code, I spend a majority of my time configuring my baseline JS/TS environment rather than working on the coding problems, which is fun because I get to see how much things have changed just like this video hits on 😆 Edit: I'm excited to see this full course and how it evolves ;D 🎉
When you compile you run the .js file and you target the other .js files, typescript won't change your import to ts so you declare it with .js that's why...
@@stxnw when I dont specify the files extension, "esModuleInterop" set to true gives me: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext' When using .ts files, The vscode hints say: "An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.ts(5097)" When I enable it, all errors are gone, but the typescript compiler throws: "error TS5023: Unknown compiler option 'allowImportingTsExtensions'." So weird.
A thousand thank-yous for this! I wish this video were linked in the TypeScript official getting started docs. As an infrequent JavaScript developer starting to dig into the TypeScript ecosystem, the legacy module situation is a huge stumbling block to get past. Love your straightforward presentation.
Thanks a lot! ❤ I was able to figure this out the hard way, but I'm glad I stumbled upon this video for a) confirming that I did it correctly and b) future references. Cheers!
The module field is pretty much abandoned. It's only really used by bundlers. The correct way to tell node how to import your code is to use the "files" and “exports” fields. Not trying to sound like a stackoverflow comment, just wanted to share a thing I picked up after diving into all this stuff recently. Excited to watch the rest, I love your content!
Million likes for this video! I spent the entire day debugging until I stumbled upon your video. Turns out, the issue was that I was importing a common JS package without specifying {"type":"module"} in the package.json. Thank you so much! ❤❤❤❤❤
Thank you! This could not come at a better time. For the life of me I could not get TypeScript working with my GraphQL setup but your review of the tsconfig files cleared up my confusion. My main issue was needing to add the .js file extensions to the imports.
I always find myself having a mini heart attack when watching your videos because you'll occasionally hear a baby crying in the background and I ALWAYS think it's my baby. I'm literally home alone right now and still paused the video to listen out for him crying :')
I need to work with pure javascript to get CommonJS working, because of dynamically use the code and re-import it on runtime is such a blessing as well a curse. But for my project and personal works, it's perfectly fine.
Deno NPM compatibility is nearly there! We're so close. Most libraries just work OOTB already. I am running from node with the speed of light my man, at least for my personal projects
It's truly a peculiar experience see how this channel's owner is gradually descending into madness by the hand of web technologies mostly. I just can't look away... keep the hard work
You should make a movie about package managers, only few people know about PNPM for example, but for now it's the fastest and most space efficient solution!
It's important to highlight that this is only one way to set up Typescript with Node in 2023. I have different priorities, revolving more around minimizing surprises than around efficiency, so I do almost everything differently, and I don't expect my values to turn around completely next year either. This tutorial is valuable because it's a complete description of an error-free setup, not because the statements within are universally optimal.
It feels like this message is trying to tell us something without actually saying what it is. Or maybe I'm just missing something obvious. Can someone express the "different priorities" in more blunt terms?
For those that want nodemon to watch over file changes: add "ts-node": { "esm": true } to tsconfig.json And if your shell complains like mine did use ( npx nodemon src/index.ts ) this should work Also add ts-node globally with ( npm i -g ts-node ) really not sure if this is needed but I did it anyway
I'm still confused as to why we need to specify file extention when we import. Couldn't node/TS resolve it itself based on the actual file it is importing?
I kind of remember Ryan Dahl spoke about this being needlessly complex to implement and (not so sure if I remember this right) hogs resources. If he were given a chance to do Node all over again he would not do it.
I just use tsc-alias to fix the import file extension after compiling. It's easier and cleaner. And handles the path aliasing. I would recommend using nodenext for moduleresolution, but for the module option to use esnext or commonjs
npm init tst --init Done. Now, my way of doing this is (as a proud developer) is scripting all of this. Hosting CommonJS and ESM project templates on a NodeJS-based, fully automated file server that's using my own database that's using its own virtual file system and cloning it whenever I need. Yes It's overcomplicated for a reason don't argue just accept that life isn't always the way it should be.
Great video as always. From 3.09 secs to 3.28 secs, your voice sounded different. Is it me or has anyone noticed it? R u well bro. Please stay safe and sound. Looking forward to your next video.
@@Zwiebelgian it's not a lot of work to setup a typescript project , cleaner directories I'm not seeing any problem, speed not sure , I've not seen any benchmarking
@@Zwiebelgian yeah, it also has better apis under the Deno. namespace and a std library. You also get less config files, lots of built in stuff like linter so you don’t have to do that yourself, more secure, faster http server, better browser compatibility, the apis mostly use promises (and sync versions) instead of callbacks, you can run code directly from a url, even Ts code and so on The npm support doesn’t work on all packages perfectly just yet but soon:tm:
For developing nodejs backend, I generally use babel with watch mode and nodemon to have very fast server restart on file save. I'll check this out but I'll probably still prefer sticking with a faster transpiler than tsc
Importing a js file in typescript that doesn't exist on the file system is really confusing and simply weird. It's way better to use a tool like tsc-alias to fix the imports as a compilation step instead of having to change every import of every source file in every project.
Just yesterday I was dealing with something similar with Fastify and Typescript. I wanted to be using ESM, and went through the whole troubleshooting process to figure out the right tsconfig settings, but due to the way a lot of Fastify packages were exporting their types it broke being able to import the default export from it. I don't know the specifics, but it was just super annoying that this glorified linter was causing such an obnoxious bug for code that worked fine without it. However, Typescript in Deno is a beautiful experience. Largely I think because you don't have to worry about commonJS. Makes me wonder if as Deno gets more popular, the TS Node people will move over to it
Just add the path alias in tsconfig.json for the "@components" or even better, just point "@" to the src folder, so you can "@/anything". Then, install @types/node and @types/express as development dependencies. If you use dotenv and cors, install @types/dotend and @types/cors.
@@LarsRyeJeppesen yeah, there are a lot of issues in Node and TypeScript, and each bundler have its own solutions. But for now, that's the solution and packages like module-alias or better-module-alias. But if you know of a better solution, please comment it instead of being secretive about it. Cheers!
I'd advise using a runner like TSX or Esbuild runner. This strips the types and makes it much less painful to develop. Type checking is gradually moving in the direction of being a CI step rather than part of the build step.
Nah, this is one of the reasons why I use Nest.js - TypeScript by default, no hassle, no cry - just awesome architecture, typescript and more time for playing Witcher 3 after the work is done.
I recommend using @tsconfig/bases packages for a predefined config for you environment, so you don't have to remember what put into "target" and other properties.
why not make a nestjs video? Nest is a framework for building efficient, scalable Node.js server-side applications. It uses modern JavaScript, is built with TypeScript (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).
Could you go over some scenarios for building and publishing. For instance, I'm creating a base server implementation (basically an express wrapper with auth middleware) and I would like to publish it to a local npm registry (Verdaccio). It publishes everything, not just the dist folder, and I'm not sure how to handle dependencies. I have some issues with importing the server package as well, needing to do a second deconstruction of the default export for the dependency. A good up to date minimal setup for building and publishing would be really cool! Something with build to dist, publish from dist and importing the package somewhere (maybe even with import instead of require)