Skip to content

Instantly share code, notes, and snippets.

@cmdruid
Created October 17, 2023 04:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmdruid/07ac824eed41af273719244aaf2b5792 to your computer and use it in GitHub Desktop.
Save cmdruid/07ac824eed41af273719244aaf2b5792 to your computer and use it in GitHub Desktop.
A quick and simple transpiler for resolving path aliases in typescript.

Here is a nice trick that I would like to share if you are working with typescript and path aliases.

Suppose you have a typescript project, and you are in love with path aliases.

// tsconfig.json
{
  "baseUrl": "./src",
  "paths": {
    "@/*" : [ "./*" ]
  },
 }

Path aliases are great. They allow us to write sane, readable import statements.

// It sucks to write this:
import { widget } from '../../../../lib/widget.js'
// This is way better:
import { widget } from '@/lib/widget.js

However our path aliases will not work at run-time, so we need a way to convert them back into relative imports.

Microsoft refuses to add path resolution to typescript, so many folks turn to third-party tools. But many of these tools are buggy, abandoned, baked into specific frameworks, or part of some complex tool-chain.

I don't want a new framework or toolchain. I just want sensible path resolution!

So I wrote a very basic script for transpiling code, using good uncle sed:

#!/bin/bash

## A quick and simple transpiler for resolving path aliases in our codebase.

DIRECTORY="./dist"  # The file path to search.
EXTENSION="js"      # The file extension to look for.
ABSOLUTE_PATH="@/"  # The path sub-string we are targeting.
DEPTH_OFFSET=3      # Offset our depth counter. Adjust to your needs.

# Loop through all files in the directory that match the specified extension.
find "$DIRECTORY" -name "*.$EXTENSION" -type f | while read -r file
do
    # Count the number of slashes in the file's path to determine its depth
    DEPTH=$(echo "$file" | tr -cd '/' | wc -c)
    
    # Build a relative path string based on the depth.
    RELATIVE_PATH=""
    for (( i=DEPTH_OFFSET; i<=$DEPTH; i++ ))
    do
        RELATIVE_PATH="../$RELATIVE_PATH"
    done
    
    # Use sed to perform the in-place replacement.
    sed -i "s|$ABSOLUTE_PATH|$RELATIVE_PATH|g" "$file"
done

Now I can transpile my code with this neat build script:

// package.json
"scripts": {
   "build": "rm -rf ./dist && tsc && ./transpile.sh",
 }

It works great. Zero dependencies!

I hope you find this gist useful, and fall in love with path aliases. Thank you for reading!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment