Skip to content

Instantly share code, notes, and snippets.

@ScorpionConMate
Last active September 6, 2023 15:45
Show Gist options
  • Save ScorpionConMate/3d1791dd6078d0637f5e42ca5649ed0c to your computer and use it in GitHub Desktop.
Save ScorpionConMate/3d1791dd6078d0637f5e42ca5649ed0c to your computer and use it in GitHub Desktop.
Setting Up Node.js Typescript Project with Eslint, Prettier & Live Reloading

Setting Up Node.js Typescript Project with Eslint, Prettier & Live Reloading

Setting up Typescript and live reloading in Node.js

First, setting up the file tsconfig.json to compile the typescript files into javascript files.

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "ESNext",
    "noImplicitAny": false,
    "experimentalDecorators": true,
    "allowJs": true,
    "emitDecoratorMetadata": true,
    "resolveJsonModule": true,
    "sourceMap": true,
    "rootDir": "./",
    "outDir": "./dist",
    "types": [
      "node"
    ],
  },
  "include": [
    "./src/**/*"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

Then, install the typescript compiler tsc and the typescript node module ts-node as dev dependencies.

npm i -D nodemon ts-node @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint prettier typescript @types/node

Now, create a file to live reloading in development mode, nodemon.json:

{
 "watch": ["src"],
 "ext": "ts",
 "ignore": [
  "src/**/*.spec.ts",
  "src/**/*.test.ts",
  "src/**/*.d.ts",
  "node_modules"
 ],
 "exec": "ts-node ./src/index.ts"
}
  • In case that live reload not working, try to add the following line to the nodemon.json file:
 "legacyWatch": true

Setting up ESLint and Prettier

Now, we need create 2 separate files .eslintrc. and .prettierrc to configure ESLint and Prettier.

Prettier file

{
    "parser": "typescript",
    "printWidth": 120,
    "singleQuote": true,
    "trailingComma": "all",
    "useTabs": true
}

Eslint file

{
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "root": true,
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "project": "./tsconfig.json",
        "tsconfigRootDir": "./"
    },
    "plugins": [
        "@typescript-eslint"
    ],
    "rules": {
        "no-async-promise-executor": "off",
        "no-mixed-spaces-and-tabs": "off"
    }
}

Add the following scripts to package.json

    "dev": "nodemon",
    "start": "node ./dist/src/index.js",
    "build": "tsc",
    "build:watch": "tsc -w",
    "lint": "eslint src/**/*.ts",
    "lint:fix": "eslint --fix src/**/*.ts",
    "format": "prettier --write \"src/**/*.ts\"",
    "format:check": "prettier --check \"src/**/*.ts\""

Setting up a logger

Create a file logger.ts with the following content

import winston from 'winston';
import { version } from '../../package.json'; // Import version from package.json
const logger = winston.createLogger({
	format: winston.format.combine(
		winston.format.timestamp(),
		winston.format.colorize(),
		winston.format.label({ label: "OUR-Service-" + version }),
		winston.format.printf((info) => {
			const meta = info[Symbol.for('splat')];
			info.message = `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`;
			if (meta) info.message += ` - ${JSON.stringify({ metadata: meta })}`;
			return info.message;
		}),
	),
	transports: [
		new winston.transports.Console(),
		new winston.transports.File({
			filename: 'logs/error.log',
			level: 'error',
			format: winston.format.uncolorize(),
		}),
		new winston.transports.File({
			filename: 'logs/combined.log',
			format: winston.format.uncolorize(),
		}),
	],
	exceptionHandlers: [
		new winston.transports.File({
			filename: 'logs/exceptions.log',
		}),
	],
	exitOnError: false,
});

export default logger;

In our index.ts or entrypoint file of the application, at the end of file, add the following code, to replace all console.* by the new implementation

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-explicit-any
console.log = (...args: any[]) => logger.info.call(logger, ...args);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-explicit-any
console.error = (...args: any[]) => logger.error.call(logger, ...args);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-explicit-any
console.warn = (...args: any[]) => logger.warn.call(logger, ...args);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment