Setting up node and typescript
This article describes the creation process of a node application with TypeScript.
Installing nvm
There are multiple ways to install node
but we have picked the nvm
path. This method will
allow us to have multiple versions of node installed on the computer.
We have to make sure that xcode command line tools are installed. We can trigger the installation by
trying a command like cc
on the terminal.
Run the following command to install nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
The previous command will automatically install all the files to ~/.nvm
and update the shell
initialization file. To reload the shell configuration run:
source ~/.zshrc
We can now try nvm
:
nvm --version
Installing node and npm
The next step is to install node and npm (node package manager) by using nvm.
nvm install node
wait for the proces to complete and try the following commands:
node --version
npm --version
The previous commands have installed the latest versions of node and npm. To install and use a specific version of node and npm try:
nvm install v12.18.0
nvm use v12.18.0
To list all the versions available on our computer:
nvm list
To get the installation directory for a specific node version:
nvm which 18.10.0
Creating a new project
Start by creating a new directory for our project, cd
into it and initialize the project
with the following command:
npm init
The previous command will generate a file called package.json
.
Adding typescript support
Now, enter the following command to add TypeScript support:
npm install typescript --save-dev
Create a file named tsconfig.json
along with the package.json
file, where we
will put our TypeScript configuration:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"outDir": "dist",
"sourceMap": true,
"target": "ES6",
"noImplicitAny": true,
"noImplicitReturns": true,
"strict": true
}
}
allowJS
andcheckJs
tell TypeScript how to handle native JavaScript code it encounters in our source files.outDir
tells TypeScript where to put the converted files,sourceMap
instructs it to link the converted code back to the original (for debugging),target
tells it to convert our code to a browser-friendly, yet still modern, version of JavaScript.noImplicitAny
,noImplicitReturns
, andstrict
impose a series of additional tests on code, which promote best coding practices.
Update package.json
:
{
//...
"main": "src/index.ts",
"scripts": {
// ...
"build": "tsc && npm run build:cp-public",
"build:cp-public": "cp ./public/** ./dist",
"type": "tsc --noEmit"
}
// ...
}
- update
main
to usesrc/index.ts
instead of the defaultindex.js
, build
runs two commands,tsc
(the TypeScript compiler), andbuild:cp-public
,build:cp-public
copies the contents of thepublic
directory to thedist
directory,type
is triggered bynpm run type
to help during debugging.
Creating source files and compiling
Create a simple src/index.ts
file:
function helloWorld() {
const element = document.getElementById("hello-world");
if (element) {
element.textContent = "Hello, World!";
}
}
helloWorld();
and a public/index.html
file:
<html>
<body>
<p id="hello-world"></p>
<script src="index.js"></script>
</body>
</html>
Notice that we are referencing index.js
from the html file. That is what the TypeScript compiler
will output from our src/index.ts
file.
And we are ready to compile the project:
npm run build
The resulting files can be found in the dist
directory.
A working example can be found on my github page.
Installing additional modules
First, add the type
argument to the script tag to avoid issues with Safari.
<script type="module" src="index.js"></script>
Safari will complain with the following error if the type
argument is missing:
SyntaxError: Unexpected token ‘{’. import call expects exactly one argument.
Let’s install charts.js
and configure it to work with TypeScript. Start by installing the module:
npm install chart.js
Now try importing the module from index.ts
:
import { Chart } from 'chart.js';
const ctx = document.getElementById('csd1') as HTMLCanvasElement;
const myChart = new Chart(ctx, {
// ...
});
and compile.
npm run build
If the compiler fails with the following error:
Cannot find module ‘chart.js’. Did you mean to set the ‘moduleResolution’ option to ‘node’, or to add aliases to the ‘paths’ option?
we can fix it by setting moduleResolution
to node
in tsconfig.json
:
{
"compilerOptions": {
"moduleResolution": "node"
}
}
Common questions
Why we have to commit package-lock.json
?
guarantee exact same version of every package between your dev and prod environments. This part is the most important when building in different environments at different times. You may use ^1.2.3 in your package.json, but how can you ensure each time npm install will pick up the same version in your dev machine and in the build server, especially those indirect dependency packages? Well, package-lock.json will ensure that. (With the help of npm ci which installs packages based on lock file)
Common issues
Reinstalling all node modules
We want to reinstall all the existing node modules when dependency errors show up. To do it, remove the node-modules
directory and the package-lock.json
file, and run npm
with the install
parameter again.
rm -Rf node-modules
rm package-lock.json
npm install
Dealing with CORS issues
Browsers block certain types when loading resources using the file://
protocol. To overcome the issue, we need to set up a web server. An easy way to do it is to use python. The process is very simple, cd
into the directory that contains the web resources and enter the following command:
cd <any-directory>
python -m SimpleHTTPServer 9000
or for python3:
cd <any-directory>
python3 -m http.server 9000
if we omit the port, python will use the default 8000 one.
References
- Node and TypeScript example. https://github.com/ajaimesv/node-typescript
- How to install Node.js and npm on macOS. https://www.newline.co/@Adele/how-to-install-nodejs-and-npm-on-macos--22782681
- Node Version Manager. https://github.com/nvm-sh/nvm
- Do I commit the package-lock.json file created by npm 5? https://stackoverflow.com/a/50868690/2079513
- Lutterbie, S. Setting up a simple TypeScript project. https://javascript.plainenglish.io/setting-up-a-simple-typescript-project-b11140877e24