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

chore: switch to using JavaScript Modules (ESM) #5233

Merged
merged 2 commits into from
Nov 6, 2023
Merged

chore: switch to using JavaScript Modules (ESM) #5233

merged 2 commits into from
Nov 6, 2023

Conversation

TimBeyer
Copy link
Contributor

@TimBeyer TimBeyer commented Oct 11, 2023

What this PR does / why we need it:

Switches to ESM.
This had many different effects that derived from it, making this PR so massive.

Changes

Modules
The first stage was to rewrite all the imports to use .js endings everywhere.
Then we needed to replace and bump a bunch of dependencies to their ESM version.

Bundling
Following that we tried to use rollup to bundle everything back into CommonJS so that we can use it in pkg since pkg does not support ESM.
This was unsuccessful, and after trying several different single application solutions, we decided we will have to write our own.

Single Executable Binary
We now use a custom Rust binary which bundles a zipped version of NodeJS, the native extensions and the bundled code.
We bundle the code for tree-shaking and size reduction, but also because otherwise we had issues with how we ensure that native modules are loaded correctly and with resolving the imports correctly cross-platform.
Then on first run, the binary extracts those files to the filesystem and runs node from there.
There are checksum files that we bundle together with the archives and that we store on disk to see if we need to re-extract or not.
This also gives us a huge performance boost in some cases - especially when lots of filesystem reads are required - since pkg was patching and proxying those methods and making things slow.

Kubernetes client
We also had to update the Kubernetes library to the 1.0.0-rc3, with a patch from a fork that contains the changes for kubernetes-client/javascript#1341
That is because the library was using request-promise behind the scenes, which started showing up with unhandled rejection warnings and errors about req not being defined in some cases.
That library update required us to change almost every k8s call since the interface now uses objects instead of positional arguments, which makes things much nicer to read and use. We also had to introduce a workaround for using custom certificates together with proxies, something that was previously globally monkey-patched by global-agent.

request-promise
We no longer depend on request-promise and fully removed the dependency.

Which issue(s) this PR fixes:

Fixes #3841
Fixes #4898

Special notes for your reviewer:

@stefreak stefreak force-pushed the chore/esm branch 2 times, most recently from 848b5b0 to a5476e6 Compare October 16, 2023 08:29
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y

# To be able to run cargo
source "$HOME/.cargo/env"
Copy link
Member

Choose a reason for hiding this comment

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

Optional: it's likely enough to source this once somewhere.

cli/package.json Outdated Show resolved Hide resolved
"source-map-support": "^0.5.21",
"tar": "^6.2.0",
"undici": "^5.26.5",
"unzipper": "^0.10.14"
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 get rid of unzipper entirely by saving the whole nodejs archive to disk, and then extracting

support/debian.Dockerfile Outdated Show resolved Hide resolved
support/alpine.Dockerfile Outdated Show resolved Hide resolved
cli/bin/garden.js Outdated Show resolved Hide resolved
@stefreak stefreak force-pushed the chore/esm branch 4 times, most recently from 6d32cb9 to a44fe47 Compare November 3, 2023 15:33
This had many different effects that derived from it, making this PR so massive.

**Modules**:
The first stage was to rewrite all the imports to use .js endings everywhere.
Then we needed to replace and bump a bunch of dependencies to their ESM version.

**Bundling**:
Following that we tried to use rollup to bundle everything back into CommonJS so that we can use it in pkg since pkg does not support ESM.
This was unsuccessful, and after trying several different single application solutions, we decided we will have to write our own.

**Single Executable Binary**:
We now use a custom Rust binary which bundles a zipped version of NodeJS, the native extensions and the bundled code.
We bundle the code for tree-shaking and size reduction, but also because otherwise we had issues with how we ensure that native modules are loaded correctly and with resolving the imports correctly cross-platform.
Then on first run, the binary extracts those files to the filesystem and runs node from there.
There are checksum files that we bundle together with the archives and that we store on disk to see if we need to re-extract or not.
This also gives us a huge performance boost in some cases - especially when lots of filesystem reads are required - since pkg was patching and proxying those methods and making things slow.

**Kubernetes client**:
We also had to update the Kubernetes library to the 1.0.0-rc3, with a patch from a fork that contains the changes for kubernetes-client/javascript#1341
That is because the library was using request-promise behind the scenes, which started showing up with unhandled rejection warnings and errors about req not being defined in some cases.
That library update required us to change almost every k8s call since the interface now uses objects instead of positional arguments, which makes things much nicer to read and use. We also had to introduce a workaround for using custom certificates together with proxies, something that was previously globally monkey-patched by global-agent.

**request-promise**:
We no longer depend on request-promise and fully removed the dependency.

Fixes #3841
Fixes #4898
@stefreak stefreak changed the title chore: ESM chore: switch to using JavaScript Modules (ESM) Nov 6, 2023
@stefreak stefreak marked this pull request as ready for review November 6, 2023 12:02
@stefreak stefreak enabled auto-merge November 6, 2023 13:42
@stefreak stefreak added this pull request to the merge queue Nov 6, 2023
Merged via the queue into main with commit 0f535dd Nov 6, 2023
3 checks passed
@stefreak stefreak deleted the chore/esm branch November 6, 2023 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants