loopbackio / loopback-next

LoopBack makes it easy to build modern API applications that require complex integrations.
https://loopback.io
Other
4.97k stars 1.07k forks source link

In an extension, Loopback CLI depends on @loopback/core in list of dependencies #9476

Open benjaminrae opened 1 year ago

benjaminrae commented 1 year ago

Describe the bug

Running CLI commands such as lb4 model in a loopback extension cause the commands to be aborted.

Generation is aborted: Error: No `@loopback/core` package found in the "dependencies" section of C:\Users\Ben\Documents\dev\customer-service\extensions\intercom\package.json. The command must be run in a LoopBack project.

This is because @loopback/core is not listed in dependencies. Yes it is both a devDependency and a peerDependency in a loopback extension. This was last discussed in #2163 and implemented in #2166.

Wouldn't it be a better developer experience if the command accepted @loopback/core as a peerDependency?

Logs

$ lb4 model

No change to package.json was detected. No package manager install will be executed.
Generation is aborted: Error: No `@loopback/core` package found in the "dependencies" section of C:\Users\Ben\Documents\dev\customer-service\extensions\intercom\package.json. The command must be run in a LoopBack project.

Additional information

No response

Reproduction

n/a

benjaminrae commented 1 year ago

Now that I'm more familiar with the repository I have had a look into what is causing this.

In the function (checkDependencies)[https://github.com/loopbackio/loopback-next/blob/391c3158c3fecb17baf267a86c1b5a651b1f640c/packages/cli/lib/version-helper.js#L36] the project's dependencies are checked unless the command is 'update', then it checks peer and dev dependencies too.

  const projectDepsNames = isUpdate
    ? Object.keys(
        // Check dependencies, devDependencies, and peerDependencies
        {
          ...pkgDeps.dependencies,
          ...pkgDeps.devDependencies,
          ...pkgDeps.peerDependencies,
        },
      )
    : Object.keys(pkgDeps.dependencies);

  const isLBProj = isUpdate
    ? projectDepsNames.some(n => n.startsWith('@loopback/'))
    : projectDepsNames.includes(dependentPackage);

There are two solutions I can see to the issue.

  1. Checking peer dependencies as well as dependencies to identity if the loopback project is an extension.
  2. Adding @loopback/core as a dependency of extensions generated by the CLI.

Otherwise the only workaround I've found is to use the LB4 CLI with an extension is to add @loopback/core as a dependency manually after creating the extension.

I'd love to hear thoughts and then I can submit a PR with a fix.