javascript - Hur hanterar man produktionsbygget av ett TypeScript-monorepo (NestJS) med gemensamma bibliotek?


Jag har problem med produktionsbygget av ett TypeScript-monorepo. Företaget jag arbetar för har ett monorepository med flera API:er (NestJS) och några gemensamma bibliotek (främst TypeScript-källkod byggd med tsc) som jag tyvärr inte kan dela här.

API:erna kan köras med nest start och vi kan också få åtkomst till @nestjs/swagger som är distribuerad inom API:erna utan några problem. Fram tills för några veckor sedan byggde vi produktionsartefakten med nest build --webpack med följande webpack-konfiguration:

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;
                }
            })
        ]
    };
};

Vi är inte riktigt säkra på denna konfiguration, den låter oss paketera våra API:er som en fil per API som innehåller alla beroenden (vilket, baserat på min omfattande forskning, är ett dåligt mönster). Vår användning av IgnorePlugin är ganska riskabel och konfliktdriven.

Hittills fungerade det bra men vi kan nu inte nå swagger-sidan som tillhandahålls av @nestjs/swagger och är konfigurerad inom våra API:er. Rutten finns men leder till en vit sida (json-filen som innehåller API-beskrivningen laddas men varje försök att ladda swagger-statisk resurs returnerar 404).

Jag tänkte på en swagger statisk resurskopiering men det verkar vara ett dåligt mönster. Dessutom har vi inga node_modules eftersom vi använder Yarn med Plug'n play nodeLinker.

Sammanfattningsvis: efter flera dagar av att leta efter goda metoder, exempel är jag lite förlorad eftersom problemet har olika dimensioner:

  • Hur man bygger varje API och paketerar det med dess lokala beroenden (vanliga bibliotek)? Distributionen görs med en Docker-bild så att vi kan installera de externa beroendena från package.json under bildkonstruktionsfasen.
  • Behöver vi verkligen webpack?
  • Hur man serverar de statiska resurserna för swagger?

Jag följde NestJS monorepo-dokumentationen men den motsvarar inte vårt problem eftersom företagets monorepo innehåller flera API:er och deras bibliotek men också en webbapplikation och en react-native-applikation som riktar sig mot Android. Båda dessa projekt som inte är nest-projekt använder också de delade biblioteken.

Jag är redo att refaktorera hela monorepo-konfigurationen, men jag behöver ett bra exempel att basera mitt arbete på.

Tack för din hjälp, tips eller någon idé

Relaterade artiklar