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

yarn 2 berry: tsdx tried to access babel-jest, but it isn't declared in its dependencies; #688

Open
Tracked by #933
sgratzl opened this issue Apr 19, 2020 · 7 comments
Labels
scope: integration Related to an integration, not necessarily to core (but could influence core)

Comments

@sgratzl
Copy link

sgratzl commented Apr 19, 2020

Current Behavior

when using v0.13.2 with yarn 2 berry, I get the following error when running tsdx test

Error: tsdx tried to access babel-jest, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.

see also:

'.(js|jsx)$': require.resolve('babel-jest'), // jest's default

Expected behavior

all modules that are references using require or require.resolve have to be part of the dependencies of the package.

Suggested solution(s)

add babel-jest to the direct dependencies

Additional context

Your environment

Software Version(s)
TSDX 0.13.2
TypeScript 3.8.3
Browser n.a
npm/Yarn yarn 2 berry
Node 12.16.1
Operating System win
@agilgur5 agilgur5 added the scope: integration Related to an integration, not necessarily to core (but could influence core) label Apr 20, 2020
@agilgur5
Copy link
Collaborator

agilgur5 commented Apr 20, 2020

So babel-jest isn't a direct dependency because it's a dependency of Jest, and Jest's default config is very similar -- we want to configure JS the same and use the same babel-jest version (though realistically, I don't think the yarn.lock would change at all with the addition of a babel-jest dependency). The require.resolve is necessary as plain string throws some errors.

It's a bit weird that Berry would punish require.resolve but not plain string. Requiring that every sub-dependency specified in a config also be a direct dependency gets you the ESLint shareable config problem. Several libraries reference "optional dependencies" this way too (and babel-jest is only necessary for JS users), expecting the dependency to be installed if needed.

TSDX also doesn't have support for Berry yet -- there is #458 for that -- I'd be surprised if this were the only issue encountered while using Berry. I'm not sure all the dependencies support it either.

@ghost
Copy link

ghost commented Apr 20, 2020

For a temporary resolution, you can switch to pnp loose mode. Set pnpMode: loose in your yarnrc

@sgratzl
Copy link
Author

sgratzl commented Apr 21, 2020

so far I was able to manage it to get it work together with yarn 2 in my monorepo: https://github.com/upsetjs/upsetjs. It required some customization (like the rollup-plugin-pnp-resolve for rollup: https://github.com/upsetjs/upsetjs/blob/master/packages/model/tsdx.config.js) but doable.

@merceyz
Copy link

merceyz commented Aug 26, 2020

If you look at the dependency tree it's really just luck/hoisting that makes tsdx test work at all.

$ yarn why babel-jest -R
└─ mylib@workspace:.
   └─ tsdx@npm:0.13.3 (via npm:^0.13.3)
      └─ jest@npm:24.9.0 (via npm:^24.8.0)
         └─ jest-cli@npm:24.9.0 (via npm:^24.9.0)
            ├─ @jest/core@npm:24.9.0 (via npm:^24.9.0)
            │  ├─ @jest/reporters@npm:24.9.0 (via npm:^24.9.0)
            │  │  └─ jest-runtime@npm:24.9.0 (via npm:^24.9.0)
            │  │     └─ jest-config@npm:24.9.0 (via npm:^24.9.0)
            │  │        └─ babel-jest@npm:24.9.0 [11af2] (via npm:^24.9.0 [11af2])
            │  ├─ jest-config@npm:24.9.0 (via npm:^24.9.0)
            │  └─ jest-runtime@npm:24.9.0 (via npm:^24.9.0)
            └─ jest-config@npm:24.9.0 (via npm:^24.9.0)

we want to configure JS the same and use the same babel-jest version

@agilgur5 There is no guarantee you'll actually get the same version as jest has in its tree without declaring it, there might be some other dependency that declares babel-jest as a dependency, in which case the version that gets hoisted to the top is undefined behaviour.

TSDX also doesn't have support for Berry yet -- there is #458 for that -- I'd be surprised if this were the only issue encountered while using Berry. I'm not sure all the dependencies support it either.

From running npx tsdx create mylib lint and test is the only things that doesn't work, one of which can be fixed rather easily by declaring the dependencies you need to use.

@agilgur5
Copy link
Collaborator

agilgur5 commented Aug 27, 2020

If you look at the dependency tree it's really just luck/hoisting that makes tsdx test work at all.

Per my previous comment, Jest itself does the same for its default config. It's officially documented behavior, not luck.

From running npx tsdx create mylib lint and test is the only things that doesn't work, one of which can be fixed rather easily by declaring the dependencies you need to use.

The comment above and issue itself say that build doesn't work. Neither mentions lint. In any case, there is a good bit of investigation, work, and automated tests to do. I've never used Berry either. This issue has 0 upvotes and the other 2, so the work/benefit ratio is quite low.

You're welcome to contribute that work if you want that integration to exist faster.

@cspotcode
Copy link

In case this is helpful:

I think module.createRequire() is the correct approach when trying to load dependencies that you must assume are declared by a different package.json and not your own.

https://nodejs.org/api/module.html#module_module_createrequire_filename

@agilgur5 agilgur5 mentioned this issue Nov 10, 2020
6 tasks
@cspotcode
Copy link

What is tsdx's intended behavior when choosing a version of babel-jest?

Jest's documentation says that projects are supposed to declare their own dependency on babel-jest, suggesting that users should not depend on a version being hoisted from jest's dependency tree: https://jestjs.io/docs/en/getting-started#using-babel

I assume that tsdx intends to bundle its own copy of babel-jest to simplify end-user configuration. What is the intent if a project declares its own babel-jest dependency, with a different version than the one bundled by tsdx?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: integration Related to an integration, not necessarily to core (but could influence core)
Projects
None yet
Development

No branches or pull requests

4 participants