Nodejs Tips and Tricks

Image of Author
April 20, 2023 (last updated July 23, 2023)

log full objects

You can use util and the depth: Infinity option. You still have to call console.log.

import util from 'node:util'

const obj = {}

console.log(util.inspect(out, { depth: Infinity }));

directories

process.cwd() is the directory the node process is currently being ran in.

But maybe you want to write a cli lib and want to access static assets/files within your npm library. For that, you can use __direname and __filename, which aren't quite globals, and only work in .cjs (common js) files. Importantly, symlinks are resolved before filename resolution. This means that even though the script is likely executed from node_modules/.bin/<script>, since that is a symlink to the package.bin field, it will actually display that file path. From there, you can construct relative paths to reach your desired static asset.

nodejs test runner is legit

As of v20, the nodejs test runner is stable. It now defaults to a much more readable spec test reporter when ran in the terminal.

conditional exports seem great for package authors

To begin with, you should be familiar with the exports key, which seems to be intended to supercede the main key in package.json files: With conditional exports The exports key seems to be intended to supercede the main key in package.json:

When a package has an "exports" field, this will take precedence over the "main" field when importing the package by name.

Now, within the exports key, you can defined conditional exports, which can target different module types.

For example, let's say we are writing a package in TypeScript using esm files. We can use tsup to easily bundle our exports into multiple formats, and then point to each module type bundle within the exports key.

{
  // source code is in esm
  "type": "module",
  // tsup outputs ts types
  "types": "dist/index.d.ts",
  // tsup bundles/builds
  "scripts": {
    "build": "tsup src/index.ts --dts --formats esm,cjs"
  },
  // conditional exports
  "exports": {
    "import": "dist/index.js",
    "require": "dist/index.cjs"
  }
}

Now, packages that depend on your package can require('package') or import _ from 'package'.

Finally, you can also include "types" within "exports". This is considered a community condition. For some reason it must come first. I have not move the types key in the example above because I cannot get it to work with the vscode typescript engine.

package.json spec is in multiple locations