microsoft/TypeScript

TypeScript has doubled in size since v2.0.0 - now 35 MB

styfle opened this issue ยท 22 comments

Search Terms: install size mb

Expected behavior:
I expected typescript to be relatively small since it has zero dependencies so there is no additional bloat from package.json or README.md files included with dependencies.

install size typescript@2.0.0 is about 17 MB, not too bad.

Actual behavior:

install size typescript@2.9.0-dev.20180411 is about 35 MB - double the size in about 2 years

I realize that there are no stated goals of install size, however it is worth considering because...how is TypeScript getting so big so fast? ๐Ÿ˜•

This might inhibit new users from coming on board when their code base might be a few kB with plain JS and adding TS would make it 35 MB.

Steps to reproduce

mkdir ts2.0
cd ts2.0
npm init -y
npm install --save-dev typescript@2.0.0
cd ..
mkdir ts2.9
cd ts2.9
npm init -y
npm install --save-dev typescript@2.9.0-dev.20180411
cd ..
du -sh ts2.0 # 17M
du -sh ts2.9 # 35M

I agree - installs should be definitely be fast! But also keep in mind that 2 years is a long time, so we've done a lot outside of what was in 2.0 (e.g. infrastructure for our emit pipeline).

But you're right, on an individual basis, tsc.js from 2.0 is about half of what we're producing now. This is exacerbated by the fact that the compiler's core code (e.g. type-checker etc.) are duplicated between outputs like tsc.js and typescript.js. So if the core compiler increased by 1.44MB, I believe we'd actually see something like a 7.2MB increase. If we used modules, we'd be able to share each file and avoid this duplication.

Just to note, otherwise, the TypeScript package's lib folder contains the following apart from .js files:

  • 4.85MB of lib.*.d.ts files
  • 0.87MB of .d.ts files relating to our API
  • 2.20MB of localized versions of error messages used by the --locale flag

@DanielRosenwasser Thanks for the quick and detailed response!

The installs are pretty fast which is why it caught me off guard.

I noticed typescript is about the same size as webpack-cli but installs much faster, likely due to the fact that there are zero dependencies (I didn't measure install times and I'm not sure if npm caches results anyway).

If we used modules, we'd be able to share each file and avoid this duplication.

By modules, you mean ES6 Modules? Something that node.js doesn't support yet?

I know that @jdalton wrote esm which might be worth including a few additional kB from the esm dependency if you can drastically decrease the output size.

I'm not sure how much collaboration there is between the TypeScript team and the Web Apps team or even if this is achievable.

I tried installing some packages and checking the resulting size of node_modules (update: totally wrong):

  • react-dom: 155 MB
  • flow-bin: 53 MB
  • @angular/cli: 153 MB
  • vue: 157 MB (704 dependencies!)

It doesn't seem like investing time to reduce our install to be even more smaller than other comparable JS tools is a good use of resources. If there's low-hanging fruit we can trim without cost, we should do that, but this isn't worth worrying about right now.

@RyanCavanaugh Those are not the numbers I got when I ran the same tests ๐Ÿ˜•

See my results below:

Oops, totally invalid results. Didn't realize NPM changed behavior and started saving to package.json by default!

I have been doing some comparisons of popular tools in similar categories and I happen to really like TypeScript so I thought I would make note of it.

You can see some of the comparisons I've done here: https://github.com/styfle/packagephobia#demo


That being said, what is the quote "If we used modules, we'd be able to share each file and avoid this duplication" mean? Is this achievable in a TS 3.0.0 or some future release?

We have a change to reorganize the library in #15780. this should allow us to remove all duplication in the lib files. that said, I expect the lib file to increase in the next release as we are working on updating it and adding comments, so that might end up being a wash.

We should be able to remove some 6 MBs by combining the two targets tsserverlibarary.js and typescriptservices.js. this a breaking change, so we will have to phase it on two releases or so (i.e. combine the contents of the two files in one, but keep both copies in one release, then remove one copy in the next release.).

We can always minify our output. we have not had a reason to do this in the past.

That being said, what is the quote "If we used modules, we'd be able to share each file and avoid this duplication" mean? Is this achievable in a TS 3.0.0 or some future release?

it is something we want to do, but no plans for the short term. that is where the majority of savings would come from. if we use modules, we should be able to cut the non-library part to 7 MBs or so.

That being said, what is the quote "If we used modules, we'd be able to share each file and avoid this duplication" mean?

For context, today we don't use modules; each file in the Typescript compiler uses namespaces in the global scope, and is concatenated at the end. That means that checker.ts gets concatenated and duplicated in in each output .js file, rather than generating a checker.js which is imported by tsc.js, tsserver.js, etc.

We can always minify our output. we have not had a reason to do this in the past.

For a Node project, I don't think this is worth it unless it'd just be about stripping out whitespace.

Thanks for all the information, I appreciate the dialog ๐Ÿ‘

I would like to point out that the latest typescript@2.9.0-insiders.20180510 has just doubled again
...now 76.8 MB! ๐Ÿ˜ฎ

The spike was introduced in typescript@2.9.0-dev.20180505 install size

Is this worrisome? At what point is TypeScript too big? ๐Ÿ˜•

No, that is definitely a bug.. we changed the publishing script, and now we are picking up way too many files that should not be there..

  • gulpfile.js
  • lib\typescript_standalone.d.ts
  • lib\diagnosticmessages.generated.json
  • lib\tsc.d.ts
  • lib\tsc.js.map
  • lib\tsserver.js.map
  • lib\tsserverlibrary.js.map
  • lib\typescriptservices.js.map
  • lib\typinginginstaller.js.map
  • lib\cancellationtoken.js.map

other files that should not be there in the first place

  • contributing.md

@weswigham can you please take a look, we need to fix this for the next release..

thanks @styfle for reporting this.

@mhegazy is the case of those files wrong in our npmignore? All we did was start to publish on 'nix.

the .d.ts files indicate a change in the build process, we should not be building tsc.d.ts in the first place.

lib\diagnosticmessages.generated.json should not be copied to the build output.

the *.map file means that debug=true was not set when the build was triggered.

looks like we are explictlly setting setDebugMode in the build.

nevermind, we set it to run the tests, and not for the publishing..

looks like the rouge files were added in #23844

typescript@2.9.1-insiders.20180521 was just published, and we are back to 35 MB.

Thanks, I confirmed install size

Also, I created #24282 to display this info in the README so it's more visible.

@mhegazy This happened again in typescript@3.0.0-dev.20180630

version install size
3.0.0-dev.2018062 install size
3.0.0-dev.20180630 install size

Update: I would have expected #24712 to catch this at build time before the new version was published. Would you like a new issue for this or should we continue discussion here?

Also happened again in typescript@3.1.0-dev.20180721

version install size
3.1.0-dev.20180717 install size
3.1.0-dev.20180721 install size

Surely this must be a bug, right?

@weswigham can u take a look.