Frontend Masters Boost RSS Feed https://frontendmasters.com/blog Helping Your Journey to Senior Developer Wed, 15 Jan 2025 15:40:04 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.3 225069128 Do I Need This Node Dependency? https://frontendmasters.com/blog/do-i-need-this-node-dependency/ https://frontendmasters.com/blog/do-i-need-this-node-dependency/#comments Wed, 15 Jan 2025 15:40:03 +0000 https://frontendmasters.com/blog/?p=4982 Brian Muenzenmeyer on new(ish) things in Node:

Through the efforts of contributors over several recent majors, great new features are landing. Each is useful in isolation, but put together they form a more and more comprehensive standard library.

Do you need a 3rd party testing library like jest? Maybe, but there is a tester built in now. Do you need a 3rd party file watcher like chokidar? Maybe, but there is a built-in watcher now. Do you need a build process to deal with TypeScript? Not anymore. Do you need chalk to colorize/style terminal output? Not anymore.

]]>
https://frontendmasters.com/blog/do-i-need-this-node-dependency/feed/ 2 4982
TypeScript without Build Tools https://frontendmasters.com/blog/typescript-without-build-tools/ https://frontendmasters.com/blog/typescript-without-build-tools/#comments Mon, 30 Dec 2024 18:33:32 +0000 https://frontendmasters.com/blog/?p=4407 TL;DR: There are a bunch of tools these days that allow you to write in TypeScript and… just not think about it much more than that. You needn’t deal with converting that code into JavaScript yourself.


Here’s what has me thinking about all that.

We’ve got a monorepo at work.

We’ve been moving to TypeScript for years, with mostly positive results. I’m fairly convinced that the code output from writing in TypeScript is better and the experience of writing and editing existing TypeScript code is better DX.

It’s not without challenges though. I hate wasting time futzing with types when I just know it really isn’t improving the quality of my code I’m just fighting with a machine. This concern is multiplied when you see your team doing the same thing.

Another challenge is the part where you actually have to produce JavaScript. This is not a difficult job in and of itself. There are loads of tools that do this from the canonical tsc to tools that do no type checking but can very speedily compile TS to JS (like esbuild). But sometimes, you still have to do it.

One example from our monorepo is that we have some components that we’d like to write in .tsx, but they can be consumed by a number of different site building tools (e.g. a Next.js site, an Astro site, an classic Just Load React On The Page site, etc). The most sane way of handling this is processing the TS into JS ahead of time. That way whatever site that wants to import them can do it as native, normal JavaScript ESM stuff.

monorepo
website-1
website-2
packages
components
dist
MyVeryImportantComponent
index.js
src
MyVeryImportantComponent
index.tsx

Now I need to make a build process to do this. I’ll probably write a little script. npm run process-packages or whatever, fine. I’ll probably use tsc for this on purpose, knowing that it isn’t the fastest, but it’s the one that is capable of actually throwing errors when there are TypeScript problems. This is useful because I can call my script in a pre-commit hook in Git, for example, to prevent myself and my team from committing bad TypeScript. I can call the script in CI as well which is additional protection.

So now I have tsc building from src to dist, great. But TypeScript explicitly will never build an “other files” copy machine. Well that’s annoying. What about my other stuff?

packages
components
src
MyVeryImportantComponent
index.tsx
queries.graphql
styles.module.scss

Now I have to wire up some new machine to copy anything that isn’t TypeScript over from src to dist. Blech. Fine, I’ll do it.

But this is all complicated by the fact that this script we’re building needs to be able to run two ways:

  1. As a builder, where you call it and it does the job
  2. As a watcher, where it runs the build when any pertinent file changes

It’s unacceptable DX to expect a developer to run a build command after every file change manually. So we have to build our own little watcher too. I guess it’s Chokidar time? I hate piling on dependencies, but that’s the only watcher that’s ever felt truly reliable to me.

I don’t mean to paint this picture too negatively. This is all doable. This is the job. There are tools to help with this that get better over time. But wow, it’s a lot when you consider it was just TypeScript, this invisible layer of special code helping syntax, that pushed us this far into toolsville.

I’d rather focus on the positive stuff I’m seeing here. As the years tick by, and TypeScripts popularity remains high, the surrounding tools that deal in JavaScript are more and more fine with “just leave it as TypeScript.” I find that interesting!

This “native” support of TypeScript is a product choice. We know some of our customers write and prefer TypeScript so we’ll make it easier for them. But there is no Official™ way to do this. The product needs to decide how they are going to handle it. Are they going to check types for you and alert you (somehow? somewhere?) to type problems? Or are they leaving type problems to you, and if the code compiles to JavaScript, so it shall be. What version of TypeScript is it going to support? Is configuration necessary?

So what are these products?

Tools & Products That Let You Write TypeScript “Natively”

Frameworks

  • Astro: “Astro ships with built-in support for TypeScript. You can import .ts and .tsx files in your Astro project, write TypeScript code directly inside your Astro component, and even use an astro.config.ts file for your Astro configuration if you like.”
  • Next.js: “Next.js comes with built-in TypeScript, automatically installing the necessary packages and configuring the proper settings”
  • This is pretty common in UI meta frameworks… Nuxt, Remix, SvelteKit, Redwood, etc. This, likely, is the thing that pushed other products to do the same.

Runtimes

  • Deno: “TypeScript is a first class language in Deno, just like JavaScript or WebAssembly.” You can just deno run script.ts, deploy .ts files to their cloud service, and there is a type checking command. See what I mean about it being a product choice?
  • Bun: “Bun treats TypeScript as a first-class citizen.”
  • Cloudflare Workers: “TypeScript is a first-class language on Cloudflare Workers.”

Bundlers

  • Vite: “Vite supports importing .ts files out of the box.”
  • esbuild: “…esbuild has built-in support for parsing TypeScript syntax and discarding the type annotations.”
  • Parcel: “Parcel supports TypeScript out of the box without any additional configuration.”

Meta

  • tsx: The big thing here is the tsx project, or “TypeScript Execute”. A lot of times what you’re trying to do in Node is node script.ts, like in an npm script, but you can’t, because Node doesn’t support TypeScript “natively”. But replace node with tsx, and it works.

Drumroll?

I started writing this post a few weeks ago, and now I’ve just seen: Node.js Now Supports TypeScript By Default.

Node 23 will soon be able to run TypeScript files without any extra configuration.

You can run node index.ts with no further flags

Node will strip out the types using a version of swc, then run the resulting code.

Well there ya have it. Feels like we were on to something there eh?

I feel like this pushed it more into Official™ territory and now this will be less of a product-level choice and more of a “leverage what the technology already does” choice. For instance, products don’t have do anything special or build additional technology to support TypeScript, they’ll just do what Node does. And they won’t have to fret over “well should we do type checking?” because they can just follow in the steps of what the tool already does (just strip them).

]]>
https://frontendmasters.com/blog/typescript-without-build-tools/feed/ 2 4407
Make Sure You Can Switch https://frontendmasters.com/blog/make-sure-you-can-switch/ https://frontendmasters.com/blog/make-sure-you-can-switch/#respond Tue, 02 Jul 2024 15:34:02 +0000 https://frontendmasters.com/blog/?p=2904 Nicholas C. Zakas on the idea that we have choice in server-side JavaScript runtimes now, and you should be careful.

… it makes sense to preserve the ability to switch runtimes easily. It doesn’t matter if you want to use Node.js or Deno or Bun in production right now. What you really want is the ability to change your mind later with as little pain as possible.

Here’s his advice (truncated for brevity):

  1. Don’t use Deno- or Bun-specific APIs. Stick with Node APIs that are already supported in Deno and Bun.
  2. Use the “node:” prefix for Node.js internal modules. Node works just fine when using the “node:” prefix, so you can ensure compatibility across all three runtimes.
  3. Use npm and JSR packages, not HTTP module specifiers. Deno is still the only runtime to support URL modules, so it’s best to stick with npm and JSR packages, which can be used across all three.
  4. Use package.json for dependencies. Don’t use the proprietary file formats which have no advantages.
  5. Always run CI with Node, too. Even if you’re deploying to Deno or Bun, run CI in Node.
]]>
https://frontendmasters.com/blog/make-sure-you-can-switch/feed/ 0 2904
require(esm) in Node.js https://frontendmasters.com/blog/requireesm-in-node-js/ https://frontendmasters.com/blog/requireesm-in-node-js/#comments Tue, 16 Apr 2024 22:09:17 +0000 https://frontendmasters.com/blog/?p=1707 Joyee Cheung made some waves in Node land last month:

Since ESM was shipped in Node.js, for many years, it was possible to import cjs, but not possible to require(esm). The frustration of ERR_REQUIRE_ESM has bothered many and probably has been the primary source of wasted hours in the Node.js ecosystem. If package authors wanted to make sure that both CJS and ESM users can consume their package, they either had to continue shipping their modules as CJS, or ship both the CJS and ESM version

Apparently, it will go out in v22, which isn’t out yet but should be soon.

It seems to me this should alleviate some of the pain the Node world is still feeling where projects and their dependencies are still a mix of both. But the true impact remains to be seen. Will you be upgrading to v22 to soothe any pain of your own?

]]>
https://frontendmasters.com/blog/requireesm-in-node-js/feed/ 1 1707
Node.js Debugging in Chrome DevTools https://frontendmasters.com/blog/node-js-debugging-in-chrome-devtools/ https://frontendmasters.com/blog/node-js-debugging-in-chrome-devtools/#comments Mon, 08 Apr 2024 23:10:27 +0000 https://frontendmasters.com/blog/?p=1616 I was pairing with my co-worker last week. They had a super different debugging style than I do. I’m aware that I can do fancy things in DevTools, like set breakpoints and whatnot right from within DevTools and use well-placed debugger; statements to halt JavaScript execution and inspect things at that point.

But I hardly ever do any of that.

I’m quite sure I don’t even know all the cool tricks. I’m a console.log() type. I just absolutely litter the code in them until I learn what I need to learn. It’s a little amateur-ish, I admit. I’ve made it this far, but there’s no time like now to level up.

I especially don’t know any tricks with Node.js debugging. To begin with, I didn’t even know you could use Chrome DevTools with Node.js. It sort of makes sense since Node.js uses v8 just like Chrome does, but it never clicked with me to use a browser tool for server code. It’s not a new thing! Paul Irish was telling people how to do this in 2016.

The kind of debugging my co-worker and I were doing was complex enough that having DevTools to help us really worked. I think I’m a believer. For this article though, I’m going to show you how to do it with a simple example. You probably wouldn’t need DevTools for this, but the point is learning how to do it.

1) Have Chrome Open

Then go to chrome://inspect/. The first tab, Devices, has the link you’re looking for.

These settings work for me, but if you run Node at some specific port or local URL, you should add it here.

2) Have Node Code

Kinda goes without saying, but you’re going to need to execute some Node code, likely from your terminal, in order for there to be anything to expect. Might be an npm script or something. Let’s just assume we have a file called app.js and we’re going to run it directly like node app.js.

3) Have a Problem

My goal with this code was to have…

Hello World

… turn into:

Hello 👋 World!!!

That is, put a wave emoji between each word. But the output I was getting was:

undefinedHello 👏 World 👏 !!!.

That’s a problem because:

  1. I don’t want undefined there
  2. It put a wave at the end too
  3. There is a space before the “!!!”.

We must fix this super contrived example!

4) Execute the Node Code with an Inspection Flag

Like this:

node --inspect-brk app.js

That --inspect-brk flag is the real magic here.

When I do that, the terminal output will tell me where Node is running and that the Debugger is attached:

It will automatically pause before it starts executing.

5) Go through the Code

These buttons are of particular interest:

If you press “Play” here (that first blue one), the code will just run and be done without much a chance to inspect anything.

You could use the next button, the dot with a little curved arrow up and over it, to start “stepping” through the code. But Node is complicated, and you’ll soon find yourself in the bowels of Node doing god-knows-what.

The trick is to put a debugger; statement in the code where you start caring about stuff. So…

Now when I run again, I can hit the blue Play button and hop to this exact point the first time it gets there. Now I can start “stepping” through the code to see values. As I step through, I can see the values of relevant variables as I go.

I can also hover over variables to see values as well as see locally-scoped variables in the sidebar on the right.

Here I learned that when I declared the variable and then appended a string to it, I got that undesirable result. Lemme start with a blank string instead.

We also essentially want to skip the last iteration of the loop. So instead we’ll use an old school for loop and run it over the length of all the words minus one. Then plop the last word (and !!!) at the end separately.

5) Restart Things Anytime

As I change my code, I can always Control-C out of the Node process and run it again, and DevTools (thank god) will automatically re-attach.

Here I can start over and step through the code, seeing my changes yield the correct output.

The other debugger buttons (like the down arrow and up arrow) allow you to step through code quicker by fast forwarding to the next function call or finishing the function you’re currently in.


This just feels like a more grown-up way to debug code when things get complicated. Especially for apps where you are jumping between lots of files, you can see all that happening in the DevTools file explorer on the left.

Good luck out there!

]]>
https://frontendmasters.com/blog/node-js-debugging-in-chrome-devtools/feed/ 5 1616
Node.js: The Documentary https://frontendmasters.com/blog/node-js-the-documentary/ https://frontendmasters.com/blog/node-js-the-documentary/#respond Mon, 08 Apr 2024 16:16:09 +0000 https://frontendmasters.com/blog/?p=1568 I enjoyed watching Honeypot’s recent Node.js Documentary. Props to Honeypot for taking the time and resources to do these historical dives into some of our industries most major technologies. I like seeing the human side of these things. I feel like if too much more time passed, documentaries like these would get a lot harder to pull off and may never happen at all. Not to assign bloated importance to my own industry, but web technology affects a massive slice of the population of Earth, so major changes in how it works are a big deal.

They’ve also done Ruby on Rails, React, Vue, Ember, GraphQL, and others. All stuff you can learn on Frontend Masters, weird 😛.

]]>
https://frontendmasters.com/blog/node-js-the-documentary/feed/ 0 1568