node-app-root-path icon indicating copy to clipboard operation
node-app-root-path copied to clipboard

Support for yarn workspaces

Open TheAifam5 opened this issue 7 years ago • 8 comments

Hey,

Currently the package is not compatible with yarn workspaces/lerna. Example of issue you can find here: https://github.com/typeorm/typeorm/issues/2805

Is there any way to support yarn workspaces/lerna for monorepo solutions?

Regards, TheAifam5

TheAifam5 avatar Nov 18 '18 14:11 TheAifam5

I just bumped into this as well. As a workaround, you can use the ConnectionOptionsReader directly to get options from any folder/file you like.

My connection stuff is still a bit messy, but I'll post it here as an example. Note that I apply the name "default" to my config so the connectionOptionsReader.get call will work.

import * as fs from 'fs';
import * as path from 'path';
import { createConnection, Connection, ConnectionOptionsReader } from "typeorm";

const connectionOptionsReader = new ConnectionOptionsReader({
    // TODO: Maybe look in every folder up from CWD
    root: process.cwd()
});

let connectionOptions;
let connection;

export default async function connect (): Promise<Connection> {
    if (!connection) {
        connectionOptions = {
            ...(await connectionOptionsReader.get(process.env.TYPEORM_CONNECTION || 'default')),
            entities: [__dirname + "/entity/**/*.js"],
            migrations: [__dirname + "/migration/**/*.js"],
            subscribers: [__dirname + "/subscriber/**/*.js"]
        };
        connection = createConnection(connectionOptions);
    }

    return connection;
}

Checking in process.cwd() seemed to mimic the behavior of the typeorm cli commands (like typeorm migration:generate), so it was convenient to have this behavior be consistent.

I also found it convenient to set the entities and other paths here so that I could consume this package from other repos, with their own ormconfig.js files, and not have to keep setting up these paths. Not sure if I'm doing all of this right, but at least I can load my configs in my monorepo now!

Hope that's helpful

jbreeden avatar Nov 19 '18 00:11 jbreeden

I figure out another workaround. You can use yarn's nohoist option to make sure that app-root-path doesn't get hosted to the top "project root" directory.

If you put this in your subproject/package.json and re-install packages (I usually do yarn install --force) you should end up with app-root-path in subproject/node_modules which then should cause a correct lookup and find your ormconfig.js:

{
  "workspaces": {
    "nohoist": [
      "typeorm/**",
      "typeorm"
    ]
  }
}

sgronblo avatar Sep 04 '19 06:09 sgronblo

I recently ran into this issue with Typeorm specifically as well.

@sgronblo's solution was great for Yarn v1, but if you're using Yarn v2–v3, you will likely need a .yarnrc.yml (I added it to my workspace directory) with the following:

nodeLinker: node-modules
nmHoistingLimits: workspaces

Now run yarn and you should see the node_modules folder inside your workspace directory, with Typeorm in node_modules as well.

(You can now safely remove the deprecated nohoist code from your root package.json)


nohoist is deprecated in v2+ and replaced by nmHoistingLimits (Docs).

This article also explains more about Yarn's decision to change away from nohoist.

P.S. if you're switching from Yarn v1 to v2+, I recommend reading their step-by-step upgrade guide.

nwittwer avatar Aug 16 '21 12:08 nwittwer

Does anyone have any recommendations on how to handle workspaces?

inxilpro avatar Aug 27 '21 20:08 inxilpro

I suppose we could read the package.json file in the discovered root path, and look for a "workspaces" key, and adjust the behavior if that exists…

inxilpro avatar Aug 27 '21 20:08 inxilpro

@inxilpro This is my goto package and just realised it's not bulletproof under yarn workspaces! Would be keen to help with this.

regarding looking for workspaces. Child projects can also have workspaces such as for nohoist

"workspaces": {
  "nohoist": ["react-native", "react-native/**"]
}

Do you have any other ideas of how we could solve this?

Brianzchen avatar Feb 16 '22 05:02 Brianzchen

Oof, that seems like a nightmare to resolve. I think the first step is to try to enumerate all the different cases that we need to account for and the expected behavior. Maybe you could start there and see if anyone has comments?

inxilpro avatar Feb 16 '22 18:02 inxilpro

It should be safe to just check the package.json if there's workspaces that's Array.isArray() or workspaces.packages that's Array.isArray() we can safely assume this is the root package of the mono repo. Should work well for yarn which is what I'm familiar with.

And if not, we keep traversing up the tree until we find a package.json that fits the criteria

Brianzchen avatar Mar 02 '22 09:03 Brianzchen