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

[Bug] RC-23 unable to find file #706

Closed
1 task
zdm opened this issue Jan 18, 2020 · 17 comments · Fixed by #2068
Closed
1 task

[Bug] RC-23 unable to find file #706

zdm opened this issue Jan 18, 2020 · 17 comments · Fixed by #2068
Labels
bug Something isn't working reproducible This issue can be successfully reproduced

Comments

@zdm
Copy link

zdm commented Jan 18, 2020

  • I'd be willing to implement a fix

Describe the bug

This code worked in RC-19, but not works in RC-23.

const fs = require("fs");

const rc = `---
root: true

extends:
    - 'eslint:recommended'
`;

fs.writeFileSync('./.eslintrc.yaml', rc);
fs.writeFileSync('./1.js', '');

fs.writeFileSync(`./.yarnrc.yml`, `enableGlobalCache: true\n`);

await yarn(`init`);
await yarn(`add`, `eslint`);

await expect(yarn(`eslint`, `1.js`)).resolves.toEqual(``);
@zdm zdm added the bug Something isn't working label Jan 18, 2020
@yarnbot yarnbot added the broken-repro The reproduction in this issue is broken label Jan 19, 2020
@yarnbot

This comment has been minimized.

@arcanis
Copy link
Member

arcanis commented Jan 19, 2020

I tested it locally and it seemed to work; note that you needed to use yarn init before yarn add otherwise Yarn doesn't know where to add the dependencies. Does that solve your problem?

@yarnbot yarnbot added reproducible This issue can be successfully reproduced and removed broken-repro The reproduction in this issue is broken labels Jan 19, 2020
@yarnbot

This comment has been minimized.

@yarnbot yarnbot added unreproducible This issue cannot be reproduced on master and removed reproducible This issue can be successfully reproduced labels Jan 19, 2020
@yarnbot

This comment has been minimized.

2 similar comments
@yarnbot

This comment has been minimized.

@yarnbot

This comment has been minimized.

@zdm
Copy link
Author

zdm commented Jan 19, 2020

Of course, I am using yarn init before.
I am not sure, that i wrote sherlock script correctly, but this issue is reproduced for RC > 19 under windows and linux.

yarn --version
yarn init
yarn add eslint
touch 1.js
cat <<EOF >> ./.eslintrc.yaml
root: true
extends:
    - 'eslint:recommended'
EOF
yarn eslint 1.js
[root@devel:/var/local/111]$ yarn --version
2.0.0-rc.23
[root@devel:/var/local/111]$ yarn init
{
  name: '111'
}
[root@devel:/var/local/111]$ yarn add eslint
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: Done
[root@devel:/var/local/111]$ touch 1.js
[root@devel:/var/local/111]$ cat <<EOF >> ./.eslintrc.yaml
> root: true
> extends:
>     - 'eslint:recommended'
> EOF
[root@devel:/var/local/111]$ yarn eslint 1.js
Error: Cannot read config file: /root/.yarn/global/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/conf/eslint-recommended.js
Error: Cannot find module '/root/.yarn/global/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/conf/eslint-recommended.js'
Require stack:
- /root/.yarn/global/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/noop.js
Require stack:
- /root/.yarn/global/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/noop.js
Referenced from: /var/local/111/.eslintrc.yaml
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:973:15)
    at Function.module_1.Module._resolveFilename (/var/local/111/.pnp.js:10345:54)
    at resolveFileName (/root/.yarn/global/cache/resolve-from-npm-4.0.0-f758ec21bf-1.zip/node_modules/resolve-from/index.js:29:39)
    at resolveFrom (/root/.yarn/global/cache/resolve-from-npm-4.0.0-f758ec21bf-1.zip/node_modules/resolve-from/index.js:43:9)
    at module.exports (/root/.yarn/global/cache/resolve-from-npm-4.0.0-f758ec21bf-1.zip/node_modules/resolve-from/index.js:46:41)
    at module.exports (/root/.yarn/global/cache/import-fresh-npm-3.2.1-b4f6711244-1.zip/node_modules/import-fresh/index.js:13:19)
    at loadJSConfigFile (/root/.yarn/global/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/config-array-factory.js:201:16)
    at loadConfigFile (/root/.yarn/global/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/config-array-factory.js:284:20)
    at ConfigArrayFactory._loadConfigData (/root/.yarn/global/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/config-array-factory.js:496:13)
    at ConfigArrayFactory._loadExte

@zdm
Copy link
Author

zdm commented Jan 19, 2020

So, the problem is in global store.
Here is my .yarnrc.yml, located in ~.

enableGlobalCache: true

globalFolder: '.yarn/global'
pnpUnpluggedFolder: '.yarn/unplugged'
yarnPath: '.yarn/releases/yarn-berry.js'

Everything works, when I disable global store.

@yarnbot yarnbot added reproducible This issue can be successfully reproduced and removed unreproducible This issue cannot be reproduced on master labels Jan 19, 2020
@yarnbot

This comment has been minimized.

@yarnbot
Copy link
Collaborator

yarnbot commented Jan 19, 2020

This issue reproduces on master:

Error: expect(received).resolves.toEqual()

Received promise rejected instead of resolved
Rejected to value: [Error: Command failed: /usr/bin/node /github/workspace/scripts/actions/../run-yarn.js eslint 1.js
Error: Cannot read config file: /github/home/.yarn/berry/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/conf/eslint-recommended.js
Error: Cannot find module '/github/home/.yarn/berry/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/conf/eslint-recommended.js'
Require stack:
- /github/home/.yarn/berry/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/noop.js
Require stack:
- /github/home/.yarn/berry/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/noop.js
Referenced from: /tmp/tmp-27KM0Wc49J68tZ/.eslintrc.yaml
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:797:15)
    at Function.module_1.Module._resolveFilename (/tmp/tmp-27KM0Wc49J68tZ/.pnp.js:10378:54)
    at resolveFileName (/github/home/.yarn/berry/cache/resolve-from-npm-4.0.0-f758ec21bf-1.zip/node_modules/resolve-from/index.js:29:39)
    at resolveFrom (/github/home/.yarn/berry/cache/resolve-from-npm-4.0.0-f758ec21bf-1.zip/node_modules/resolve-from/index.js:43:9)
    at module.exports (/github/home/.yarn/berry/cache/resolve-from-npm-4.0.0-f758ec21bf-1.zip/node_modules/resolve-from/index.js:46:41)
    at module.exports (/github/home/.yarn/berry/cache/import-fresh-npm-3.2.1-b4f6711244-1.zip/node_modules/import-fresh/index.js:13:19)
    at loadJSConfigFile (/github/home/.yarn/berry/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/config-array-factory.js:201:16)
    at loadConfigFile (/github/home/.yarn/berry/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/config-array-factory.js:284:20)
    at ConfigArrayFactory._loadConfigData (/github/home/.yarn/berry/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/config-array-factory.js:496:13)
    at ConfigArrayFactory._loadExtendedBuiltInConfig (/github/home/.yarn/berry/cache/eslint-npm-6.8.0-d27045f313-1.zip/node_modules/eslint/lib/cli-engine/config-array-factory.js:753:25)

]
    at expect (/github/workspace/.yarn/cache/expect-npm-24.8.0-8c7640c562-1.zip/node_modules/expect/build/index.js:138:15)
    at module.exports (evalmachine.<anonymous>:19:7)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async /github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.37-bb4398f5f1-1.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:56:13
    at async executeInTempDirectory (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.37-bb4398f5f1-1.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:17:16)
    at async Object.executeRepro (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.37-bb4398f5f1-1.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:24:12)
    at async ExecCommand.execute (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.37-bb4398f5f1-1.zip/node_modules/@arcanis/sherlock/lib/commands/exec.js:25:38)
    at async ExecCommand.validateAndExecute (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-1.zip/node_modules/clipanion/lib/advanced/Command.js:161:26)
    at async Cli.run (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-1.zip/node_modules/clipanion/lib/advanced/Cli.js:74:24)
    at async Cli.runExit (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-1.zip/node_modules/clipanion/lib/advanced/Cli.js:83:28)

@arcanis
Copy link
Member

arcanis commented Jan 19, 2020

Investigation

Found the problem. ESLint requires the extends file through importFresh here:

https://github.com/eslint/eslint/blob/master/lib/cli-engine/config-array-factory.js#L201

The problem is that importFresh uses resolveFrom, which creates a whole new module (second parameter in _resolveFilename):

https://github.com/sindresorhus/resolve-from/blob/188ed7da119c788d98272852e8a71fd19195f6cf/index.js#L29-L33

The new module loses information, two in particular:

  • the file that owns the resolution that we're requiring (ie the .eslintrc.yml file).
  • the dependency tree that "owns" the resolved entry.

As a result of the second one, the PnP loader tries to regenerate it by finding the closest ancestor PnP hook (.pnp.js) for the issuer. That would usually do the trick, but since importFresh also lost the issuer then the loader fallbacks to finding the closest ancestor for the request itselfy.

Unfortunately, in the case of the global cache, the request is a file within the cache, and the closest ancestor doesn't exist (because the cache doesn't have a .pnp.js file). So the preset is loaded as if it wasn't covered by a PnP dependency tree, hence the "Cannot find module" message (PnP would throw something more detailed).

One last mystery: even if we're loading the preset through the regular Node resolver instead of the PnP resolver, why did the resolution failed? After all, as we can see in the error, we're resolving an absolute path. So it makes sense that it would fail to load its dependencies, but we can't even load it at all - what happens? The answer is that the Node resolver cheats:

https://github.com/nodejs/node/blob/v13.5.0/lib/internal/modules/cjs/loader.js#L136

In order to be faster, they use a special native and internal stat function that isn't exposed to userland code and, more importantly, doesn't support reading from Zip archives ... so when it tries to check whether the file exists, it has no idea that it needs to look inside the archive, and the Node resolution fails.

How to fix?

It's a bit difficult to say because frankly the whole require / require.resolve API is an incredible mess due to the fact that it deals directly with file paths rather than abstract tokens. This is a very bad design, and as a result it's very hard for everyone to know exactly how the API should be used in a perfectly generic way.

I'll need to think some more about this.

@zdm
Copy link
Author

zdm commented Jan 19, 2020

Please, don't forget, that it works in RC19. Compare the changes and you fill find solution.

@arcanis
Copy link
Member

arcanis commented Jan 19, 2020

Yes, rc.19 didn't support multi-tree resolution (which is required for things such as Vue CLI or Create-React-App); everything was always resolved from the .pnp.js at the root of your project.

Something I may consider would be to exclusively enable this mode from packages installed via yarn dlx. It's extremely rare in all other cases... 🤔

@zdm
Copy link
Author

zdm commented Mar 10, 2020

Something I may consider would be to exclusively enable this mode from packages installed via yarn dlx. It's extremely rare in all other cases...

How I can do this?

@zdm
Copy link
Author

zdm commented Mar 16, 2020

@arcanis
Hi, you wrote:

Something I may consider would be to exclusively enable this mode from packages installed via yarn dlx. It's extremely rare in all other cases...

Could you, please, tell me how I can do this. I want to use latest builds, but this issue is blocking upgrade for me.

@jonaskuske
Copy link
Contributor

@arcanis Do you think the error with module resolution described here might be the same thing that also causes enableGlobalCache to break esm (standard-things/esm#871) ?

@ylemkimon
Copy link
Contributor

This is also the case with Docusaurus v2: facebook/docusaurus#3324.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working reproducible This issue can be successfully reproduced
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants