Danny Brown

A Blog on Code and Occasionally Other Things

Dotfiles Script for a New TypeScript/Node Project

Danny BrownDecember 21, 2023

I set out recently to get more fluent in TypeScript, and after getting comfortable with syntax in browser-based interpreters, the next step was to get TypeScript running locally. As this is generally useful information, I figured I would write a blog post to share my approach.

Global ts-node Install

Assuming you already have the npm package installed, run the following command to globally install the ts-node package:

sudo npm install --global ts-node

Further, if you’re setting this up in your personal dotfiles, be sure to put this install in an appropriate place in your pipeline. (I have an .npm script in my dotfiles that is run the first time I set them up, for example.)

Note that we’re not installing TypeScript itself globally. Instead, we’ll set it as a project dependency so that different TypeScript versions can be supported across different projects.

Set NPM Configuration Default

You can also configure default options that will be automatically set when you generate a new Node project:

npm config set init-author-name "Your Name"
npm config set init-author-email "youremail@email.com"
npm config set init-author-url "https://github.com/yourgithubhandle"
npm config set init-license "MIT"
npm config set init-version "0.0.1"

Node/TypeScript Project Initialization

Create a new, empty directory and cd into it. The following commands will set up a new Node project with some useful defaults:

    yes | npx gitignore node
    npm init -y
    npm i --save-dev typescript
    git init
    mkdir src
    touch src/index.ts

The above code block will:

  1. Create a .gitignore file with standard Node-project settings
  2. Create a package.json and package-lock.json reflecting all of the defaults we set earlier
  3. Set TypeScript as a dev dependency and add it to package*.json files
  4. Initialize a git repository
  5. Create an empty directory and file at src/index.ts

One more step: create a tsconfig.json. This method allows us to write a beautifully formatted JSON block within our script, but also messes up my beautifully formatted script by requiring no white space at the beginning of certain lines, most notably the closing EOF statement.


    tsconfig_content=$(cat <<EOF
{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "outDir": "./dist",
        "rootDir": "./src",
        "strict": true
    }
}
EOF
)
    echo "$tsconfig_content" > tsconfig.json

Bonus Content: Project Directory Creation

I was not a fan of having to manually create a folder to run the above commands in.

    if [ ! -z "$(ls -A)" ]; then
        echo "WARNING: Current working directory is not empty, see the contents:"
        ls -A
        read -p "Directory name to create in ~/projects/ (leave blank to proceed in cwd): " project_name
        if [ -n "$project_name" ]; then
            local location="$HOME/projects/$project_name"
            mkdir -p "$location"
            echo "Project directory created at: $location"
            cd "$location"
        fi
    fi

This block checks if the current directory is empty. If it is: great, we move on. Otherwise, it will prompt for a project_name. I like to keep all of my projects in a directory at ~/projects, so my code creates a new directory with the project_name in that location.

Alternatively, we retain the option to not provide a project name. This is for cases where we have a file or two already created but we still want to initialize a Node project in that directory.

Bonus Content: Directory Safeguards

With the ability to run in non-empty directories, I wanted to add a couple safeguards so that I didn’t run this in undesirable places and be forced to clean up the mess.

    if [[ $(pwd) = "$HOME/projects" || $(pwd) = $HOME ]]; then
        echo "ERROR: Don't run this script in $HOME or $HOME/projects"
        return
    fi

Because ~ and ~/projects are meaningful directories for me, I don’t want to proceed with the script if they are the cwd.

    if [[ -d ".git" ]]; then
        echo "ERROR: A .git folder already exists in the current working directory"
        return
    fi

We’re also aborting the mission if the cwd is already a git repository.

The Full Script

Here is my current working version of node_project_init.sh:

#!/bin/bash

# Spin up some basic Node project files, with a little bit of prompting
# and safeguarding to make sure we're not running in undesirable places


function node_project_init {
    if [ ! -z "$(ls -A)" ]; then
        echo "WARNING: Current working directory is not empty, see the contents:"
        ls -A
        read -p "Directory name to create in ~/projects/ (leave blank to proceed in cwd): " project_name
        if [ -n "$project_name" ]; then
            local location="$HOME/projects/$project_name"
            mkdir -p "$location"
            echo "Project directory created at: $location"
            cd "$location"
        fi
    fi
    if [[ $(pwd) = "$HOME/projects" || $(pwd) = $HOME ]]; then
        echo "ERROR: Don't run this script in $HOME or $HOME/projects"
        return
    fi
    if [[ -d ".git" ]]; then
        echo "ERROR: A .git folder already exists in the current working directory"
        return
    fi
    yes | npx gitignore node
    npm init -y
    npm i --save-dev typescript
    git init
    mkdir src
    touch src/index.ts

    tsconfig_content=$(cat <<EOF
{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "outDir": "./dist",
        "rootDir": "./src",
        "strict": true
    }
}
EOF
)
    echo "$tsconfig_content" > tsconfig.json
}

Sweet!

Installing for Use

To make the command node_project_init available in your terminal, do the following.

Update your PATH environment variable in your ~/.bashrc file or wherever else you prefer:

export PATH="$HOME/path/to/directory/with/script:$PATH"

Then source the script (you’ll need to do this whenever making changes to update the command in your terminal):

source $HOME/path/to/directory/with/script/node_project_init.sh

Now you can run node_project_init from any location in your system!

Running Code

Add some TypeScript to src/index.ts. Here’s a sample program if you’d like:

function helloName(name: string): void {
    console.log(`Hey, ${name}!`)
}
helloName("you")

Remember how way up at the top we did a global install of ts-node? This is where that comes in, as it allows you to run your TypeScript file directly:

ts-node src/index.ts

The alternative to this is running the tsc command, which transpiles your TypeScript code to ES6 (based on the settings from earlier), then you could run node distro/index.js after transpiling. The ts-node option is a useful shortcut!

Hope this was helpful! Cheers.

Posted In Bash | code | TypeScript
Tagged bash | dotfiles | typescript

Post navigation

PreviousSo I Told You to Go See a Broadway Play? Tips for Theater in New York
NextOpen Pull Requests from the Terminal (One of My Favorite Dotfiles Scripts)

Danny Brown

A Dev Blog with Some Tangents

About

Categories

  • code
    • APIs
    • Bash
    • CSS
    • Django
    • HTML
    • JavaScript
    • Python
    • S3
    • Selenium
    • Serverless
    • TypeScript
  • games
  • music
    • concert reviews
    • synthesizers
  • opinion
  • sports
  • tech
    • Bitbucket
    • Git
    • GitHub
    • MS Teams
    • WordPress
  • theater

Recent Posts

  • Open Pull Requests from the Terminal (One of My Favorite Dotfiles Scripts)
  • Dotfiles Script for a New TypeScript/Node Project
  • So I Told You to Go See a Broadway Play? Tips for Theater in New York
  • Build a Simple Microsoft Teams Bot Easily, No SDK Required
  • Creating a GUI for Conway’s Game of Life Using Pygame and Numpy

External Links

  • GitHub
  • LinkedIn

Recent Posts

  • Open Pull Requests from the Terminal (One of My Favorite Dotfiles Scripts)
  • Dotfiles Script for a New TypeScript/Node Project
  • So I Told You to Go See a Broadway Play? Tips for Theater in New York
  • Build a Simple Microsoft Teams Bot Easily, No SDK Required
  • Creating a GUI for Conway’s Game of Life Using Pygame and Numpy

Categories

  • code
    • APIs
    • Bash
    • CSS
    • Django
    • HTML
    • JavaScript
    • Python
    • S3
    • Selenium
    • Serverless
    • TypeScript
  • games
  • music
    • concert reviews
    • synthesizers
  • opinion
  • sports
  • tech
    • Bitbucket
    • Git
    • GitHub
    • MS Teams
    • WordPress
  • theater
Copyright © 2025. Danny Brown
Powered By WordPress and Meritorious