apollographql / apollo-tooling

✏️ Apollo CLI for client tooling (Mostly replaced by Rover)
https://apollographql.com
MIT License
3.04k stars 469 forks source link

Yarn V2 compatibility #1850

Open such opened 4 years ago

such commented 4 years ago

Intended outcome:

apollo commands should work normally when using Yarn V2 with Plug'n'Play

Actual outcome:

It fails with the following:

(node:61) Error Plugin: apollo: could not find package.json with { type: 'core',
  root:
   '/app/.yarn/cache/apollo-npm-2.25.0-39bd67c43e-2.zip/node_modules/apollo',
  name: '@oclif/plugin-help' }
module: @oclif/config@1.14.0
task: loadPlugins
plugin: apollo
root: /app/.yarn/cache/apollo-npm-2.25.0-39bd67c43e-2.zip/node_modules/apollo
See more details with DEBUG=*
(node:61) Error Plugin: apollo: could not find package.json with { type: 'core',
  root:
   '/app/.yarn/cache/apollo-npm-2.25.0-39bd67c43e-2.zip/node_modules/apollo',
  name: '@oclif/plugin-not-found' }
module: @oclif/config@1.14.0
task: loadPlugins
plugin: apollo
root: /app/.yarn/cache/apollo-npm-2.25.0-39bd67c43e-2.zip/node_modules/apollo
See more details with DEBUG=*
(node:61) Error Plugin: apollo: could not find package.json with { type: 'core',
  root:
   '/app/.yarn/cache/apollo-npm-2.25.0-39bd67c43e-2.zip/node_modules/apollo',
  name: '@oclif/plugin-plugins' }
module: @oclif/config@1.14.0
task: loadPlugins
plugin: apollo
root: /app/.yarn/cache/apollo-npm-2.25.0-39bd67c43e-2.zip/node_modules/apollo
See more details with DEBUG=*
(node:61) Error Plugin: apollo: could not find package.json with { type: 'core',
  root:
   '/app/.yarn/cache/apollo-npm-2.25.0-39bd67c43e-2.zip/node_modules/apollo',
  name: '@oclif/plugin-warn-if-update-available' }
module: @oclif/config@1.14.0
task: loadPlugins
plugin: apollo
root: /app/.yarn/cache/apollo-npm-2.25.0-39bd67c43e-2.zip/node_modules/apollo
See more details with DEBUG=*
Error: @oclif/parser tried to access @oclif/errors, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.
Required package: @oclif/errors (via "@oclif/errors")
Required by: @oclif/parser@npm:3.8.4 (via /app/.yarn/cache/@oclif-parser-npm-3.8.4-dd47359399-2.zip/node_modules/@oclif/parser/lib/)
Require stack:
- /app/.yarn/cache/@oclif-parser-npm-3.8.4-dd47359399-2.zip/node_modules/@oclif/parser/lib/validate.js
- /app/.yarn/cache/@oclif-parser-npm-3.8.4-dd47359399-2.zip/node_modules/@oclif/parser/lib/index.js
- /app/.yarn/$$virtual/@oclif-command-virtual-818296db1a/0/cache/@oclif-command-npm-1.5.19-b10e786c92-2.zip/node_modules/@oclif/command/lib/flags.js
- /app/.yarn/$$virtual/@oclif-command-virtual-818296db1a/0/cache/@oclif-command-npm-1.5.19-b10e786c92-2.zip/node_modules/@oclif/command/lib/index.js
- /app/.yarn/cache/apollo-npm-2.25.0-39bd67c43e-2.zip/node_modules/apollo/bin/run
    at Object.makeError (/app/.pnp.js:34509:34)
    at resolveToUnqualified (/app/.pnp.js:41869:37)
    at resolveRequest (/app/.pnp.js:41959:27)
    at Object.resolveRequest.maybeLog [as resolveRequest] (/app/.pnp.js:42027:26)
    at Function.module_1.Module._resolveFilename (/app/.pnp.js:41222:34)
    at Function.module_1.Module._load (/app/.pnp.js:41107:40)
    at Object.<anonymous> (/app/.yarn/cache/@oclif-parser-npm-3.8.4-dd47359399-2.zip/node_modules/@oclif/parser/lib/validate.js:3:18)

How to reproduce the issue:

Bootstrap any Yarn V2 project, add the apollo dependency and run any apollo command.

Versions

Tested with 2.21.2 and latest (2.25.0)

nnennajohn commented 4 years ago

Hi. Is there any status on this, or guide on how to use with Yarn 2?

snasirca commented 4 years ago

In Yarn 2, when I run apollo client:codegen --target=typescript, I get the following error:

(node:82281) Error Plugin: apollo: could not find package.json with {
  type: 'core',
  root: '/Users/shahn/Development/work/packmanager/.yarn/cache/apollo-npm-2.28.3-3d185f04c8-3.zip/node_modules/apollo',
  name: '@oclif/plugin-help'
}
module: @oclif/config@1.15.1
task: loadPlugins
plugin: apollo
root: /Users/shahn/Development/work/packmanager/.yarn/cache/apollo-npm-2.28.3-3d185f04c8-3.zip/node_modules/apollo
See more details with DEBUG=*
(Use `node --trace-warnings ...` to show where the warning was created)
(node:82281) Error Plugin: apollo: could not find package.json with {
  type: 'core',
  root: '/Users/shahn/Development/work/packmanager/.yarn/cache/apollo-npm-2.28.3-3d185f04c8-3.zip/node_modules/apollo',
  name: '@oclif/plugin-not-found'
}
module: @oclif/config@1.15.1
task: loadPlugins
plugin: apollo
root: /Users/shahn/Development/work/packmanager/.yarn/cache/apollo-npm-2.28.3-3d185f04c8-3.zip/node_modules/apollo
See more details with DEBUG=*
(node:82281) Error Plugin: apollo: could not find package.json with {
  type: 'core',
  root: '/Users/shahn/Development/work/packmanager/.yarn/cache/apollo-npm-2.28.3-3d185f04c8-3.zip/node_modules/apollo',
  name: '@oclif/plugin-plugins'
}
module: @oclif/config@1.15.1
task: loadPlugins
plugin: apollo
root: /Users/shahn/Development/work/packmanager/.yarn/cache/apollo-npm-2.28.3-3d185f04c8-3.zip/node_modules/apollo
See more details with DEBUG=*
(node:82281) Error Plugin: apollo: could not find package.json with {
  type: 'core',
  root: '/Users/shahn/Development/work/packmanager/.yarn/cache/apollo-npm-2.28.3-3d185f04c8-3.zip/node_modules/apollo',
  name: '@oclif/plugin-warn-if-update-available'
}
module: @oclif/config@1.15.1
task: loadPlugins
plugin: apollo
root: /Users/shahn/Development/work/packmanager/.yarn/cache/apollo-npm-2.28.3-3d185f04c8-3.zip/node_modules/apollo
See more details with DEBUG=*
  ✔ Loading Apollo Project
  ✔ Generating query files with 'typescript' target - wrote 10 files

It still appears to be functioning as we need it to. It creates the generated type files. But it outputs a bunch of non-blocking errors.

Versions

Tested with apollo 2.28.3

snasirca commented 4 years ago

I'm able to get past this by temporarily patching @oclif/config package's lib/plugin.js:89:

diff --git a/lib/plugin.js b/lib/plugin.js
index 583f75af38f..95fd59b86ed 100644
--- a/lib/plugin.js
+++ b/lib/plugin.js
@@ -85,7 +85,9 @@ class Plugin {
     async load() {
         this.type = this.options.type || 'core';
         this.tag = this.options.tag;
-        const root = await findRoot(this.options.name, this.options.root);
+        let root = await findRoot(this.options.name, this.options.root);
+        if (!root)
+            root = require.resolve(this.options.name + '/package.json').split('/package.json')[0];
         if (!root)
             throw new Error(`could not find package.json with ${util_1.inspect(this.options)}`);
         this.root = root;

I don't see why the plugin loader doesn't just use require.resolve to find packages to load. Maybe a limitation within npm.

ldiqual commented 4 years ago

@snasirca Does this mean it's an oclif issue then? Maybe worth filing a bug on https://github.com/oclif/config/issues ?

dc-pm commented 3 years ago

I think this is a oclif issue - there's even a PR to fix this already: https://github.com/oclif/config/pull/171 but it seems like the repository doesn't get much love as this has been open for several months.

Until then, as a quick fix I had some luck with using pnpify to wrap the tool: https://yarnpkg.com/advanced/pnpify/

yarn add @yarnpkg/pnpify
yarn pnpify apollo client:codegen ...
tonypee commented 3 years ago

Thanks @dc-pm - that worked well!

timini commented 3 years ago

any update on this, also experiencing it

timini commented 3 years ago

no luck with @yarnpkg/pnpify either

yarn pnpify apollo client:codegen Internal Error: spawn apollo ENOENT at Process.ChildProcess._handle.onexit (node:internal/child_process:282:19) at onErrorNT (node:internal/child_process:477:16) at processTicksAndRejections (node:internal/process/task_queues:83:21)

lafiosca commented 3 years ago

It seems to me that the @oclif/config warnings have nothing to do with the fatal problem here. Yarn in PnP mode is complaining and crashing out because various apollo packages do not specify their graphql dependencies explicitly.

For example, apollo-codegen-typescript does not list graphql as a dependency or a peerDependency: https://github.com/apollographql/apollo-tooling/blob/6d69f226c2e2c54b4fc0de6394d813bddfb54694/packages/apollo-codegen-typescript/package.json

But you can see right on the first line of this file that it's using graphql: https://github.com/apollographql/apollo-tooling/blob/6d69f226c2e2c54b4fc0de6394d813bddfb54694/packages/apollo-codegen-typescript/src/language.ts#L1

Yarn PnP doesn't like this. When you try to run the codegen script you'll get an error like this:

    Error: apollo-codegen-typescript tried to access graphql, but it isn't declared in its dependencies; this makes
    the require call ambiguous and unsound.

    Required package: graphql
    Required by: apollo-codegen-typescript@npm:0.40.4 (via [...]/.yarn/cache/apollo-codegen-typ
    escript-npm-0.40.4-1b43ae28cc-8a04bb1236.zip/node_modules/apollo-codegen-typescript/lib/)

One workaround is to use yarn's packageExtensions to override the package files and add dependencies. By adding the following to my monorepo's root .yarnrc.yml, I was able to get my codegen script to run:

packageExtensions:
  'apollo-link-context@*':
    dependencies:
      graphql: '*'
  'apollo-link-error@*':
    dependencies:
      graphql: '*'
  'apollo-codegen-core@*':
    dependencies:
      graphql: '*'
  'apollo-codegen-flow@*':
    dependencies:
      graphql: '*'
  'apollo-codegen-scala@*':
    dependencies:
      graphql: '*'
  'apollo-codegen-swift@*':
    dependencies:
      graphql: '*'
  'apollo-codegen-typescript@*':
    dependencies:
      graphql: '*'

Apparently all of these dependencies are imported, even if you're generating code for a single language. So all of these entries were necessary to get it to run.

The @oclif/config problem mentioned above causes the script to spew a bunch of error messages about plugins missing package.json files, but they don't seem to impact the functionality of the script:

(node:72254) Error Plugin: apollo: could not find package.json with {
  type: 'core',
  root: '[...]/.yarn/cache/apollo-npm-2.33.6-c2094045c5-e713980c59.zip/node_modules/apollo',
  name: '@oclif/plugin-plugins'
}
module: @oclif/config@1.17.0
task: loadPlugins
plugin: apollo
root: [...]/.yarn/cache/apollo-npm-2.33.6-c2094045c5-e713980c59.zip/node_modules/apollo
See more details with DEBUG=*

It would be nice for @oclif/config to not do this, but I don't think the require.resolve patch mentioned earlier in this thread is enough to fix it. This would cause oclif to try resolving various paths which are not specified in its own dependencies, triggering the same yarn PnP error that apollo was causing. Additionally, it looks like oclif is using that logic to find various project roots to check for the existence of oclif.manifest.json files. It probably needs a more significant patch.

Ultimately even if the oclif errors are resolved, based on what I've described here I think apollo needs to update their various package.json dependencies if they're going to play nicely with yarn PnP.

-- Edited to add: here's a reference to the yarn documentation explaining the error: https://classic.yarnpkg.com/en/docs/pnp/troubleshooting/ Edited again to add: apollo-codegen-typescript was missing from my packageExtensions example

Nicoowr commented 2 years ago

It seems this issue was solved in @oclif/config: https://github.com/oclif/config/pull/289

It'd be great if apollo could bump the version of oclif to 1.18.2

benatshippabo commented 2 years ago

It seems this issue was solved in @oclif/config: oclif/config#289

It'd be great if apollo could bump the version of oclif to 1.18.2

It would be great to have the version bumped! But in the meantime you can just use yarn resolutions to get the updated version. Also, you may need to patch the package.json of some of the oclif plugins that do not specify the main field