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