-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Optimize how TypeScript-authored packages are built #47002
Conversation
Here is how your PR affects size of JS and CSS bundles shipped to the user's browser: App Entrypoints (~47 bytes removed 📉 [gzipped])
Common code that is always downloaded and parsed every time the app is loaded, no matter which route is used. Legend What is parsed and gzip size?Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory. Generated by performance advisor bot at iscalypsofastyet.com. |
For the packages that have transitioned from the We should use a tsconfig that is intended for generating code and not just types. I believe the Notably, the target changes which results in different output:
// Input
const a = { a: 'a' }, b = { b: 'b' }, c = { c: 'c' }
const abc = { ...a, ...b, ...c }
// target: es2018
const a = { a: 'a' }, b = { b: 'b' }, c = { c: 'c' };
const abc = { ...a, ...b, ...c };
// target: es5
import { __assign } from "tslib";
var a = { a: 'a' }, b = { b: 'b' }, c = { c: 'c' };
var abc = __assign(__assign(__assign({}, a), b), c); That's not expected at the moment, our published packages are intended to be published with ES5 syntax (with versions for esmodules or commonjs modules). For Calypso as a consumer, if we transpile these after the fact then we can compile to modern syntax + type definitions which will likely give us the best output, but that would need another configuration on top of the existing es5 targets. We'll also need to add ☝️ This bit is important and should be resolved ImprovementsThe TypeScript setup in Calypso isn't ideal. I don't have a lot of time or focus to dedicate to it right now but I will help with reviews and guidance if someone would like to take on the task. Better config sharingCommon tsconfig should be centralized and extended. Don't repeat and allow for confusing examples that may be copied from more or less ideal sources. tsc-compiled and type-only configurations would likely be lifted to top-level and extended. Smarter buildingThis PR touches on the redundancy of cjs builds for Calypso. It's an improvement, but the following suggests further improvement. For Calypso where cjs is redundant, we should make Calypso client a composite typescript project. This is achieved by adding an of the tsc-compiled packages it requires, e.g.: // client/tsconfig.build.json
{
// Don't actually compile anything from Calypso
"files": [],
// Calypso requires all of these packages to be built
"references": [
{ "path": "../packages/data-stores" },
{ "path": "../packages/search" },
// … add all the tsc-built monorepo dependencies
]
} All of the |
@sirreal I improved the transpilation config in 46cb58d I used the
I believe this is blocked by the conflict over For JS packages consumed only by webpack or Node.js, not by
I would be even more radical here and say that the cjs build is redundant. 🙂 I don't think there's even a single consumer that would use the published CJS build. It's all ESM modules consumed by webpack. Ideally, we would publish untranspiled sources (ES2020 + JSX, or TypeScript) and let the consumer do the transpilations they need. I believe all consumers are already easily configured for that, we'll avoid complexity related to the builds, and the end users will get bundles optimized for their platform without unneccessary ES5. |
👍 I scanned the configs and they look good.
That was likely because the
If we're expecting consumers to polyfill anyways, should it just be
👍
🤔 Let's back up and forget references and composite projects for a moment. The Calypso webpack build is already configured to consume TypeScript source files. None of the Calypso client is actually built by
I haven't thought much about this and don't feel strongly either way. I'd say it's material we can leave for another PR 🙂 |
… transpile scripts
…ESM in prepare script
…ild only ESM in prepare script
46cb58d
to
cb36622
Compare
Good point, I changed the lib to
That's true. Where And it was the That fails the But I admit I'm already pretty confused here and what I write can be wrong. I'll need to repeat the experiments I did 4 months ago to get new results and to refresh my memory 🙂 |
We removed These checks and editor integrations are where project references and the composite project would be beneficial. They allow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested the instructions with the search and language-picker packages and this works.
We've discussed some future improvements that would be good avenues to continue this work, but this is a good incremental step.
Thanks!
|
||
## 6.4.0 | ||
|
||
- Removed the exceptions for the `import/no-extraneous-dependencies` eslint rule for '*.md.jsx' and '*.md.js' files | ||
- Removed the exceptions for the `import/no-extraneous-dependencies` eslint rule for '_.md.jsx' and '_.md.js' files |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this was autofixed by prettier wrong, those should be *.md.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, fixing in #47179.
This PR solves two problems:
I noticed that the Search and Language Picker packages are built with a combination of TypeScript Compiler and Babel: the types are generated with
tsc
, but the JS files are generated by Babel (by virtue of thetranspile
script fromcalypso-build
). That looks inefficient: why not build both withtsc
, in one step? Follows up to a discussion with @saramarcondes in Extract the search component into@automattic/search
#46424 (comment)To build Calypso The App, we only need the files in
dist/esm
. Building thedist/cjs
folder is needed only when publishing a package to NPM and the time and CPU to build it is wasted in all other cases. This PR follows the lead in Do not transpile JS packages twice #44824 and builds only thedist/esm
folder in theprepare
step.dist/cjs
is done only in theprepack
step, during NPM publishing.To produce only the
dist/esm
ordist/cjs
folders, I had to patch thetranspile
andcopy-assets
scripts incalypso-build
. They now accept--esm
and--cjs
options to override the default that processes both module types.Booting up the TypeScript compiler and compiling a handful of files takes ~3.5s on my machine, which is a lot. These changes should speed up the
build-packages
step significantly.If this PR goes through, there are still plenty of other packages that should be optimized the same way. For example, the
wpcom.js
package'sprepare
script builds CJS, ESM and also a webpack library bundle intended to be loaded as<script>
tag. Only the ESM build is needed locally.How to test:
Verify that
prepare
-ing the@automattic/search
and@automattic/language-picker
produces a correctdist/esm
folder with everything that should be there (types, compiled JS files, copied SCSS files) and that thedist/cjs
folder is created onlyon
yarn run prepack
.