nx: Local plugin "Cannot find module" error

Current Behavior

Using a local plugin generator fails with error “Cannot find module”, as shown below.

Expected Behavior

As written in the docs, a plugin should be able to be used locally.

Steps to Reproduce

Run the following commands to create a new nx workspace with a local plugin package. yarn has been used, but the same result is obtained with npm.

npx create-nx-workspace@latest --preset=core my-workspace
cd my-workspace
rm -r node_modules
rm package-lock.json
echo '{"version": 2, "projects": {}}' >> workspace.json
yarn add -D @nrwl/nx-plugin -W
yarn nx g @nrwl/nx-plugin:plugin my-plugin --importPath @my-workspace/my-plugin
yarn nx g @nrwl/nx-plugin:generator app --project my-plugin
yarn nx g @my-workspace/my-plugin:app testapp --verbose

The last command fails with the error specified in Failure Logs.

As a workaround, the workspace files can be removed from the node_modules folder. With the additional following commands, the generator works as expected:

rm -r node_modules/@my-workspace/my-plugin
yarn nx g @my-workspace/my-plugin:app testapp

Failure Logs

...  my-workspace % yarn nx g @my-workspace/my-plugin:app testapp --verbose

yarn run v1.22.15
$ /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/.bin/nx g @my-workspace/my-plugin:app testapp --verbose
Cannot find module '/Users/davide/dev/temp/nx-issue/my-workspace/packages/my-plugin/src/generators/app/generator'
Require stack:
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/src/config/workspaces.js
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/src/command-line/generate.js
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/src/command-line/nx-commands.js
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/bin/init-local.js
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/bin/nx.js
Error: Cannot find module '/Users/davide/dev/temp/nx-issue/my-workspace/packages/my-plugin/src/generators/app/generator'
Require stack:
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/src/config/workspaces.js
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/src/command-line/generate.js
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/src/command-line/nx-commands.js
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/bin/init-local.js
- /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/bin/nx.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:999:19)
    at require (/Users/davide/dev/temp/nx-issue/my-workspace/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
    at /Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/src/config/workspaces.js:122:28
    at Object.<anonymous> (/Users/davide/dev/temp/nx-issue/my-workspace/node_modules/nx/src/command-line/generate.js:127:40)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/davide/dev/temp/nx-issue/my-workspace/node_modules/tslib/tslib.js:114:62)
error Command failed with exit code 1.

Environment

   Node : 17.8.0
   OS   : darwin arm64
   yarn : 1.22.15

   nx : 13.10.1
   @nrwl/angular : Not Found
   @nrwl/cypress : Not Found
   @nrwl/detox : Not Found
   @nrwl/devkit : 13.10.1
   @nrwl/eslint-plugin-nx : 13.10.1
   @nrwl/express : Not Found
   @nrwl/jest : 13.10.1
   @nrwl/js : 13.10.1
   @nrwl/linter : 13.10.1
   @nrwl/nest : Not Found
   @nrwl/next : Not Found
   @nrwl/node : Not Found
   @nrwl/nx-cloud : Not Found
   @nrwl/nx-plugin : 13.10.1
   @nrwl/react : Not Found
   @nrwl/react-native : Not Found
   @nrwl/schematics : Not Found
   @nrwl/storybook : Not Found
   @nrwl/web : Not Found
   @nrwl/workspace : 13.10.1
   typescript : 4.6.3
   rxjs : 6.6.7
   ---------------------------------------

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 13
  • Comments: 21 (9 by maintainers)

Commits related to this issue

Most upvoted comments

any news on this?

facing same issue with yarn 1 + yarn workspaces

workaround

make sure to manually create javascript file with the same file as you executor/generator implementation with following content:

image
// @filename generator.js
const { workspaceRoot } = require('nx/src/utils/workspace-root');
const { registerTsProject } = require('nx/src/utils/register');

registerTsProject(workspaceRoot, 'tsconfig.base.json');

module.exports = require('./generator.ts');

fix

~not sure if this can be fixed - require needs to be overriden by ts-node/swc while symlinking from node_modules (forced by workspaces).~ ~I’ve tried few things in nx source without any luck.~

UPDATE:

explicitly setting node options will properly override require so that should be possible:

NODE_OPTIONS="-r ts-node/register" yarn nx generate @myorg/workspace-extensions:workspace-extensions zzz --dry-run --verbose “just works”

UPDATE 2:

Looks like i figured it out! readPluginPackageJson function needs to be refactored to something like this

export function readPluginPackageJson(
  pluginName: string,
  paths = [workspaceRoot]
): {
  path: string;
  json: PackageJson;
} {
  try {
    const result = readModulePackageJson(pluginName, paths);
    // this will check if the plugin is 3rd party or if its local symlinked to node_modules via workspaces
    if (result.path.includes('node_modules')) {
      return {
        json: result.packageJson,
        path: result.path,
      };
    }
    return registerLocalPlugin();
  } catch (e) {
    if (e.code === 'MODULE_NOT_FOUND') {
      return registerLocalPlugin();
    }
    throw e;
  }

  function registerLocalPlugin() {
    const localPluginPath = resolveLocalNxPlugin(pluginName);
    if (localPluginPath) {
      const localPluginPackageJson = path.join(
        localPluginPath.path,
        'package.json'
      );
      return {
        path: localPluginPackageJson,
        json: readJsonFile(localPluginPackageJson),
      };
    }
  }
}

🫡

@AgentEnder should I send PR or you’ll take it from here ? cheers

Any news on this? Unfortunately the workarounds described above won’t work on my project.

@Hotell Thank you, running in the same issue on a vanilla install. 🎉

Props to @hotell for https://github.com/nrwl/nx/issues/9823#issuecomment-1207397040 – new to NX and spent a good 2 hours figuring out why this wasn’t working (and couldn’t reproduce fresh)

For any looking for the quick fix:

Manually create a generator.js or executor.js like the following:

// @filename generator.js
// @see https://github.com/nrwl/nx/issues/9823#issuecomment-1207397040
const { workspaceRoot } = require('nx/src/utils/workspace-root');
const { registerTsProject } = require('nx/src/utils/register');

registerTsProject(workspaceRoot, 'tsconfig.base.json');

module.exports = require('./generator.ts');
// @filename executor.js
// @see https://github.com/nrwl/nx/issues/9823#issuecomment-1207397040
const { workspaceRoot } = require('nx/src/utils/workspace-root');
const { registerTsProject } = require('nx/src/utils/register');

registerTsProject(workspaceRoot, 'tsconfig.base.json');

module.exports = require('./executor.ts');

the issue is still persisting in 14.3.6. Inside node_modules there is a symlink to the plugin project. After deleting it, the issue is resolved. @AgentEnder is there any way to work arround this issue?

The issue in this case is explicitly caused by npm workspaces, your issue sounds to be different. Can you open a new issue and include a reproduction? I’ve not seen this.