How to handle the production build of a typescript monorepo (NestJS) with common librairies?

Viewed 154

I'm struggling with the production build of a typescript monorepo. The company I'm working for has a mono repository with multiple APIs (nestJS) and few common libraries (mainly typescript source code built using tsc) which I can't sadly share here.

The APIs are runnable using nest start and we can also access to the @nestjs/swagger deployed within the APIs without any problem. Until few weeks ago we were building the production artefact using nest build --webpack with the following webpack configuration :

const path = require("path");
const webpack = require("webpack");

module.exports = function (options) {
    return {
        ...options,
        mode: "production",
        target: "node",
        node: {
            __dirname: false,
            __filename: false
        },
        entry: "./src/main.ts",
        output: {
            path: path.resolve(__dirname, "build"),
            filename: "main.js",
            clean: true
        },
        externals: [...options.externals, "fastify-swagger"],
        module: {
            ...options.modules,
            rules: [
                {
                    test: /\.(t|j)sx?$/,
                    exclude: /node_modules/,
                    use: {
                        loader: "ts-loader",
                        options: {
                            transpileOnly: true,
                            projectReferences: true
                        }
                    }
                }
            ]
        },
        plugins: [
            ...options.plugins,
            new webpack.IgnorePlugin({
                checkResource(resource) {
                    const lazyImports = [
                        "@nestjs/microservices",
                        "@nestjs/microservices/microservices-module",
                        "@nestjs/websockets",
                        "@nestjs/websockets/socket-module",
                        "@nestjs/platform-express",
                        "@nestjs/swagger",
                        "@nestjs/mapped-types"
                    ];

                    if (!lazyImports.includes(resource)) {
                        return false;
                    }
                    try {
                        require.resolve(resource);
                    } catch (err) {
                        return true;
                    }
                    return false;
                }
            })
        ]
    };
};

We are not really sure of this configuration, it let use bundle our APIs as one file per API containing all the dependencies (which, based on my numerous researchs, is a bad pattern). Our usage of the IgnorePlugin is quite hazardous and conflict-driven.

Until now it was working fine but we are now unable to access the swagger page provided by @nestjs/swagger and configured within our APIs. The route exists but leads to a white page (the json containing the API description is loaded but every swagger static resource loading returns a 404).

I thought about a swagger static ressource copy but it seems to be a bad pattern. Moreover we do not have a node_modules since we are using Yarn with the Plug'n play nodeLinker.

In conclusion : after several days looking for good practices, examples I'm a bit lost since the problem presents different dimensions :

  • How to build each APIs and bundle it with its local dependencies (common libraries) ? The deployment is done using a docker image so we can install the external dependencies from the package.json at the image construction phase.
  • Do we really need webpack ?
  • How to serve the static resources of swagger ?

I followed the NestJS monorepo documentation but it doesn't correspond our problem since the company's monorepo contains severals APIs and their libraries but also a web application and a react-native application targeting Android. Both of those projects which are not nest projects are also using the shared libraries.

I'm ready to refactor the whole monorepo configuration but I need a good sample/example to base my work on.

Thank you for your help, pointers or any idea

0 Answers
Related