Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

loadNpmTasks fails to find task plugins when working with monorepo symlinks #1732

Open
tehhowch opened this issue Jun 18, 2021 · 2 comments · May be fixed by #1762
Open

loadNpmTasks fails to find task plugins when working with monorepo symlinks #1732

tehhowch opened this issue Jun 18, 2021 · 2 comments · May be fixed by #1762

Comments

@tehhowch
Copy link

When a dependency has been symlinked into a monorepo application, and this dependency is hoisted to the monorepo root, the dependency's tasks/ folder cannot be located by grunt.loadNpmTasks due to an incorrect assumption made when determining the root filepath.

The core issue is that the name parameter that loadNpmTasks is invoked with is not required to be a valid path part due to symlinks. Consider the example directory layout:

dev/
  corp-utils-monorepo/
    applications/
      neato-task-plugins/
        tasks/
          cool-task.js
        package.json
    // other stuff from the company
  my-team-monorepo/
    packages/
      team-app-1/
        Gruntfile.js
        package.json
    // other monorepo projects that also use the neato-task-plugins package

As a Good Company, scopes are used to guard internal packages from dependency squatting, and thus neato-task-plugins is published internally with the @mycorp scope. Its tasks are loaded from the team-app-1 package Gruntfile with grunt.loadNpmTasks('@mycorp/neato-task-plugins');

All is well, until one tries to develop a new corp-wide task and symlinks the task package by running e.g. yarn link '@mycorp/neato-task-plugins' from the my-team-monorepo directory.

Now, running the previously working grunt tasks fail with an error logged from here:

grunt/lib/grunt/task.js

Lines 412 to 417 in ee722d1

var tasksdir = path.join(root, name, 'tasks');
if (grunt.file.exists(tasksdir)) {
loadTasks(tasksdir);
} else {
grunt.log.error('Local Npm module "' + name + '" not found. Is it installed?');
}

e.g. >> Local Npm module "@mycorp/neato-task-plugins" not found. Is it installed?

And caused by the setting of root here:

root = pkgfile.substr(0, pkgfile.length - normailzedName.length - '/package.json'.length);

Where the variables have values like:

pkgfile === '/Users/me/dev/corp-utils-monorepo/applications/neato-task-plugins/package.json';
normailzedName ===                                 '@mycorp/neato-task-plugins';
// root === '/Users/me/dev/corp-utils-monorepo/appli'

However, we even after we fix the calculation of root, e.g. by doing something like slicing off 2 (or 3 for scoped packages) path elements, the code still fails to compute tasksdir correctly, looking for
/Users/me/dev/corp-utils-monorepo/applications/@mycorp/neato-task-plugins/tasks instead of
/Users/me/dev/corp-utils-monorepo/applications/neato-task-plugins/tasks.

I think the best solution is to use relative paths from the resolved pkgfile, rather than attempt to use path.join with varied arguments of root, name, or node_modules:

var tasksdir = path.join(path.dirname(pkgfile), 'tasks');

I'm not sure what the behavior should be for "collection plugins" that are symlinked, as I'm not familiar with those.

@redonkulus
Copy link

redonkulus commented Mar 24, 2023

@tehhowch I just hit this same exact issue as well in my monorepo. Were you able to work around this issue? The tasksdir change that you suggested worked well for me.

FYI, I've opened a PR based on the suggested fix above for discussion #1762

@micellius Since you were the original developer that added this support, do you have any idea's on a potential fix?

@tehhowch
Copy link
Author

@redonkulus nope, never worked around it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants