Today, I added import aliases and PrismJS to this project. I added PrismJS specifically for this page.

Why add import aliases?

As you start working on a project, it gets larger and requires some organization to stay maintainable. Before taking care of this, often times, the imports at the top of most files begin to look a bit like this:

// src/components/my/deeply/nested/component.tsx

import { MyButton }	from "../../buttons/my-button.tsx";
import { UserResponse }	from "../../../../types";
import "../../../../styles/styles.css";

That's pretty ugly, and hard to maintain. If you move this file to a different location in the project, you have to update every one of these relative import statements.

Similarly, renaming or moving a file requires you to update every OTHER file that imports something from that original file.

Import aliases solve this problem. With them, you can declare globally-interpreted sources for modules to be imported:

// src/pages/my/deeply/nested/page.tsx

import { MyButton } from "$components/my-button";
import { UserResponse }	from "$types";
import "$public/styles.css";

I'm using the $ symbol to denote local-project modules. An approach I've seen in the past is to use the @ symbol, but this prefix is also commonly used for third-party packages (installed via NPM), so I want to remove this ambiguity.

How?

To do this yourself in a Gatsby/TS project, you'll need to install a Gatsby plugin and update a couple files.

In your project's tsconfig.json:

Add the alias mappings you'd like to use. The * is a glob-like character. Read more in the TypeScript docs.

// tsconfig.json

{
  "compilerOptions": {
    // ...
    "paths": {
      "$components/*": ["./src/components/*"],
      "$styles/*": ["./src/styles/*"],
      "$types/*": ["./src/types/*"],

      // Also include the aliases below if you want to import directly from the alias, e.g.
      // import { MyButton } from "$components";
      "$components": ["./src/components"],
      "$styles": ["./src/styles"],
      "$types": ["./src/types"]
    }
    // ...
  },
  // ...
}

Optionally, you can set a base URL with which the paths will be prefixed:

// tsconfig.json

{
  "compilerOptions": {
    // ...
    "baseUrl": "./src",
    "paths": {
      "$components/*": ["components/*"],
      "$styles/*": ["styles/*"],
      "$types/*": ["types/*"],

      // Also include the aliases below if you want to import directly from the alias, e.g.
      // import { MyButton } from "$components";
      "$components": ["components"],
      "$styles": ["styles"],
      "$types": ["types"]
    }
  },
  // ...
}

Make sure also that your TypeScript Compiler's config includes the source code you're working with:

// tsconfig.json
	
{
  "compilerOptions": {
    // ...
  },
  "include": [
    "./src/**/*",
    "./gatsby-config.ts",
    // ...
  },
  // ...
}

Install gatsby-plugin-alias-imports

Install gatsby-plugin-alias-imports via NPM:

npm i gatsby-plugin-alias-imports

Or via Yarn:

yarn add gatsby-plugin-alias-imports

In your project's gatsby-config.js:

Add the aliases in the plugin configuration for gatsby-plugin-alias-imports. Read more in the docs for the plugin.

// gatsby-config.ts

  // ...
  plugins: [
    // ...
    {
      resolve: "gatsby-plugin-alias-imports",
      options: {
        alias: {
          $components: "src/components",
          $styles: "src/styles",
          $types: "src/types",
        },
        extensions: ["ts", "tsx", "js", "jsx"], // Include any other file extensions in your project
      },
    },
  ],
  // ...

Good to go!

That's all there is to it! Go wild.

PrismJS

Prism is a lightweight syntax highlighter with lots of customization options. I am using it via NPM, but you can download a minified version of it (JS and CSS) from PrismJS.com. I'm using the VS Code Dark Plus theme.