A Simple Project With TypeScript & NodeJs
Overview
This is a quick article that shows you how to set up a simple project with node and typescript. The article will provide a brief guide on getting a little project up and running Then in part 2 we will discuss improving it and allowing you to read an excel file and parse its content into JSON.
Part 2 is now live https://andrewallison.medium.com/building-a-nodejs-typescript-project-for-reading-excel-files-part-2-dfa8fda1eaf7
Assumptions
I’m going to assume you already know at least the basics of node and have an environment configured which will allow you to run node files and also edit/save excel files. The article is not by any means an in-depth look into the problem or a comprehensive guide to the best practices of ETL with node. It is simply something I find myself doing often and decided to create an article about it in the hopes it might help others.
Getting Started
As discussed I’m assuming you are familiar with the command line and also with NodeJs and javascript/typescript.
From a command line create a new directory either with the GUI or via a command line like so:
mkdir read-excel
cd .\read-excel\
npm init -y
NOTE: npm init -y skips the wizard and attempts to pre-populate the details in the packa.json file
You should then see something along the lines of
From there open your favourite editor, such as vscode or my personal favourite Webstorm
Next, we will install our deDependencies. These are the libraries we will use to make the project tick, build, commit etc. but they aren’t really part of the overall solution. We install commitizen to allow us to produce pretty commits that can be standardized and used as part of release notes. We will use it with cz-conventional-changelog this makes us good commitizens and makes sure our commits make sense and can be used later on if we need to. It’s probably not necessary for this project but its a handy habit to get into.
npm i -D commitizen commitlint cz-conventional-changelog eslint @typescript-eslint/eslint-plugin eslint-config-prettier eslint-plugin-prettier ts-node
We have also added eslint config, prettier plugin to make sure our code can be standardised and linted so it’s nice and consistent.
copy the following code and place it at the bottom of your package.json
file this will configure the cz function to use the standard template when committing
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
Next create the following files to allow us to configure the linter and code styling `.prettierrc .eslintrc.js`
open .eslintrc.js and paste the following content. It’s a simple config file for eslint that has a number of options turned off to soften it a little bit. This is due to over-aggressive linting being painful during the early stages of a dev project.
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js', 'graphql.ts'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
The .prettierrc file should look like. Again just some simple options for prettier that I find useful.
{
"singleQuote": true,
"trailingComma": "all",
"endOfLine": "auto"
}
I find it helpful when using prettier and eslint that you install a plugin for the IDE you are using that will obey the laws set out by them. It’s also handy if you have it configured to auto-format based on these rules. I’ll not go into this now but if you are interested drop me a comment and I’ll write an article.
Next up create a new directory called src
and place a file in it named index.ts
Paste the following content into the index file.
const helloWorld = () => {
console.log('Hellow, World')
}
helloWorld();
Change the scripts section in the package.json file to look like this:
"scripts": {
"start": "ts-node src/index.ts"
},
If you now fun the file either by clicking a run arrow in the package.json file (it’s another great plugin worth using, although WebStorm does it out of the box I think) or use npm run start
from a command line.
After we know the project is running ok we will commit an initial version so we always have this as a starting point.
Create a file in the root of the folder called .gitignore
and paste the following content
# ignore the node_modules folder.
node_modules
# Keep environment variables out of version control
.env
.env.*
# IDE
.idea/
# Dist
dist/
# coverage
coverage
# documentation
documentation
# ignore any temp documents
temp
From here we want to initialise the repository
git init
Once that’s completed run git status
to see if there are any files in the staged content that you wouldn’t expect. It should look like this
As long as all the files seem like they make sense you can add them all to the staged files that will be committed
git add .
git-cz
Another useful plugin for windows and in particular the PowerShell console is posh-git this gives you a very pretty output reflective of the status of the repo at the command line. A resulting window following the above commands will look like
Proceed by following the steps of the cz command
We could leave it at this ORRRRRRRR we could also add a GitHub repo. Then we know it’s safe on the web in case we drop out laptop down the stairs when trying to program on the way to bed. (again…..)
There are a number of ways to do this and configuring an environment for GitHub/Git is beyond the scope of this document. As discussed previously if you are struggling and want me to help with this chuck a message in the comments. My set-up involves ssh-keys that I’ve set up with GitHub so I can easily do a push from the command line. I know not everybody likes to pretend they are a hacker or in The Matrix, so Source Tree and GitHub Desktop would be good alternatives for those of a more GUI-based persuasion. Once you have all of these steps configured and you are logged in to GitHub and authenticated you can follow these steps to get the repository pushed
Firstly go to GitHub and create a new repository. Clicking new in the panel on the home screen is often the quickest way.
From here you need to enter a name and a description. Set the repository to public or private depending on your preference. We’ve added a .gitignore
file so we don’t need to worry about that we can add a licence and ReadMe.md
if we need to but I’ll leave them for now
Once the repository has been created you will get a useful message explaining how to add the code to the repo
Because of the way things are set up we are only really interested in these 2 lines
git remote add origin git@github.com:<USERNAME>/read-excel.git
git push -u origin main
You will then see the following output
This next bit is optional but for me having a consistent workflow even on small projects (They often grow to be more than small projects) makes it easier to jump between things and have the same safety nets and experiences. This means including a git-flow-based branching strategy for git. A good cheat sheet to help can be found here. Having an understanding of Git branching is another area I’m assuming you grasp but a good place to discover a lot about git is https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow
As always I try to stick with the default options where possible. It keeps things simple moving forward and helps on-boarding new developers.
You will now have a git flow repo and be placed on the develop branch. Let’s push that branch now as well
git push --set-upstream origin develop
If you check GitHub that should all now be available there for all to see. Or just you depending on if you set private for the repo or not.
Let's add some changes and see how things go.
Update the package.json
file and make the scripts section look like this.
"scripts": {
"eslint": "eslint src/**",
"start": "ts-node src/index.ts"
},
Add a tsconfig.json
file to the root of the project and add the following content
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"lib": ["esnext"],
"esModuleInterop": true
}
}
Next run npm run eslint
or use a nice helpful arrow in Webstorm
OOOPPPSSSS. I end up with the following content
We can manually tweak it or we can be a bit cleverer and add --fix
after the eslint command.
"scripts": {
"eslint": "eslint src/** --fix",
"start": "ts-node src/index.ts"
},
This is also a good chance to look at the file with a git comparison tool. WebStorm and VsCode have them built-in or use GitHub desktop. Either way, you should be able to see it look something like
Let’s stay true to our philosophy of trying to do this at least a little professionally.
git add .
git-cz
Selecting the linter option of git-cz
We then push that up to GitHub as well. git push
Ok, so this is the project structure and main boilerplate set up and running. This project could easily be reverted to this point and used as a starter project for others.
See you in part 2 for the next exciting instalment.