Setup

Boilerplate

Terminal
npx nestia start <directory>

Just run above npx nestia start <directory> command.

Boilerplate would be automatically constructed in the <directory>. For reference, this is a minimal boilerplate project concentrating only on the SDK generation from the NestJS server. It does not contain the database connection.

If you want to construct much detailed boilerplate project, visit @samchon/backend or run below command. Below boilerplate project is using Prisma ORM and PostgresSQL database. Also, it guides how to utilize FP (Functional Programming) and TDD (Test Driven Development) in the NestJS backend development.

Terminal
npx nestia template <directory>

Setup Wizard

Terminal
npx nestia setup

When you want to setup nestia in existing project, just run above npx nestia setup command.

Setup Wizard will install and configure everything automatically.

During the setup process, the prompt will ask you to whether configure runtime swagger or not. If you hope to build Swagger Document in the runtime, you have to choose true option. Otherwise, just select the false option please.

Terminal
npm install --save-dev nestia@latest
npx nestia setup
 
----------------------------------------
 Nestia Setup Wizard
----------------------------------------
? Package Manager (Use arrow keys)
> npm
  pnpm
  yarn (berry is not supported)
? Transform Runtime Swagger (Use arrow keys)
> true
  false

Webpack

With node_modules

Terminal
# SETUP NESTIA
npx nestia setup
 
# INSTALL TS-LOADER & WEBPACK
npm install --save-dev ts-loader
npm install --save-dev webpack webpack-cli webpack-node-externals 

When you want to bundle your NestJS project into a single file, you have to install webpack manually.

Never run nest build --webpack command of @nestjs/cli, because it is not compatible with nestia.

webpack.config.js
const path = require("path");
const nodeExternals = require("webpack-node-externals");
 
module.exports = {
  // CUSTOMIZE HERE
  entry: {
    server: "./src/executable/server.ts",
  },
  output: {
    path: path.join(__dirname, "dist"),
    filename: "[name].js",
  },
  optimization: {
    minimize: false,
  },
 
  // JUST KEEP THEM
  externals: [nodeExternals()],
  mode: "development",
  target: "node",
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        loader: "ts-loader",
      },
    ],
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
};

After installing both nestia and webpack, configure webpack.config.js file like above.

From now on, you can build the single JS file just by running the npx webpack command. By the way, when removing devDependencies for --production install, never forget to add the --ignore-scripts option to prevent the prepare script.

Terminal
npx webpack
npm ci --omit=dev --ignore-scripts

Single JS file only

If you can build your NestJS project into a singile JS file, and that JS file even does not require the node_modules directory, it would be useful for building a serverless environment. Also, as it does not need to perform the pruning process (represented by pnpm install --production --ignore-scripts command), it would be much convenient and faster than the above method.

To accomplish the light JS bundling, install special dependencies like below.

Terminal
# SETUP NESTIA
npx nestia setup
 
# INSTALL SPECIAL DEPENDENCIES
npm install --save-dev ts-loader
npm install --save-dev webpack webpack-cli
npm install --save-dev copy-webpack-plugin write-file-webpack-plugin

Also, configure webpack.config.js file like below, considering options.

For example, if your NestJS backend server is utilizing the Prisma ORM, uncomment the CopyWebpackPlugin.patterns block to copy the Prisma engine files (node_modules/**/.prisma/client/*.node) into the output dist directory.

After that, just run npx webpack command. Then the light JS file(s) would be bundled into the dist directory, and you don’t need to perform the pruning process (represented by pnpm install --production --ignore-scripts command) for the distribution. Just deploy the dist directory to the target server.

webpack.config.js
const path = require("path");
 
const CopyWebpackPlugin = require("copy-webpack-plugin");
const WriteFilePlugin = require("write-file-webpack-plugin");
const { IgnorePlugin } = require("webpack");
 
const lazyImports = [
  "@fastify/static",
  "@fastify/view",
  "@nestjs/microservices",
  "@nestjs/websockets",
  "class-transformer",
  "class-validator",
];
 
// @reference https://tech-blog.s-yoshiki.com/entry/297
module.exports = {
  // CUSTOMIZE HERE
  entry: {
    server: "./src/executable/server.ts",
  },
  output: {
    path: path.join(__dirname, "dist"),
    filename: "[name].js",
    chunkFormat: false,
  },
  optimization: {
    minimize: true,
  },
 
  // JUST KEEP THEM
  mode: "production",
  target: "node",
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        loader: "ts-loader",
      },
    ],
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
  plugins: [
    new CopyWebpackPlugin({
      patterns: [
        {
          from: ".env",
          to: "[name][ext]",
        },
        {
          from: "package.json",
          to: "[name][ext]",
        },
        // {
        //   from: "node_modules/**/.prisma/client/*.node",
        //   to: () => Promise.resolve("[path][name][ext]"),
        //   globOptions: {
        //     dot: true,
        // },
      ],
    }),
    new WriteFilePlugin(),
    new IgnorePlugin({
      checkResource: (resource) => {
        if (lazyImports.some((modulo) => resource.startsWith(modulo))) {
          try {
            require.resolve(resource);
          } catch (err) {
            return true;
          }
        }
        return false;
      },
    }),
  ],
};

NX

Terminal
npx nestia setup

After installing nestia like above, and ensuring the prepare script is something similar to ts-patch install && typia patch you have to modify the tsconfig.lib.json on each package to be similar to the below.

tsconfig.lib.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/out-tsc",
    "declaration": true,
    "types": [],
    "plugins": [
      { "transform": "typia/lib/transform" },
      { 
        "transform": "@nestia/core/lib/transform",
        "validate": "assert",
        "stringify": "assert", 
      },
      { "transform": "@nestia/sdk/lib/transform" }, // for runtime swagger composition
    ],
  },
  "include": ["**/*.ts"],
  "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"]
}

After this, when running nx <package-name>:build it should now output with the Nestia transforms applied. But if Nestia fails for any reasons (for example it considers some type you have to be invalid), this error is not reported back via Nx. Nx will silent swallow these errors from ts-patch/nestia, and you will just not get the output you expect. To debug this, you can create a new task in your project.json file similar to the below.

project.json
 "targets": {
    "build:validate:nestia": {
      "executor": "nx:run-commands",
      "options": {
        "commands": [
          "tsc --project packages/<package-name>/tsconfig.lib.json --outDir dist/packages/nestiaTest"
        ],
      }
    },
    ...
 }

Running this task will show you the errors from Nestia, and allow you to correct them, meaning that using the standard nx <package-name>:build task should now work the way you expect.

Note: While Nx has a transformers feature on certain plugins, that won’t work with Nestia. The reason is because Nx is expecting a transformer to export a before hook, which Nx then plugs directly into TypeScript via the compiler API. Nestia doesn’t export that kind of hook, because Nestia only works with ts-patch, which abstracts the need for creating a specific before hook in the way Nx wants.

Manual Setup

Terminal
# COMPILERS
npm install --save-dev typescript
npm install --save-dev ts-node
npm install --save-dev ts-patch
 
# NESTIA
npm install --save-dev nestia
npm install --save @nestia/core
npm install --save @nestia/e2e
npm install --save @nestia/sdk
npm install --save typia

If you want to install nestia manually, you have to install ts-node and ts-patch modules as well as typescript. After installing those compilers, install nestia libraries like above.

tsconfig.json
{
  "strict": true,
  "strictNullChecks": true,
  "compilerOptions": {
    "plugins": [
      { "transform": "typia/lib/transform" },
      { 
        "transform": "@nestia/core/lib/transform",
        "validate": "assert",
        "stringify": "assert", 
      },
      { "transform": "@nestia/sdk/lib/transform" }, // for runtime swagger composition
    ],
  },
}

After that, configure tsconfig.json file like above.

As @nestia/core and typia are generating optimal validation and JSON serialization code through transformation, you’ve to configure them as plugins. For reference, you can choose which typia functions to be used in validation and JSON serialization.

Also, never forget to configure strict (or strictNullChecks) as true. It is essential option for modern TypeScript development.

package.json
{
  "scripts": {
    "prepare": "ts-patch install && typia patch"
  }
}
Terminal
npm run prepare

At last, configure npm run prepare command like above.

Of course, you’ve to run the npm run prepare command after configuration.

For reference, ts-patch is an helper library of TypeScript compiler that supporting custom transformations by plugins. With the ts-patch setup and plugin configurations, whenever you run tsc command, your @nestia/core decorator function call statements would be transformed to the optimal operation codes in the compiled JavaScript files.


Standard TypeScript Only

If you’re using @nestia/core module, you’ve to use only standard TypeScript compiler.

Do you remember? @nestia/core boosts up runtime validation and JSON serialization through AOT compilation. By the way, @nestia/core performs the AOT compilation through standard TypeScript compiler API. Therefore, if you want to utilize those superfast decorators of @nestia/core module, you have to use only standard TypeScript compiler.

I also know that non-standard compilers are faster than standard. However, all of them are erasing type information, and skipping type checking for rapid compilation. By the way, without type information, @nestia/core can’t do anything. It is the reason why @nestia/core does not support them.