square / find-yarn-workspace-root

Algorithm for finding the root of a yarn workspace, extracted from yarnpkg.com
Apache License 2.0
49 stars 8 forks source link

Support for nested workspaces #18

Open hrougier opened 5 years ago

hrougier commented 5 years ago

Upcoming Yarn 2 will bring cleaner support for nested workspaces. As stated in the workspaces documentation:

if you try to setup nested workspaces then you must make sure that the nested worktree is defined as a valid workspace of its parent worktree (otherwise Yarn won't find its correct parent folder)

Here is an example of a monorepo taking advantage of nested workspaces:

/my-app
  package.json (my-app)
  /back
    package.json (@my-app/back)
    /microservice1
      package.json (@my-app/microservice1)
    /microservice2
      package.json (@my-app/microservice2)
  /front
    package.json (@my-app/front)
    /mobile
      package.json (@my-app/mobile)
    /web
      package.json (@my-app/web)

with my-app/package.json defining workspaces like this:

{
  "name: "my-app",
  "private": true,
  "workspaces": {
    "packages": ["back", "front"]
  }
}

my-app/back/package.json defining workspaces like this:

{
  "name: "@my-app/back",
  "private": true,
  "workspaces": {
    "packages": ["microservice1", "microservice2"]
  }
}

and my-app/front/package.json defining workspaces like this:

{
  "name: "@my-app/front",
  "private": true,
  "workspaces": {
    "packages": ["mobile", "web"]
  }
}

Issue

Current algorithm stops as soon as it finds a package.json containing a workspaces section up in the tree.

Note: it already is possible to nest workspaces with Yarn 1 by defining the root worktree package like this:

{
  "name: "my-app",
  "private": true,
  "workspaces": {
    "packages": ["back/**", "front/**"]
  }
}

With the workspaces section of @my-app/back and @my-app/front having no effect. But Yarn 2's way of defining packages definitely seems cleaner.

What would you think about having the algorithm to search for the most upward worktree package ? Something like:

currentPackage = ./package.json
while (hasParentPackage(currentPackage) && parentPackage.workspaces.includes(currentPackage) {
  currentPackage = parentPackage
}
return currentPackage

It will still work for Yarn 1 workspaces while being ready for Yarn 2 nested workspaces.

vitorcamachoo commented 4 years ago

Need this feature

hrougier commented 4 years ago

Yarn 2 is coming.

I did not mention that I opened this issue especially because a lot of libraries use this library, such as expo-yarn-workspaces for example. So you have to deal with this issue as soon as you want to use Yarn workspaces for expo apps 😕