jestjs / jest

Delightful JavaScript Testing.
https://jestjs.io
MIT License
44.09k stars 6.44k forks source link

Make jest small #6266

Open styfle opened 6 years ago

styfle commented 6 years ago

🚀 Feature Proposal

Make jest small again (less than 30 MB)

Motivation

It appears jest is the largest when comparing other test harnesses.

jest@0.1.40 was small...it looks like jest@12.1.0 is when the size exploded. Now jest@23.0.0 is even larger.

Example

package install size
tap@12.0.1 install size
ava@0.25.0 install size
mocha@5.2.0 install size
tape@4.9.0 install size
jasmine@3.1.0 install size
jest@0.1.40 install size
jest@12.1.0 install size
jest@23.0.0 install size
jest@23.0.1 install size

Click a badge above to see a history of the install size.

Pitch

Every repo needs to install jest to run it's own tests.

One repo with 50 MB is maybe not too bad but your app is split into 200 microservices, that's 10 GB of jest!

cpojer commented 4 years ago

Let's remove node-notifier and make it an optional plugin. I don't know of anyone who uses it, and the people who do can install a separate package to hook it in. Does anyone want to work on a PR to make it its own package that will be used only when installed (and explicitly enabled)?

Note it is already an optional dependency (and at FB we blackhole it to an empty package).

cpojer commented 4 years ago

@SimenB is removing sane in https://github.com/facebook/jest/pull/10048.

SimenB commented 4 years ago

Note it is already an optional dependency (and at FB we blackhole it to an empty package).

Yeah, it should just be a matter of moving it from optionalDependencies to devDependencies and tweaking the error message to tell people to install it. We do this for weak-napi already

probil commented 4 years ago

Here is approx. files count per dependency (top 10):

$ du -a | cut -d/ -f2 | sort | uniq -c | sort -nr | head -10
1051 lodash
 528 @babel
 485 jsdom
 217 @jest
 144 resolve
 144 @types
 126 cssstyle
 100 ajv
  99 node-notifier
  86 jest-snapshot

BTW, can't jsdom be made optional or peer? It's FE only, 13Mb in node_modules, uses deprecated request@2.88.2

cpojer commented 4 years ago

@probil JSDOM will become optional in Jest 28: https://jestjs.io/blog/2020/05/05/jest-26

Right now it's the default, so Jest 27 will make the node env the default, and then 28 will stop shipping it.

Note that for the monorepo at Facebook where we develop React Native, we blackhole jest-environment-jsdom to an empty module.

probil commented 4 years ago

@cpojer Cool! Thanks for update

TrySound commented 3 years ago

27 took so much time. How long to live with bloated node_modules and deprecation warnings until 28 is out? Maybe just kill jsdom in 27? Shouldn't be a big deal to add dependency for users.

SimenB commented 3 years ago

28 will come quite quick as I wanna drop node 10 and 15 as well. 27 should be just around the corner

wopian commented 3 years ago

Jest 27 has knocked off a further ~10 MB compared to 26 🎉

package install size
jest@26.6.3 install size
jest@27.0.0 install size
TrySound commented 3 years ago

Removing jsdom in jest 28 will cut another 10 https://packagephobia.com/result?p=jsdom

RDIL commented 2 years ago

Hey all! I might be misunderstanding the exact reason, but it seems like installing Jest gets @jest/types installed too, which doesn't seem right... from my understanding, it is only for type definitions, so I don't quite know why it should be present (user-facing types live at @types/jest, right?)

styfle commented 2 years ago

Confirmed, Jest 28 reduced install size by 34%! Great job 🎉

package install size
jest@27.5.1 install size
jest@28.0.0 install size
SimenB commented 2 years ago

@styfle awesome! Looking at the OP, this is the smallest Jest has been in "modern" times (i.e. when FB/Meta took over the jest package name - before that jest package wasn't this. 9d2b2bcf5e0705c64d5eba631c225426c09965ef). Would you say the issue is fixed?

FWIW, in the future we'll stop shipping babel-jest by default as well. Not sure how much smaller that'd make us as we use babel in snapshot tests, but still. Beyond that, I don't think there's much space saving to be had?

styfle commented 2 years ago

@SimenB Looks like babel-jest is nearly 11MB install size

If you remove that dependency then I think we can close this issue.

For comparison, here are the current competitors:

package install size
jest@28.0.2 install size
mocha@9.2.2 install size
ava@4.2.0 install size
tape@5.5.3 install size
wtgtybhertgeghgtwtg commented 2 years ago

@SimenB Looks like babel-jest is nearly 11MB install size

Most of that is from @jest/transform at 10.6MB, which comes in anyway (e.g. from @jest/core)

But, most of that seems to come from babel-plugin-istanbul at 7.30MB.

Drilling down, it's mostly @babel/core at 6.68MB.

milesj commented 2 years ago

I wonder if istanbul can be dropped entirely, since v8 code coveraga was released in nodejs v15.1.0, v14.18.0, v12.22.0.

cpojer commented 2 years ago

I'm in favor of dropping Istanbul.

SimenB commented 2 years ago

I'd think it makes sense for that to be part of dropping out of the box Babel support as we'd still pull in @babel/core from babel-jest.

We talked about babel-jest and its use cases in https://jestjs.io/blog/2020/05/05/jest-26, and we'd have to break all of them (out of the box) to get rid of @babel/core. Specifically

Once V8 coverage and native ESM support stabilizes in Jest, we will also be able remove babel-jest as a default but we will keep maintaining it.

I don't think anything has really changed here? V8 coverage is probably more viable, but ESM is still just as blocked as ever (although the mocks is mostly me having zero interest in working on it before ESM is more stable - others are free to jump in!)

That said, we can probably flip default coverage provider from babel to v8 and require the user to provide babel-plugin-istanbul. We'd still pull in @babel/core, so wouldn't really change anything, tho.

EDIT: Oh, and @jest/reporters pulls in istanbul-lib-instrument which is the dep that requires @babel/core, so that'd need a refactor as well. We could also of course drop support for babel coverage outside of babel-jest. It's used in the reporter to get coverage of uncovered files - could just as well be v8 coverage (we mark the entire file as uncovered - however that means e.g. type definitions are counted weirdly)

EDIT2: And as mentioned we use babel in inline snapshots, so that would need a refactor as well to yell at people that use inline snapshots to install babel

RDIL commented 2 years ago

@SimenB is making snapshots, say, an optional module (that manually needs to be installed) a possibility?

SimenB commented 2 years ago

we don't need babel for regular snapshots, so that seems overkill. Can do something for inline snapshots, tho.

That said, I personally do not care about the install size, so if anything is to happen here, somebody else has to do the work 🙂

yifanwww commented 1 year ago

Is there any reason that we need some @types/* deps listed in dependencies instead of devDependencies?

for example:

mixtur commented 7 months ago

Who needs babel when there is esbuild. It won't make installation size much smaller, but at least dependency graph is less crazy that way.