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

[experimental] yarn pnp #7726

Closed
wants to merge 1 commit into from
Closed

[experimental] yarn pnp #7726

wants to merge 1 commit into from

Conversation

jeysal
Copy link
Contributor

@jeysal jeysal commented Jan 27, 2019

Edit: Just to be clear, I did not intend for this to be merged in this or some similar form 😄 this PR is just to share what I've done and what the problems are so we can possibly get back to this when there are good solutions for them :)

Summary

Since it seems nobody has attempted this before, I tried for about an hour to make the Jest repo Yarn pnp-compatible. My impression is that it would be possible (with a significant amount of additional effort put into it), but might not be desirable until pnp has matured further.

What works:

  • yarn, including post install
  • ~90% of unit/e2e tests (although I achieved this in a quick and dirty way)
  • yarn lint, mostly

What doesn't:

  • yarn flow, this fix did not help either
  • ESLint has 13 no-unresolved errors because of dependencies that are correctly declared in the corresponding package.json, but not the root. I consider this to be quite a deal breaker, because I really do not want a dependency on react in the root
  • examples/react-native because of node_modules/something all over the Jest preset file, although @SimenB may have fixed that in fix: use require.resolve in jest-preset facebook/react-native#22972

I did not check any of the other scripts.

cc @arcanis in case you're interested, although probably none of this is new to you 😅

Test plan

@jeysal
Copy link
Contributor Author

jeysal commented Jan 27, 2019

CI looks a bit worse than on my machine, it shouldn't fail that early 😄

@@ -26,6 +27,7 @@
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-react": "^7.1.0",
"eslint-plugin-relay": "~0.0.19",
"estraverse": "^4.2.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@@ -3,6 +3,7 @@
"devDependencies": {
"@babel/core": "^7.1.0",
"@babel/plugin-transform-strict-mode": "^7.0.0",
"@babel/plugin-transform-modules-commonjs": "^7.1.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should go on master

"prettier": "^1.16.1",
"prettylint": "^1.0.0",
"progress": "^2.0.0",
"promise": "^8.0.2",
"readable-stream": "^3.0.3",
"realpath-native": "^1.0.0",
"request": "^2.88.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's for fetchSupporters, it should go in website/package.json

"prettier": "^1.16.1",
"prettylint": "^1.0.0",
"progress": "^2.0.0",
"promise": "^8.0.2",
"readable-stream": "^3.0.3",
"realpath-native": "^1.0.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the integration test? if so, should land on master

setupFilesAfterEnv: ['<rootDir>/testSetupFile.js'],
snapshotSerializers: [
'<rootDir>/packages/pretty-format/build/plugins/ConvertAnsi.js',
'jest-snapshot-serializer-raw',
require.resolve('jest-snapshot-serializer-raw'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can land this on master

const result = spawnSync(
JEST_PATH,
// TODO this is ugly and a problem for e2e tests related to config/resolution
['--resolver', require.resolve('jest-pnp-resolver'), ...(args || [])],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah... no. Not sure how to properly deal with it, though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear, I did not intend for this to be merged in this or some similar form 😄 this PR is just to share what I've done and what the problems are so we can possibly get back to this when there are good solutions for them :)

@jeysal
Copy link
Contributor Author

jeysal commented Jan 27, 2019

@SimenB I'll make a PR for the changes you suggested to integrate into master - I guess revealing possible improvements like these would be one of the main benefits of pnp if we could use it at some point

@jeysal
Copy link
Contributor Author

jeysal commented Jan 27, 2019

Regarding the other changes such as request for fetchSupporters, the reason why pnp would force us to put so many dependencies into the root is essentially this yarnpkg/yarn#6514 (comment).
This is the primary reason why I do not consider using pnp viable at this point.

@arcanis
Copy link
Contributor

arcanis commented Jan 27, 2019

Really nice! I think it could be simplified if there was a way to remove the need for require.resolve on the user side. I have to check, but I wanted to look at jest-config/normalize - maybe it would simply be a matter of using require.resolve(config.someSettings, {paths:[path.dirname(configPath)]}), what do you think?

@arcanis
Copy link
Contributor

arcanis commented Jan 27, 2019

Regarding the packages required at the root, can you list why they are needed? It's usually only a way to workaround a legit issue in a package, and maybe the right fix would simply be to propagate the fixes upstream.

@jeysal
Copy link
Contributor Author

jeysal commented Jan 27, 2019

require.resolve(config.someSettings, {paths:[path.dirname(configPath)]})

I believe that should work. preset is a weird case though:
"A preset that is used as a base for Jest's configuration. A preset should point to an npm module that has a jest-preset.json or jest-preset.js file at the root."
But that will probably get cleaned up with the configuration overhaul in Jest 25

Regarding the packages required at the root, can you list why they are needed

I'll compile a non-exhaustive list, there would probably be a lot more cases of this to show up if we want to make all scripts work :)

@jeysal
Copy link
Contributor Author

jeysal commented Jan 27, 2019

Here's a few:

If request is put into website/package.json devDependencies instead of the root, yarn postinstall prints:

error /Users/timseckinger/proj/jest/.pnp/unplugged/npm-jest-website-0.0.0/node_modules/jest-website: Command failed.
Exit code: 1
Command: node fetchSupporters.js
Arguments:
Directory: /Users/timseckinger/proj/jest/.pnp/unplugged/npm-jest-website-0.0.0/node_modules/jest-website
Output:
/Users/timseckinger/proj/jest/.pnp.js:27718
    throw firstError;
    ^

Error: You cannot require a package ("request") that is not declared in your dependencies (via "/Users/timseckinger/proj/jest/website/fetchSupporters.js")    

Not sure why this is happening.


If estraverse is omitted, yarn lint fails everything with:

  10:40  error  Parse errors in imported module 'types/Config':
Package "eslint@5.12.0" (via "/Users/timseckinger/Library/Caches/Yarn/v4/npm-eslint-5.12.0-fab3b908f60c52671fb14e996a450b96c743c859/node_modules/eslint/lib/api.js")
is trying to require the package "estraverse" (via "estraverse") without it being listed in its dependencies
(@babel/code-frame, ajv, chalk, cross-spawn, debug, doctrine, eslint-scope, eslint-utils, eslint-visitor-keys, espree, esquery, esutils, file-entry-cache, functional-red-black-tree, glob, globals, ignore, import-fresh, imurmurhash, inquirer, js-yaml, json-stable-stringify-without-jsonify, levn, lodash, minimatch, mkdirp, natural-compare, optionator, path-is-inside, pluralize, progress, regexpp, semver, strip-ansi, strip-json-comments, table, text-table, eslint)
(undefined:undefined)  import/namespace

This might be an error on ESLint side and thus actionable?


If realpath-native is in e2e/package.json dependencies instead of the root, yarn jest hasteMapSize fails with:

  ● Test suite failed to run

    Cannot find module 'realpath-native' from 'hasteMapSize.test.js'

      12 | import HasteMap from 'jest-haste-map';
      13 | import {cleanup, writeFiles} from '../Utils';
    > 14 | import {sync as realpath} from 'realpath-native';
         | ^
      15 | 
      16 | const DIR = path.resolve(realpath(os.tmpdir()), 'haste_map_size');
      17 | 

      at Resolver.resolveModule (packages/jest-resolve/build/index.js:202:17)
      at Object.<anonymous> (e2e/__tests__/hasteMapSize.test.js:14:1)

Not sure why the custom Jest pnp resolver doesn't manage to resolve this

@SimenB
Copy link
Member

SimenB commented Jan 27, 2019

Not sure why this is happening.

Seems like an pnp bug, @arcanis?

This might be an error on ESLint side and thus actionable?

Yeah, send them a PR

Not sure why the custom Jest pnp resolver doesn't manage to resolve this

Yeah, weird. Seems like something it should handle

@jeysal
Copy link
Contributor Author

jeysal commented Jan 27, 2019

This might be an error on ESLint side and thus actionable?

Actually, looks like this is babel/babel-eslint#680, which was fixed in babel-eslint@10

@SimenB
Copy link
Member

SimenB commented Jan 27, 2019

Needs facebook/fbjs#330 to avoid the peer dep warning, then

@jeysal
Copy link
Contributor Author

jeysal commented Feb 13, 2019

Closing this for now (was mostly meant to document the issues encountered while experimenting anyway), will attempt this again once pnp has matured enough to support complex setups / has become more of a standard way of doing dependencies.

@arcanis
Copy link
Contributor

arcanis commented Mar 20, 2019

Current notes from today's session:

  • Workspaces are unplugged when they have a postinstall script (Yarn bug)
    Unblock: remove the postinstall

  • TSC doesn't support PnP
    Unblock: disable the buildTs step

  • Running yarn add in a subdirectory corrupts the PnP file (Yarn bug)
    Unblock: run yarn install after the add

  • The Jest tests are using PnP when running within the PnP process
    Unblock: should be reworked to disable the PnP native support from within the tests

  • The prettierPath doesn't go through require.resolve unless user-specified (not 100% sure)
    Unblock: set "prettierPath: 'prettier'" in jest.config.js

image

@jeysal
Copy link
Contributor Author

jeysal commented Mar 20, 2019

https://github.com/jeysal/jest/tree/yarn-pnp has the fixes and workarounds, I'll land some of the fixes in Jest master as well

@SimenB
Copy link
Member

SimenB commented Jan 28, 2020

I opened #9476 using berry, if you wanna poke at it again 🙂

@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants