edit 2: after setting up the workspace, some dependencies or all the dependencies will be placed at project root instead of each workspace. it is intentional by design, to avoid having duplicated packages in each workspace. this might surprise some but actually very useful in maintaining bigger systems.
CodePudding user response:
I want to share what I had to do in my projects and file structure to share models, types, enums, entities, etc., between the server (NestJS) and the client (React).
First of all, I started setting up npm workspaces to achieve a monorepo, as @sungryeol described in his detailed answer (thanks for it).
Unfortunately, it was only half of the way to making it work. So here is a solution I came up with (remarks are welcome) in addition to workspaces:
Client (react)
create react app
is designed to compile code only from the src
directory. Because I am using typescript in my shared code, I need to compile it to make it work. To make CRA compile my shared code, I used react-app-rewired
to modify the webpack config with the following config-overrides.js
file:
const path = require('path');
module.exports = function override(config, env) {
const babelLoaderModule = require.resolve('babel-loader');
const rule = config.module.rules[1].oneOf.find(rule => rule.loader === babelLoaderModule);
rule.include = [
rule.include,
path.resolve(__dirname, '../shared')
];
return config;
}
React finally started accepting my shared code without any issues.
Server (NestJS)
Since NestJS uses tsc
as the compiler, I had to specify the directory of the shared code in the server's tsconfig.json
as a path.
"paths": {
"@managed-businesses/shared/*": [
"../shared/*"
]
}
This made my shared code compile when I started the nest app, but it couldn't find the entry point, as it compiled the code in the following structure
dist
├── server
│ ├── src
│ ├── main.d.ts
│ └── main.js
├── shared
│ ├── dtos
│ └── enums
└── tsconfig.build.tsBuildInfo
while Nest lookup for the src/main.js
file to be at the root of the dist
directory.
To fix that, I had to tweak the nest-cli.json
file to lookup the file in the dist/server/src
directory. Here is my new config for nest-cli.
{
"collection": "@nestjs/schematics",
"sourceRoot": "server/src"
}
After all, the server finally works with the shared code, and I don't need to duplicate it between the projects. I am probably missing something or did something incorrectly, and I'll be happy to know if there is a better way, but at the bottom line, it works.