Giter VIP home page Giter VIP logo

kenso312 / nestjs-v10-webpack-boilerplate Goto Github PK

View Code? Open in Web Editor NEW
101.0 2.0 13.0 1.9 MB

🎨 Boilerplate for NestJS v10 with Webpack, Pnpm, Fastify, Swagger, Pino Logger, Airbnb JavaScript Guide, Google JSON Style, ESLint, Prettier, Editorconfig, Husky, Lint-Staged, Commitlint, Axios, Docker, Alias Path, Error Handling and Clustering

Home Page: https://kenso312.github.io/nestjs-v10-webpack-boilerplate/

License: MIT License

JavaScript 24.73% Shell 0.89% TypeScript 71.74% Dockerfile 2.63%
axios clustering commitlint docker eslint fastify husky lint-staged nestjs nestjs-boilerplate

nestjs-v10-webpack-boilerplate's Introduction

NestJS v10 Webpack Boilerplate

Banner

Language License Version

πŸ”₯ Features

  • πŸ† Graceful Production Deployment

  • 🧭 Unified API Response Structure

  • ⚑ Extreme Performance Optimize

  • πŸ“ Fully Integrated Coding Quality Tools

⚠️ Attention

Although there are advantages to use Webpack bundling your code (especially for serverless applications), there are some constraints, and details here (UPDATE: Both examples stated by the NestJS creator have already unblinded the native driver and are good to use now). Therefore, please make sure your application does not contain native bindings library, then you can enjoy the benefits.

Extra Configuration for Dependency Packages

You should install copy-webpack-plugin and copy bull default commands to the output directory when building the code.

pnpm install -D copy-webpack-plugin
// webpack.config.js;
const CopyWebpackPlugin = require('copy-webpack-plugin');
// ...
module.exports = {
  plugins: [
    // ...
    new CopyWebpackPlugin({
      patterns: [
        {
          context: 'node_modules/bull/lib/commands',
          from: '**/*.lua',
        },
      ],
    }),
  ];
}

By default we assume the application will run in production mode after building the app, so if you still using development mode you will get the error since you enable pino-pretty and it does not include in the production bundle. Therefore, if you want to use pino-pretty after bundling for any reason, you should install the pino-webpack-plugin.

pnpm install -D pino-webpack-plugin
// webpack.config.js
const { PinoWebpackPlugin } = require('pino-webpack-plugin');
// ...
module.exports = {
  // ...
  plugins: [
    // ...
    new PinoWebpackPlugin({ transports: ['pino-pretty'] }),
  ],
};

πŸ““ Commands

Commands Description

# build the app
$ pnpm build

# format the code
$ pnpm lint

# start the app
$ pnpm start

# run in development mode
$ pnpm start:dev || pnpm dev

# build the app and run it in production mode
$ pnpm start:prod || pnpm prod

# generate Swagger JSON schema
$ pnpm swagger

# test both unit test and e2e test
$ pnpm test

# test all the e2e test
$ pnpm test:e2e

# test all the unit test
$ pnpm test:unit

Running Application for Development

$ git clone <repo>

$ pnpm install

# Fill in require information in .env file
$ cp .env.example .env

# Linux / Mac users may require (allow git hook script executable)
$ chmod +x .husky -R

$ pnpm dev

πŸ“ Boilerplate Structure

β”œβ”€β”€ ci
β”‚   β”œβ”€β”€ docker-compose.yaml
β”‚   └── Dockerfile
β”œβ”€β”€ .husky
β”‚   β”œβ”€β”€ _
β”‚   β”‚   β”œβ”€β”€ .gitignore
β”‚   β”‚   └── husky.sh
β”‚   β”œβ”€β”€ commit-msg
β”‚   β”œβ”€β”€ pre-commit
β”‚   └── pre-push
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ exception
β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   └── normal.exception.ts
β”‚   β”œβ”€β”€ filter
β”‚   β”‚   β”œβ”€β”€ all-exception.filter.ts
β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   β”œβ”€β”€ normal-exception.filter.ts
β”‚   β”‚   └── validator-exception.filter.ts
β”‚   β”œβ”€β”€ interceptor
β”‚   β”‚   └── response.interceptor.ts
β”‚   β”œβ”€β”€ modules
β”‚   β”‚   β”œβ”€β”€ app
β”‚   β”‚   β”‚   β”œβ”€β”€ dto
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ response
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   β”‚   β”‚   β”‚   └── version.dto.ts
β”‚   β”‚   β”‚   β”‚   └── index.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ app.config.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ app.controller.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ app.module.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ app.service.spec.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ app.service.ts
β”‚   β”‚   β”‚   └── index.ts
β”‚   β”‚   └── http
β”‚   β”‚       β”œβ”€β”€ http.module.ts
β”‚   β”‚       └── http.service.ts
β”‚   β”œβ”€β”€ shared
β”‚   β”‚   β”œβ”€β”€ enums
β”‚   β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ log-level.ts
β”‚   β”‚   β”‚   └── node-env.ts
β”‚   β”‚   β”œβ”€β”€ interfaces
β”‚   β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   β”‚   └── response.ts
β”‚   β”‚   └── constants.ts
β”‚   β”œβ”€β”€ utils
β”‚   β”‚   β”œβ”€β”€ clustering.ts
β”‚   β”‚   β”œβ”€β”€ helper.ts
β”‚   β”‚   └── swagger.ts
β”‚   β”œβ”€β”€ env.d.ts
β”‚   └── main.ts
β”œβ”€β”€ test
β”‚   β”œβ”€β”€ app.e2e-spec.ts
β”‚   β”œβ”€β”€ common.ts
β”‚   └── jest.e2e.config.ts
β”œβ”€β”€ .vscode
β”‚   β”œβ”€β”€ extensions.json
β”‚   └── settings.json
β”œβ”€β”€ .commitlintrc.js
β”œβ”€β”€ .dockerignore
β”œβ”€β”€ .editorconfig
β”œβ”€β”€ .env.example
β”œβ”€β”€ .eslintignore
β”œβ”€β”€ .eslintrc.js
β”œβ”€β”€ .gitattributes
β”œβ”€β”€ .gitignore
β”œβ”€β”€ jest.config.ts
β”œβ”€β”€ .lintstagedrc.js
β”œβ”€β”€ nest-cli.json
β”œβ”€β”€ .npmrc
β”œβ”€β”€ package.json
β”œβ”€β”€ pnpm-lock.yaml
β”œβ”€β”€ .prettierrc.js
β”œβ”€β”€ README.md
β”œβ”€β”€ tsconfig.json
└── webpack.config.js

⭐ Coding Quality Tools Details Description

ESLint

It statically analyzes your code to help you detect formatting issues and find code inconsistencies, here we extend the ESLint TypeScript recommend rules, the most popular JavaScript style Airbnb, auto import sorting and shaking plugins.

# Config File
β”œβ”€β”€ .eslintignore
└── .eslintrc.js

Prettier

Similar to ESLint, but mainly focus on auto-formatting, not the code quality. Actually, ESLint can do all the jobs that Prettier can do, but for the formatting part, Prettier does better, so we import both and achieve each of the advantages. About the conflict of the formatting part, we can import plugin:prettier/recommended to solve this, but keep in mind that this plugin should extend at the last.

# Config File
└── .prettierrc.js

Editorconfig

It defines a standard code formatting style guide among all the IDEs and editors used within a team of developers. Basically, all the rules in the Editorconfig should sync with Prettier, Editorconfig focus on newly created files, ESLint and Prettier focus on existing files.

# Config File
└── .editorconfig

Husky + Commitlint + Lint-staged

These tools are the wrapper of Git Hook. Lint-staged enforces you to format your code (run pnpm lint) before committing, but the tools will cache the file that is already formatted to improve performance. Commitlint enforces your commit message to fit a specific format, here we extend Conventional Commits (officially recommend setting).

# Type: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test
# Commitlint Format:

<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
# Config File for Lint-staged
└── .lintstagedrc.js

# Config File for Commitlint
└── .commitlintrc.js

# Config File for Husky
β”œβ”€β”€ .husky
|   β”œβ”€β”€ commit-msg  # call Commitlint to check the commit message
|   β”œβ”€β”€ pre-commit  # call Eslint to lint the coding issue
|   └── pre-push    # call Jest to do the unit + e2e test

Git Attributes

To synchronize the end-of-line of the git repository.

# Config File
└── .gitattributes

βš™οΈ Other Configuration

SWC

SWC (stands for Speedy Web Compiler) is a super-fast TypeScript / JavaScript compiler written in Rust. NestJS v10 should be officially support it now, so we replace ts-loader to swc-loader for better building performance.

Pnpm

We use preinstall script forcing Pnpm as default package manager because it is a fast and disk space efficient manager compare with Npm and Yarn.

Webpack

We overwrite the default webpack.config.js so that the production build can bundle all required libraries in main.ts. For the configuration, we ignored a list of the nestjs-buildin library so that we could build it without error. If you need these libraries for your development, you can comment it in the lazy imports list.

Alias Path

Using an alias path can prevent dirty relative paths (e.g. ../../../), also it is easier to import files in the deep directory (e.g. src/assets/img/testing/...).

# Config File
└── tsconfig.json

API Response

Success Response

{
  "data": {
    "...": "..."
  }
}

Error Response

{
  "error": {
    "code": 400,
    "message": "..."
  }
}

We use Google JSON guide to be the response format implemented by filtering + interceptor, which is the built-in feature of NestJS, to sync with the response format. All exceptions will be caught by filtering, and all normal returns will be transformed by the interceptor.

# Related Directory
β”œβ”€β”€ src
|   β”œβ”€β”€ exception
|   β”œβ”€β”€ filter
|   └── interceptor

Environment Variables Validation

We use Joi library for the validation, which is recommended by NestJS.

# Config File
β”œβ”€β”€ src
|   └── app.config.ts

HTTP Request

Since @nestjs/axios default return Observable, it does not fit the common use case (Promise based), so we use a custom module to implement secondary encapsulation of the native Axios library, also extract .data from the response to prevent .data.data.data... chaining.

Reference:

Pino Logger

We used nestjs-pino to auto-log every request metadata and response time. We also centralized Pino config in app.config.ts for main.ts to reuse it.

Swagger

@nestjs/swagger allows you to auto-generate the API document, but here we decouple the document and the service. You can run pnpm swagger to generate the schema and put it into Swagger UI to host your API document as a static page. We have two examples in app.controller.ts to show you how to integrate the Google JSON response format. We also have a GitHub Action example to auto-update the schema and host it to the GitHub Pages. If you do not want this setup, you can just follow NestJS official guideline to host your document inside the service.

Attention: You do not need to wrap the data object to your DTO for every response, you only have to name your DTO end with 'Res', swagger.ts script will auto-wrap for you and display correctly in the Swagger UI.

Swagger UI Final Output

Docker Containerization

We also set up the Dockerfile with multi-stage builds to optimize your image size and building time. For the docker-compose config, we also included health checking.

# Config File
β”œβ”€β”€ ci
|   β”œβ”€β”€ docker-compose.yaml
|   └── Dockerfile

Clustering

We also configured the clustering feature for the service to improve performance. All you need to do is just config the environment variable CLUSTERING=true.

β˜‘οΈ Naming Convention

JS variable / function: lower camel case [e.g. twoWords]

JS global const + enum's attributes: upper case [e.g. TWO_WORDS]

JS class / interface / type / enum: pascal case [e.g. TwoWords]

Asset name (e.g. image): kebab case [e.g. two-words]

πŸ“ˆ Performance Optimization

By default, we used Fastify instead of Express to achieve twice of performance, below are the benchmarks tested by NestJS:

Express.js

Stat 1% 2.5% 50% 97.5% Avg Stdev Min
Req/Sec 14183 14183 15767 15991 15640 501.13 14182
Bytes/Sec 3.06 MB 3.06 MB 3.41 MB 3.45 MB 3.38 MB 108 kB 3.06 MB

Fastify

Stat 1% 2.5% 50% 97.5% Avg Stdev Min
Req/Sec 19935 19935 33247 34111 32030.4 4103.84 19931
Bytes/Sec 3.03 MB 3.03 MB 5.05 MB 5.19 MB 4.87 MB 624 kB 3.03 MB

Reference:

License

This project is licensed under the MIT License, Copyright Β© 2022. See LICENSE for more information.

nestjs-v10-webpack-boilerplate's People

Contributors

dependabot[bot] avatar kenso312 avatar wp-harm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

nestjs-v10-webpack-boilerplate's Issues

Error on build

Steps to reproduce

pnpm build && pnpm start

Expected behavior

Build succeed

Current behavior

Hi there,
Thank you for this great boilerplate ! Been working on it all day yesterday, but had a quack when I tried to build the project.

I tried building from the repo without any modification and had the same issue.

Looks like an issue with PINO. I tried many things to fix it and made it with on of the following:

  • Change these dependencies version to "nestjs-pino": "^2", "pino": "^6.4", "pino-http": "^5.6.0", "pino-pretty": "^6"
  • Or simply by added NODE_ENV=production to script.start in package.json

Any better way to fix it ?

Thanks,
Tim

pnpm build && pnpm start

> [email protected] prebuild /Users/tim/Desktop/test
> rimraf dist


> [email protected] build /Users/tim/Desktop/test
> nest build --webpack --webpackPath ./webpack.config.js

webpack 5.76.2 compiled successfully in 7767 ms

> [email protected] start /Users/tim/Desktop/test
> node dist/main


node:internal/event_target:1010
  process.nextTick(() => { throw err; });
                           ^
Error: Cannot find module '/Users/tim/Desktop/test/dist/lib/worker.js'
    at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
    at Module._load (node:internal/modules/cjs/loader:920:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at MessagePort.<anonymous> (node:internal/main/worker_thread:159:24)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:735:20)
    at exports.emitMessage (node:internal/per_context/messageport:23:28)
Emitted 'error' event on Worker instance at:
    at [kOnErrorMessage] (node:internal/worker:290:10)
    at [kOnMessage] (node:internal/worker:301:37)
    at MessagePort.<anonymous> (node:internal/worker:202:57)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:735:20)
    at exports.emitMessage (node:internal/per_context/messageport:23:28) {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

Node.js v18.15.0
 ELIFECYCLE  Command failed with exit code 1.

Node.js version

18

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Add Sqlite

What is the motivation / use case for changing the behavior?

Add database in the app

Describe the solution you'd like

I think it would be useful to add nestjs/typeorm with sqlite (or other database). It will be a good example how to build nest application via webpack and libraries that use binaries

Error: Cannot find module 'src/../package.json'

Steps to reproduce

  1. pnpm i
  2. pnpm dev

Error: Cannot find module 'src/../package.json'

May I ask if I have missed any key information?

node version: 18.18.2
pnpm version: 8.10.4

Expected behavior

null

Current behavior

null

Node.js version

18.18.2

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Migrate to NestJS v10

What is the motivation / use case for changing the behavior?

New NestJS version is out!

Describe the solution you'd like

We can safely migrate using npm-check-updates and fix the errors that we find during testing

For example, eslint-plugin-prettier issue requires to update it manually to eslint-plugin-prettier@alpha - probably needs rolling back prettier plugin to avoid it until stable version comes out

Swagger json is not generated after switching on SWC

Steps to reproduce

  1. pnpm install
  2. pnpm swagger

Expected behavior

Generated swagger.json

Current behavior

pnpm swagger script ends without error and swagger.json is not generated

Node.js version

18

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

switching back on tslib fixes issue

Issues with import/no-extraneous-depedencies in VSCode

Steps to reproduce

I'm having issues with this rule when using VSCode, for example

  1. pnpm add supertokens-node

Expected behavior

Package is installed and can be imported with no eslint errors

Current behavior

'supertokens-node' should be listed in the project's dependencies. Run 'npm i -S supertokens-node' to add it eslintimport/no-extraneous-dependencies

Node.js version

18

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

The issue persists only in IDE. Running pnpm lint doesn't show any errors

Looks like that's the reason
import-js/eslint-plugin-import#1177

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.