Separating the codebases into projects is what I see most of the time. Some folks will separate them across repositories and then use NPM dependencies to bridge the projects.
Personally, I find the monorepo structure to be a lot more useful here. NPM or Yarn workspaces and workspace dependencies would be a good friend!
Using the encapsulation that a monorepo provides, you can isolate your incompatible toolchains.
NounsDAO's monorepo is a great example of this being done on a decently large scale.
The premise is pretty simple and follows typical monorepo structure:
- use workspaces to break up your codebase by tech stack (e.g. separate your contracts from your web interface code)
- use workspace imports to get cross-workspace imports working (so you won't have the issue with React complaining about unresolved imports, you'd just be importing another package)
- install whatever specialized tooling you want to in each workspace, the isolation will prevent any incompatibilities or weird interactions between the different toolchains
We can use NounsDAO's monorepo as a case-study here, this is a high-level view of their monorepo structure:
.
├── packages/
│ ├── nouns-api/ (Express API server)
│ │ ├── src/
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ ├── docker-compose.yaml
│ │ └── ...
│ ├── nouns-contracts/ (Solidity contracts, Hardhat + Typechain)
│ │ ├── contracts/
│ │ ├── src/ (
│ │ ├── typechain/
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ ├── .solcover.js
│ │ ├── hardhat.config.js
│ │ └── ...
│ ├── nouns-webapp/ (React webapp)
│ │ ├── public/
│ │ ├── src/
│ │ ├── package.json
│ │ └── ...
│ └── ...
├── .eslintrc.js
├── .prettierrc
├── package.json
└── ...
In the root directory, they have all common tooling like ESLint, Prettier, and base Typescript configuration.
In each workspace package, they have completely separate (and sometimes incompatible) toolchains. If we dig into their package.json
files, we see names like @nouns/...
and dependencies following that pattern. Typical monorepo stuff!
I could go on about monorepos, but I probably won't say anything that isn't already out there on some blog. It's a useful tool in this case specifically to help you isolate incompatible toolchains!