How to make things work when in a monorepo with node.js?

Viewed 4732

I have a folder structure like this

  • root
    • libs
    • project-a
    • project-b

Now I use link in package json to link libs to my projects. But a lot of weird things happen. Modules are not installed properly... etc Some node_modules are not even installed, a node_module complains is missing some other things. node_modules are not installed the same way if you run twice... etc super weird issues. I use yarn.

I was wondering how do you deal with this?

Another option is to build libs to js and publish to npm. But every change, requires a ton of work, is a pain. Also when you click through an import, it will go to the built .js file instead of source code. So editing is also a pain, you need to manually open the file. Currently I can just click through to the source of libs from any project.

2 Answers

I personally followed through https://medium.com/ah-technology/a-guide-through-the-wild-wild-west-of-setting-up-a-mono-repo-with-typescript-lerna-and-yarn-ed6a1e5467a and https://blog.usejournal.com/step-by-step-guide-to-create-a-typescript-monorepo-with-yarn-workspaces-and-lerna-a8ed530ecd6d before creating my repo at https://github.com/cefn/lauf which is working well for me.

I'm able to have distinct groups of workspaces (apps and modules) where modules are intended for eventual packaging as npm modules, but are initially 'aliased' locally using this central tsconfig.

central config which aliases packages

( https://github.com/cefn/lauf/blob/main/tsconfig.build.json )

This config and these aliases are referenced within the packages so I can develop and bundle against the local copies AS IF they were actual scoped npm packages under the @lauf scope...

example package importing the central config

( https://github.com/cefn/lauf/blob/main/apps/noredux-async/tsconfig.json )

Most of the effort of installing and hoisting shared dependencies is via yarn workspaces

enter image description here

( https://github.com/cefn/lauf/blob/main/package.json#L6-L9 )

Yarn is used to e.g. install all dependencies of the separate packages with just yarn and is a good basis for hosting complex procedures to validate package structure, like this validate script run via yarn run validate...

You need to setup a project using a monorepo manager for node.js.

There are few options:

All of the above do some kind of hoisting of node_modules and and magics with symlinks, which more or less have quirks.

This monorepo manager: https://www.electrode.io/fynpo/, treats all npm packages under a directory like they are published.

For example, you can combine multiple npm module repos in a new directory without making any changes to their source and it would work, and they will build and pull in each other from the local copies.

npm i -g fyn
mkdir monorepo
cd monorepo
npm init --yes
fyn add fynpo
mkdir packages
cd packages
git clone <git-url-to-npm-module-repo-1>
git clone <git-url-to-npm-module-repo-2>
git clone <git-url-to-npm-module-repo-3>
git clone <git-url-to-npm-module-repo-4>
cd ..
npx fynpo
  • make changes to the original source and they will reflect in other node_modules
  • if you use something like TypeScript and enable sourcemap, then the debugger will show original source.
Related