如何使用通用库处理 typescript monorepo (NestJS) 的生产构建?

Ban*_*ash 5 javascript typescript webpack nestjs nestjs-swagger

我正在努力构建打字稿 monorepo 的生产版本。我工作的公司有一个包含多个 API (nestJS) 的单声道存储库和一些公共库(主要是使用 tsc 构建的 typescript 源代码),遗憾的是我无法在这里分享。

这些 API 可以使用运行nest start,我们也可以@nestjs/swagger毫无问题地访问 API 中部署的内容。直到几周前,我们还在使用nest build --webpack以下 webpack 配置构建生产工件:

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;
                }
            })
        ]
    };
};
Run Code Online (Sandbox Code Playgroud)

我们不太确定这个配置,它让我们将 API 捆绑为每个包含所有依赖项的 API 的一个文件(根据我的大量研究,这是一种不好的模式)。我们对 IgnorePlugin 的使用是相当危险和冲突驱动的。

到目前为止,它工作正常,但我们现在无法访问@nestjs/swaggerAPI 提供和配置的 swagger 页面。该路由存在,但会导致一个白页(包含 API 描述的 json 已加载,但每个 swagger 静态资源加载都会返回 404)。

我考虑过一个招摇的静态资源副本,但这似乎是一个糟糕的模式。此外,我们没有node_modules,因为我们将Yarn 与即插即用nodeLinker 一起使用。

结论:经过几天的寻找良好实践和示例后,我有点迷失了,因为问题呈现出不同的维度:

  • 如何构建每个 API 并将其与其本地依赖项(公共库)捆绑在一起?部署是使用 docker 映像完成的,因此我们可以在映像构建阶段从 package.json 安装外部依赖项。
  • 我们真的需要 webpack 吗?
  • 如何服务swagger的静态资源?

我遵循了NestJS monorepo 文档,但它与我们的问题不符,因为该公司的 monorepo 包含多个 API 及其库,而且还包含一个 Web 应用程序和一个针对 Android 的 React-Native 应用程序。这两个不是嵌套项目的项目也使用共享库。

我已准备好重构整个 monorepo 配置,但我需要一个好的示例/示例作为我工作的基础。

感谢您的帮助、指点或任何想法