Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workable setup for pnpm monorepo w. typescript, vite & rollup

I build a monorepo using pnpm workspaces and I have trouble getting it work. It uses typescript, vite on frontends, rollup at backend microservices.

Here is the setup:

package.json                            <== all dependencies reside here
tsconfig.json
pnpm-workspaces.yaml
- commonlib/
  package.json, tsconfig.json, rollup.config.js
  src/
    ...interfaces, types etc---
- serverlib/
  package.json, tsconfig.json, rollup.config.js
  src/
    ...modules for common server/microservice funtionality---
- weblib/
  package.json, tsconfig.json, vite.config.js
  src/
    ...react etc components & functions---
- servers/
    srv-gateway/
      package.json, tsconfig.json, rollup.config.js
      src/
        ...server code...
    ms-xxx/                             <== Multiple REST microservices
      package.json, tsconfig.json, rollup.config.js
      src/
        ...microservice code...
- webapps/
    app/
      package.json, tsconfig.json, vite.config.js
      src/
        ...main application code---
    admin/
      package.json, tsconfig.json, vite.config.js
      src/
        ...application code---
    app-2/                              <== Other webapps / micro frontends
      ...

My requirement(s):

  • I keep all package dependencies at the root package.json
  • I want to access my modules like @myapp/commonlib, @myapp/weblib, ...
  • I don't plan to publish and of these to npmjs (they are not generic - so I don't want to semver the libraries)
  • I want most higher version dependencies (I update them daily). I also want multiple types on each, cjs, es, esm etc this might be where I messed up).

My problem(s):

  • I'm lost in the definitions in package.json's, tsconfig.json's, rollup.config.json's & vite.config.json's - it became too complex.
  • Do I need to compile/transpile the *lib & version them or just include them somehow?
  • Include how? As dependencies (@myapp/...)? Using "path" and "references" in actual servers/webapps? If so, do I need vite/rollup these *lib?
  • E.g. in weblib, I compile it excluding all external packages (vite.config.ts -> rollupOptions -> external) but now I cannot make the webapp work (blank screen).

I had a working system beforehand, where I defined @myapp/uilib, @myapp/graphlib etc and used "path" and "references". But as they did increase in number, I wanted to combine them into a single library. This is where I lost track. I made too many changes to revert from a previous git state. The blame goes to many conflicting tutorials I watched & ChatGPT, and of course mainly myself :/

Apperantly I do it all wrong, now I want to learn the correct way.

Thank you in advance for your help.

like image 614
Bülent Özden Avatar asked Dec 16 '25 12:12

Bülent Özden


1 Answers

After a long list of trials, struggles, and performance tests, I decided on these:

  • Having dependencies at the root of monorepo is a bad idea. Whenever I reached the Docker creation stage, I had to move dependencies into respective packages. The package manager (pnpm) already keeps them at the highest level and links to them from individual packages.
  • As I'm working with microservices, each got small after refactoring. So, the packaging phase became unnecessary, and I ditched rollup on the server side and turned my face to esbuild. It provides nice, optimized esm (ES2020 for now) bundles and respects the "references" in tsconfig.json. (tsup does not - yet, I tried and removed it)
  • As a result of the previous point, I moved static files out of the bundle generation (I had static data files/jsons that I served with express-static). I moved the data to a static.mydomain.com installation, so I've gotten rid of the long copy processes during builds.
  • I keep the vite/rollup setups on the react frontend applications for now, they work ok - except for the problem with vite in dev mode starting very slow.
  • In all common, frontend, and server libraries, I used esbuild bundles again (ES2020 only).
  • I also moved all final frontend and servers to "apps", and moved libraries to "libs" directories.
  • I kept using the multi-level tsconfig.json structure.

This was a long lesson for me in my first monorepo. I'll try to update this post with my structure.

like image 53
Bülent Özden Avatar answered Dec 19 '25 05:12

Bülent Özden



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!