code --file-uri vscode-remote://ssh-remote+$root_path/scribbles/
  View as a Single Post
Ze Chen

Towards Modernization (I): Front-End Techniques

Project and License

Initialize a Project

npm init -y
git init && git branch -m main


Create a file LICENSE and copy from a template, e.g. MIT or ISC.

Other Information

The following entries may be filled in package.json

"description": "A description",
"main": "./build/src/index.js",
"files": [
"repository": {
    "type": "git",
    "url": "git+"
"license": "ISC",
"author": {
    "name": "Your Name",
    "email": "Your Email",
    "url": "Your URL"
"engines": {
    "node": ">=12.0"
"keywords": [
"bugs": {
    "url": ""
"homepage": "",

Version Control


husky ensures that tests, lint, etc. are done before git commit. See installation procedure.

npx husky-init && npm install


commitizen generates the commit message upon each commit. Install via

npm install --save-dev commitizen

Then run

npx commitizen init cz-conventional-changelog --save-dev --save-exact

Install husky following the instruction here. Then integrate commitizen with husky by adding the following entry in package.json

"husky": {
  "hooks": {
    "prepare-commit-msg": "exec < /dev/tty && git cz --hook || true"

Run npx cz to commit.

Run npx cz --retry to retry a failed commit.

Semantic Release

Install via

npm install --save-dev semantic-release

In package.json we need the following entry

"repository": {
    "type": "git",
    "url": "git+"

In .releaserc.json put

    "branches": ["main"],
    "plugins": [
        ["@semantic-release/npm", {
            "npmPublish": false

Note that we need to git push for once to make sure that the branch exists in the remote repo.

Then we could run semantic release

npx semantic-release --no-ci # --dry-run

semantic-release works also with Nx. See nx-semantic-release-demo.



Install with

npm install typescript --save-dev

Generate tsconfig.json

npx tsc --init

Add the following entry to package.json

"scripts": {
  "typecheck": "tsc --noEmit"

I decided to postpone the configuration until we set up Nx.


Install with

npm install -D typescript

Then we could execute .ts files directly

npx ts-node foo.ts


Install with

npm install -D @types/node

See What is @types/node package in NodeJs?.

Code Style


Format the code, e.g. trailing semicolons.

See here for set-up.

Install and configure with

npm install --save-dev --save-exact prettier
echo {}> .prettierrc.json

Add the following to .prettierignore

# Ignore artifacts:

Since we will be using lint-staged later, we don't have to worry about .prettierignore yet.

Run npx prettier --write . to format files.

Run npx prettier --check . to check files.

Remember to enable prettier in the editor (see Editor Integration).


It's the recommended practice to let Prettier handle formatting and ESLint for non-formatting issues (See What's the difference between prettier-eslint, eslint-plugin-prettier and eslint-config-prettier?).

Install using

npm install eslint --save-dev

Then interactively configure eslint using

npm init @eslint/config

See a comparison of different style guides.

Remember to enable ESLint in the editor (see Editor Integration).

We may also need the following for ESLint to work correctly

extends: [
    "plugin:import/typescript", 'prettier'

rules: {
    'import/extensions': ['error', 'never']

ESLint With Prettier

To handle conflicting rules of ESLint with Prettier, we install eslint-config-prettier using (see GitHub: eslint-config-prettier)

npm install --save-dev eslint-config-prettier

Then we edit the following in *.eslintrc.*

  "extends": [

Make sure to put "prettier" last, so it gets the chance to override other configs.

It is debatable whether one should run Prettier as if it was a linter rule. Packages like eslint-plugin-prettier do that job. However, based on the discussion in Integrating with Linters, we don't use this plugin.

ESLint Plugins


Install with

npm install --save-dev eslint-plugin-node

Then in .eslintrc.js add (see eslint-plugin-node)

extends: [

However, I had not enabled this plugin yet because it has some problems when working with TypeScript (ECMAScript to be specific).


Make sure that Prettier and ESLint are both installed before installing lint-staged.

For Prettier and ESLint to automatically run upon git commit, we install lint-staged via (see lint-staged)

npx mrm@2 lint-staged

It may match only *.js files. Edit the lint-staged entry in package.json so that it covers *.ts as well.

EsLint automatically finds .eslintrc in the directory of the file to be linted, see Configuration Files.



Install with

npm install -D typedoc

Add to the root dir a file typedoc.json with

  "out": "doc",
  "theme": "default"

Generate doc with (e.g. in an Nx workspace)

typedoc --tsconfig libs/data/tsconfig.lib.json --out docs/data libs/data/src/index.ts

See Add possibility to generating documentation for non component libraries.



Remark: another option is using immutable. However, we don't bother using it since Redux Toolkit uses immer.


A functional programming library. See ramda.


See RxJS. Library for observables.



Install with

npm install --save-dev jest

Add the following entry to package.json

  "scripts": {
    "test": "jest --coverage",
    "test:watch": "jest --watch"

We may start a test using

npm t

For a tutorial, see Getting Started.

If husky is installed, tests will run automatically upon git commit.

To generate coverage report, run

npx jest --coverage


Install with

npm i -D ts-jest @types/jest

Create config file with

npx ts-jest config:init

Edit jest.config.js

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['**/test/**/*.spec.ts'],
  collectCoverageFrom: [
  globals: {
    'ts-jest': {
      diagnostics: false,

ESLint With Jest

See eslint-plugin-jest for installation and configuration. In .eslintrc.js we need

env: {
    'jest/globals': true,

plugins: ['jest'],

See How to use ESLint with Jest.

Testing Library


Cypress is for e2e test.




Redux Toolkits uses immer, making states immutable.




Install the dev-dependencies first

npm install -D tailwindcss postcss autoprefixer vite

Then init at the component lib directory e.g. libs/ui with

npx tailwindcss init -p







See react-cytoscapejs.

Transpiling and Bundling

For a brief introduction, see Setup react with webpack and babel.


Transpiles your scripts.


Bundles your scripts.

Back-End and Integration


To let Next.js work with Nest one may try Next + Nest: Working together or NestJS + React (Next.js) in One MVC Repo for Rapid Prototyping. However, I don't deploy these techniques since I am gonna use Nx.

Next.js comes with webpack and babel, customization of which could be found here.


Create an Nx workspace

npx create-nx-workspace

Install Nx CLI

npm install -g nx

To run multiple tasks, run

nx run-many --target=serve --projects=api,html --parallel
Storybook With Nx
npm install -D @nrwl/storybook
nx g @nrwl/react:storybook-configuration project-name
nx run project-name:storybook
Note on Nx





Install with

npm i -g @nestjs/cli

Then we could start a new project by

nest new project-name

This will pop up an interactive setup program.

A Collection of Terminologies
  • SOLID principles:
    • The single-responsibility principle: "There should never be more than one reason for a class to change." In other words, every class should have only one responsibility.
    • The open–closed principle: "Software entities ... should be open for extension, but closed for modification."
    • The Liskov substitution principle: "Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it." See also design by contract.
    • The interface segregation principle: "Many client-specific interfaces are better than one general-purpose interface."
    • The dependency inversion principle: "Depend upon abstractions, [not] concretions."
  • DTO: Data transfer object.
  • CRUD: Create, Read, Update, Delete.
  • IoC: inversion of control.

Create a controller using

nest g controller controller-name

Create a service using

nest g service service-name

Create a module using

nest g module module-name
CRUD Resource

Create a resource using

nest g resource users 

This will pop up an interactive creator. Controllers, modules, services, and DTOs are automatically generated.




Using With NestJS

Install with

npm i @nestjs/passport passport passport-local
npm install -D @types/passport-local





For a basic config see Next.js + API on same server.


To have docker alpine image node:alpine run with Next.js we may need the following

RUN apk add --no-cache libc6-compat

Moreover we need (for compiling)

RUN apk add --no-cache --virtual .gyp \
        python3 \
        make \
RUN npm i
RUN npx nx run-many --target=build --projects=api,front --prod
RUN apk del .gyp

AWS Elastic Beanstalk

To deploy apps to AWS Elastic Bean, See @How to Deploy a NestJS app to AWS Elastic Beanstalk (with added HTTPS and CI/CD).

2022/1/22 16:24:10


Uploaded successfully.


Uploaded successfully.


Uploaded successfully.


Uploaded successfully.