diff --git a/.github/workflows/build-and-tests.yml b/.github/workflows/build-and-tests.yml
index 40e49e88d..c5bbc0f36 100644
--- a/.github/workflows/build-and-tests.yml
+++ b/.github/workflows/build-and-tests.yml
@@ -104,15 +104,13 @@ jobs:
target: x86_64-apple-darwin
build: >-
set -e &&
- npm run build:napi -- --release &&
- strip -x *.node
+ npm run build:napi -- --release
- host: macos-latest
target: aarch64-apple-darwin
build: >-
set -e &&
rustup target add aarch64-apple-darwin &&
- npm run build:napi -- --release --target aarch64-apple-darwin &&
- strip -x *.node
+ npm run build:napi -- --release --target aarch64-apple-darwin
# Linux
- host: ubuntu-latest
@@ -121,14 +119,13 @@ jobs:
build: >-
set -e &&
rustup target add x86_64-unknown-linux-gnu &&
- npm run build:napi -- --release --target x86_64-unknown-linux-gnu &&
- strip *.node
+ npm run build:napi -- --release --target x86_64-unknown-linux-gnu
- host: ubuntu-latest
target: x86_64-unknown-linux-musl
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
build: >-
set -e &&
- npm run build:napi -- --release && strip *.node
+ npm run build:napi -- --release
- host: ubuntu-latest
target: armv7-unknown-linux-gnueabihf
zig: true
@@ -137,8 +134,13 @@ jobs:
sudo apt-get install gcc-arm-linux-gnueabihf -y
build: >-
set -e &&
- npm run build:napi -- --release --target armv7-unknown-linux-gnueabihf &&
- arm-linux-gnueabihf-strip *.node
+ npm run build:napi -- --release --target armv7-unknown-linux-gnueabihf
+ - host: ubuntu-latest
+ target: armv7-unknown-linux-musleabihf
+ zig: true
+ build: >-
+ set -e &&
+ npm run build:napi -- --release --target armv7-unknown-linux-musleabihf
- host: ubuntu-latest
target: aarch64-unknown-linux-gnu
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
@@ -147,8 +149,7 @@ jobs:
export JEMALLOC_SYS_WITH_LG_PAGE=16 &&
rustup default nightly-2023-10-05 &&
rustup target add aarch64-unknown-linux-gnu &&
- npm run build:napi -- --release --target aarch64-unknown-linux-gnu &&
- aarch64-unknown-linux-gnu-strip *.node
+ npm run build:napi -- --release --target aarch64-unknown-linux-gnu
- host: ubuntu-latest
target: aarch64-unknown-linux-musl
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
@@ -157,20 +158,17 @@ jobs:
export JEMALLOC_SYS_WITH_LG_PAGE=16 &&
rustup default nightly-2023-10-05 &&
rustup target add aarch64-unknown-linux-musl &&
- RUSTFLAGS='-C target-feature=-crt-static -C linker=aarch64-linux-musl-gcc' npm run build:napi -- --release --target aarch64-unknown-linux-musl &&
- /aarch64-linux-musl-cross/bin/aarch64-linux-musl-strip *.node
+ RUSTFLAGS='-C target-feature=-crt-static -C linker=aarch64-linux-musl-gcc' npm run build:napi -- --release --target aarch64-unknown-linux-musl
- host: ubuntu-latest
target: armv7-linux-androideabi
build: >-
set -e &&
- npm run build:napi -- --release --target armv7-linux-androideabi &&
- ${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip *.node
+ npm run build:napi -- --release --target armv7-linux-androideabi
- host: ubuntu-latest
target: aarch64-linux-android
build: >-
set -e &&
- npm run build:napi -- --release --target aarch64-linux-android &&
- ${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip *.node
+ npm run build:napi -- --release --target aarch64-linux-android
- host: ubuntu-latest
target: riscv64gc-unknown-linux-gnu
setup: |
@@ -179,8 +177,7 @@ jobs:
build: >-
set -e &&
rustup target add riscv64gc-unknown-linux-gnu &&
- npm run build:napi -- --release --target riscv64gc-unknown-linux-gnu &&
- riscv64-linux-gnu-strip *.node
+ npm run build:napi -- --release --target riscv64gc-unknown-linux-gnu
- host: ubuntu-latest
target: powerpc64le-unknown-linux-gnu
setup: |
@@ -189,8 +186,7 @@ jobs:
build: >-
set -e &&
export CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_LINKER=powerpc64le-linux-gnu-gcc && rustup target add powerpc64le-unknown-linux-gnu &&
- npm run build:napi -- --release --target powerpc64le-unknown-linux-gnu &&
- powerpc64le-linux-gnu-strip *.node
+ npm run build:napi -- --release --target powerpc64le-unknown-linux-gnu
- host: ubuntu-latest
target: s390x-unknown-linux-gnu
setup: |
@@ -200,8 +196,7 @@ jobs:
set -e &&
export CARGO_TARGET_S390X_UNKNOWN_LINUX_GNU_LINKER=s390x-linux-gnu-gcc &&
rustup target add s390x-unknown-linux-gnu &&
- npm run build:napi -- --release --target s390x-unknown-linux-gnu &&
- s390x-linux-gnu-strip *.node
+ npm run build:napi -- --release --target s390x-unknown-linux-gnu
name: Build ${{ matrix.settings.name || matrix.settings.target }}
runs-on: ${{ matrix.settings.host }}
timeout-minutes: 30
@@ -273,6 +268,100 @@ jobs:
if-no-files-found: error
if: ${{ !matrix.settings.is-wasm-build }}
+ # smoke test for some architectures that do not receive the full test suite
+ smoke-test:
+ permissions:
+ packages: write # for caching container images
+ name: Smoke Test ${{ matrix.settings.target }}
+ needs:
+ - build
+ strategy:
+ fail-fast: false
+ matrix:
+ settings:
+ - arch: aarch64
+ distro: ubuntu_latest
+ target: aarch64-unknown-linux-gnu
+ - arch: aarch64
+ distro: alpine_latest
+ target: aarch64-unknown-linux-musl
+ - arch: armv7
+ distro: ubuntu_latest
+ target: armv7-unknown-linux-gnueabihf
+# There is a bug that hangs the build when running npm
+# - arch: armv7
+# distro: alpine_latest
+# target: armv7-unknown-linux-musleabihf
+ - arch: ppc64le
+ distro: ubuntu_latest
+ target: powerpc64le-unknown-linux-gnu
+ use-nvm: true
+ - arch: s390x
+ distro: ubuntu_latest
+ target: s390x-unknown-linux-gnu
+ use-nvm: true
+# I could not find a way to install Node without compiling from source
+# - arch: riscv64
+# distro: ubuntu_latest
+# target: riscv64gc-unknown-linux-gnu
+ runs-on: ubuntu-latest
+ timeout-minutes: 120
+ steps:
+ - name: Checkout Commit
+ uses: actions/checkout@v4
+ - name: Cache Node Modules
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: node_modules
+ key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
+ - name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
+ run: npm ci --ignore-scripts
+ - name: Build JS
+ run: npm run build:cjs
+ - name: Download napi artifacts
+ uses: actions/download-artifact@v4
+ with:
+ name: bindings-${{ matrix.settings.target }}
+ path: dist/
+ - name: Run Smoke Test
+ uses: uraimo/run-on-arch-action@v2
+ with:
+ arch: ${{ matrix.settings.arch }}
+ distro: ${{ matrix.settings.distro }}
+ githubToken: ${{ github.token }}
+ install: |
+ case "${{ matrix.settings.distro }}" in
+ ubuntu*)
+ apt-get update -y
+ apt-get install -y curl git
+ if [[ -z "${{ matrix.settings.use-nvm }}" ]]; then
+ curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
+ apt-get install -y nodejs
+ fi
+ ;;
+ alpine*)
+ apk add nodejs npm git
+ ;;
+ esac
+ run: |
+ set -e
+ if [[ -n "${{ matrix.settings.use-nvm }}" ]]; then
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
+ source ~/.nvm/nvm.sh
+ nvm install --lts
+ fi
+ echo "Node: $(node -v)"
+ echo "npm: $(npm -v)"
+ git config --global --add safe.directory /home/runner/work/rollup/rollup
+ chmod +x dist/bin/rollup
+ dist/bin/rollup --version | grep -E 'rollup v[0-9]+\.[0-9]+\.[0-9]+'
+ mv dist dist-build
+ node dist-build/bin/rollup --config rollup.config.ts --configPlugin typescript --configTest --forceExit
+ cp dist-build/rollup.*.node dist/
+ dist/bin/rollup --version | grep -E 'rollup v[0-9]+\.[0-9]+\.[0-9]+'
+
test:
name: Test${{ matrix.additionalName || '' }} Node ${{ matrix.node }} (${{ matrix.settings.target }})
needs:
@@ -352,8 +441,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
needs:
- - test
- lint
+ - test
+ - smoke-test
# This needs to be adapted for Rollup 5
if: startsWith(github.ref_name, 'v4')
steps:
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
new file mode 100644
index 000000000..a17953d7f
--- /dev/null
+++ b/ARCHITECTURE.md
@@ -0,0 +1,130 @@
+# High-level architecture
+
+## Rollup packages
+
+- The [`rollup`](https://www.npmjs.com/package/rollup) npm package contains both Rollup's Node.js JavaScript interface and the command-line-interface (CLI).
+- There is a separate browser build available as [`@rollup/browser`](https://www.npmjs.com/package/@rollup/browser). It exposes the same JavaScript interface as the Node.js build but does not include the CLI and also requires writing a plugin to encapsulate file reading. Instead of native code dependencies, this build has a bundled WASM artifact included that can be loaded in the browser. This is what the [Rollup REPL](https://rollupjs.org/repl) uses.
+- For every supported platform-architecture combination, there is a separate pacakge containing the native code. These are not listed in the committed `package.json` file but are added dynamically during publishing as `optionalDependencies`. The `README.md` and `package.json` files for those dependencies can be found in the [`npm`](npm) folder. The corresponding binaries are built and published from [GitHub Actions](.github/workflows/build-and-tests.yml) whenever a new release version tag is pushed. The actual loading of the native code is handled by [`native.js`](native.js) which is copied into the output folder during build. So to add a new platform-architecture combination, you need to
+ - add a new package in the `npm` folder
+ - update the `native.js` file
+ - add the corresponding triple to the [`package.json`](package.json) file as napi-rs depends on this
+ - extend the [GitHub Actions workflow](.github/workflows/build-and-tests.yml) to build the new package
+- There is also a separate `@rollup/wasm-node` package that is identical to the `rollup` package in that it contains the Node.js JavaScript interface and the CLI but does not contain any native code. Instead, it includes a WebAssembly artifact that runs in Node.js. This package and the corresponding artifact only built on GitHub Actions and published via the [`publish-wasm-node-package.js`](scripts/publish-wasm-node-package.js) script.
+
+## Building Rollup
+
+### JavaScript interface and CLI
+
+- The [`rollup.config.ts`](rollup.config.ts) orchestrates building the ESM and CommonJS versions of the JavaScript interface, the CLI, which is an extension of and shares code with the CommonJS build, and the browser build.
+ - `npm run build:js` builds all JavaScript artifacts. However, as it includes the browser build, it requires the browser Web Assembly artifact to be built first, otherwise the build will fail.
+- The JavaScript interface contains the core logic.
+ - It is mostly environment agnostic.
+ - To achieve full environment independence in the browser build, [`replace-browser-modules.ts`](build-plugins/replace-browser-modules.ts) replaces some modules with modified browser versions that reside in the [`browser` folder](browser).
+ - The most prominent difference is the fact that there is no fallback logic for the `resolveId` and `load` plugin hooks. If there is no plugin implementing those hooks for a file, the browser build will fail.
+ - The entry point for the Node.js build is [`node-entry.ts`](src/node-entry.ts) while the browser build uses [`browser-entry.ts`](src/browser-entry.ts). Those are mostly identical except that the browser build does not expose the watch mode interface.
+- The CLI is a wrapper around the JavaScript interface.
+ - It resides in the [`cli` folder](cli) with the entry point [cli.ts](cli/cli.ts).
+ - The logic to read configuration files resides in [locaConfigFile.ts](cli/run/loadConfigFile.ts) and is exposed as a separate export via `import { loadConfigFile } from "rollup/loadConfigFile"`.
+ - Only the CLI is able to handle arrays of configurations. Those are handled sequentially in [`run/index.ts`](cli/run/index.ts).
+ - The CLI handles several CLI-only options that are specific to the Node.js environment like setting environment variables or handling std-in, see [Command line flags](docs/command-line-interface/index.md#command-line-flags).
+
+### Native code and Web Assembly
+
+The `rollup` package relies on optional dependencies to provide platform-specific native code. These are not listed in the committed `package.json` file but are added dynamically during publishing. This logic is handled by [`napi-rs`](https://napi.rs) via `npm run prepublish:napi` from [`scripts/prepublish.js`](scripts/prepublish.js).
+
+As native modules do not work for the browser build, we use [`wasmpack`](https://rustwasm.github.io/docs/wasm-pack/) to build a WebAssembly artefact. This is triggered from `npm run build` via `npm run build:wasm`. There is also a separate Node wasm build that is again triggered from GitHub actions via `npm run build:wasm:node`.
+
+From JavaScript, native code is imported by importing [`native.js`](native.js). This module, or its WebAssembly version [`native.wasm.js`](native.wasm.js), is [copied](build-plugins/emit-native-entry.ts) as `native.js` into the output folder during build (via [`publish-wasm-node-package.js`](scripts/publish-wasm-node-package.js) for WebAssembly). Imports of this module are [declared external](build-plugins/external-native-import.ts).
+
+The Rust entrypoints are [`bindings_napi/src/lib.rs`](rust/bindings_napi/src/lib.rs) for the native modules and [`bindings_wasm/src/lib.rs`](rust/bindings_wasm/src/lib.rs) for WebAssembly.
+
+## The build and generate phases
+
+Building an output has two phases
+
+- The "build" phase builds a module graph form the input files and decides, which code should be included in the output
+ - It is triggered by calling the `rollup(inputOptions)` function exported by the JavaScript interface
+ - It returns a "bundle" object that has `generate` and `write` methods
+- The "generate" phase generates the output files from the bundle by calling `.generate(outputOptions)` or `.write(outputOptions)`
+ - The main difference is that `.write` will write the files to disk while `.generate` just returns the output in-memory. Hence `.write` requires the [`file`](https://rollupjs.org/configuration-options/#output-file) or [`dir`](https://rollupjs.org/configuration-options/#output-dir) options to be set while `.generate` does not.
+ - It is possible to generate multiple outputs from the same bundle e.g. with different formats
+ - As code-splitting is also part of the "generate" phase, outputs can also use [`preserveModules`](https://rollupjs.org/configuration-options/#output-preservemodules) to keep the file structure or [`inlineDynamicImports`](https://rollupjs.org/configuration-options/#output-inlinedynamicimports) to inline dynamic imports, albeit at the cost of some semantic changes.
+
+```mermaid
+flowchart LR
+ classDef default fill: transparent, color: black;
+ classDef graphobject fill: #ffb3b3, stroke: black;
+ classDef command fill: #ffd2b3, stroke: black, text-align: left;
+ build("rollup\ninput: main.js
"):::command
+ --> bundle(bundle):::command
+ --> generate1(".generate\nfile: main.mjs,\nformat: 'es'
"):::command
+
+ bundle
+ -->generate2(".generate\nfile: main.cjs,\nformat: 'cjs'
"):::command
+```
+
+On the highest level, all of this is orchestrated by the `rollupInternal` function in [`rollup.ts`](src/rollup/rollup.ts). This function
+
+- Parses and normalizes the input options via [`normalizeInputOptions`](src/utils/options/normalizeInputOptions.ts)
+- Initializes the [`Graph`](src/Graph.ts) instance
+- Triggers the actual build phase via `Graph.build()`
+- Generates the "bundle" object with the `.generate` and `.write` methods
+- These methods in turn first parse and normalize the output options via [`normalizeOutputOptions`](src/utils/options/normalizeOutputOptions.ts)
+- Then they create a [`Bundle`](src/Bundle.ts) instance that manages one output
+- Last, they trigger the actual generate phase via `Bundle.generate()`
+
+### The build phase
+
+To understand this phase from a plugin perspective, have a look at [Build Hooks](https://rollupjs.org/plugin-development/#build-hooks), which also contains a graph to show in which order these hooks are executed. In detail, `Graph.build` performs the following steps
+
+- It generates the module graph. This is orchestrated by the [`ModuleLoader`](src/ModuleLoader.ts) class. This class
+ - Reads all entry points provided by the [`input`](https://rollupjs.org/configuration-options/#input) option and additional entry points emitted from plugins via [`this.emitFile()`](https://rollupjs.org/plugin-development/#this-emitfile).
+ - For each module, it first creates a [`Module`](src/Module.ts) instance.
+ - Then it loads and transforms the code via the corresponding plugin hooks.
+ - The resulting code and sourcemaps are passed to the `Module` instance via `Module.setSource()`.
+ - This parses the code into the Rollup AST, which consists of the classes defined in the [ast folder](src/ast/nodes). For details see also [below](#parsing-the-ast).
+ - In the process, it also collects all static and dynamic dependencies of the module.
+ - These are then again loaded and transformed by the `ModuleLoader`, a process that repeats until the graph is complete.
+- It sorts the modules by their execution order to assign an `execIndex` to each module in [`executionOrder.ts`](src/utils/executionOrder.ts).
+- It marks which statements in each module are included in the output, also known as "tree-shaking"
+ - This happens in several passes. Each pass starts with calling `.include` on the `Module` instance.
+ - This again calls `.include` on the top-level AST node, that is then propagated to the child nodes. At several stages, inclusion will only happen if a statement or expression has "side effects", which is determined by calling its `.hasEffects` method. Usually, it means mutating a variable that is already included or performing an action where we cannot determine whether there are side effects like calling a global function.
+ - Nodes that are already included are included again for each pass as it is possible that with each pass, some additional child nodes may need to be included. Whenever something new is included, another pass will be scheduled once the current pass is finished.
+ - In the end, it sets `.included` flags on the AST nodes that are then picked up by the rendering logic in the "generate" phase.
+
+### The generate phase
+
+To understand this phase from a plugin perspective, have a look at [Output Generation Hooks](https://rollupjs.org/plugin-development/#output-generation-hooks), which again contains a graph to show in which order these hooks are executed. In detail `Bundle.generate` performs the following steps
+
+- Assign modules to chunks via [`chunkAssigment.ts`](src/utils/chunkAssignment.ts)
+- Determine the exports for each chunk by tracing the included inter-module dependencies
+- Render the chunks, which is orchestrated by the [`renderChunks`](src/utils/renderChunks.ts) helper
+ - Render the chunks with placeholders for chunk hashes by calling `Chunk.render()`
+ - Determine how dynamic imports and `import.meta` references should be resolved and store this on the corresponding AST nodes.
+ - Determine the final deconflicted variable names and store those on the AST nodes as well in [`deconflictChunk.ts`](src/utils/deconflictChunk.ts)
+ - Render each module by calling the `.render` methods of their AST nodes. This is also where tree-shaken nodes are removed from the output.
+ - Render the format specific wrapper with imports and exports for this chunk by calling the corresponding [finalizer](src/finalisers).
+ - Transform the rendered chunks via the [`renderChunk`](https://rollupjs.org/plugin-development/#renderchunk) plugin hook
+ - Determine the final chunk hashes based on the actual rendered content and the chunk dependency graph and replace the placeholders
+
+## Parsing the AST
+
+Rollup parses code within the native/WebAssembly code. As most of Rollup is still TypeScript-based, this then needs to be transformed to a JavaScript representation. To do that efficiently, a binary buffer is constructed in Rust that can be passed without copying to TypeScript where it is further transformed.
+
+- The conversion to a buffer happens mostly within [`converter.rs`](rust/parse_ast/src/convert_ast/converter.rs). Here we also make sure that the buffer follows the format of the [ESTree specification](https://github.com/estree/estree).
+- While the converter is still mostly hand-written, it relies on auto-generated constants to ensure that the encoder and decoder match. These are generated together with the decoders from [`generate-ast-converters.js`](scripts/generate-ast-converters.js) via `npm run build:ast-converters`. The definitions for the auto-generated converters can be found in [`ast-types.js`](scripts/ast-types.js), which is also the first file that needs to be extended to support additional AST nodes.
+
+There are two ways Rollup parses code into an abstract syntax tree
+
+- When a plugin calls [`this.parse`](https://rollupjs.org/plugin-development/#this-parse). This is a synchronous operation that returns a JSON-AST of the provided code.
+ - This will likely be deprecated eventually in favor of an asynchronous method that also does not directly return the JSON representation but rather a Proxy-based representation with efficient methods for traversal and manipulation.
+ - For this, the buffer is decoded within the auto-generated file [`bufferToAst.ts`](src/utils/bufferToAst.ts).
+- When a module has been loaded. In this case, it is triggered in the `setSource` method of the [`Module`](src/Module.ts) class.
+ - Here, the buffer is directly used to generate the class-based Rollup-internal AST.
+ - The actual conversion happens in the auto-generated file [`bufferParsers.ts`](src/ast/bufferParsers.ts).
+
+In general, when extending the AST parsing capabilities, the following places need to be touched:
+
+- declare any new AST nodes or additional AST attributes in [`ast-types.js`](scripts/ast-types.js).
+- write the encoder in Rust in [`converter.rs`](rust/parse_ast/src/convert_ast/converter.rs).
+- create the corresponding TypeScript classes in [`ast/nodes`](src/ast/nodes).
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8da23f4c9..37895bf32 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,145 @@
# rollup changelog
+## 4.16.4
+
+_2024-04-23_
+
+### Bug Fixes
+
+- Revert function parameter tracking logic introduced in 4.16.0 to work on some remaining issues (#5487)
+
+### Pull Requests
+
+- [#5487](https://github.com/rollup/rollup/pull/5487): Revert function parameter tracking logic for now (@lukastaegert)
+
+## 4.16.3
+
+_2024-04-23_
+
+### Bug Fixes
+
+- Do not optimize IIFEs that have a name and are again referenced inside their definition (#5486)
+
+### Pull Requests
+
+- [#5486](https://github.com/rollup/rollup/pull/5486): fix: only optimize annoymous iife (@liuly0322)
+
+## 4.16.2
+
+_2024-04-22_
+
+### Bug Fixes
+
+- Resolve a situation condition where reassignments of function parameters were not tracked properly (#5482)
+- Make sure that for armv7 packages, only one package is downloaded for the user (musl or gnu) (#5479)
+
+### Pull Requests
+
+- [#5479](https://github.com/rollup/rollup/pull/5479): Add libc field to armv7 packages (@sapphi-red)
+- [#5482](https://github.com/rollup/rollup/pull/5482): fix: function parameter reassigned update (@liuly0322)
+
+## 4.16.1
+
+_2024-04-21_
+
+### Bug Fixes
+
+- Fix crash when rendering logical or conditional expressions (#5481)
+
+### Pull Requests
+
+- [#5481](https://github.com/rollup/rollup/pull/5481): fix: conditional/logical expression should request a new tree-shaking (@liuly0322)
+
+## 4.16.0
+
+_2024-04-21_
+
+### Features
+
+- Track function call arguments to optimize functions only called once or with the same literal values (#5443)
+
+### Pull Requests
+
+- [#5443](https://github.com/rollup/rollup/pull/5443): feat: improve tree-shaking by propagate const parameter (@liuly0322, @lukastaegert)
+
+## 4.15.0
+
+_2024-04-20_
+
+### Features
+
+- Add output.importAttributesKey option to select whether to use "with" or "assert" for import attributes (#5474)
+
+### Pull Requests
+
+- [#5474](https://github.com/rollup/rollup/pull/5474): Add ImportAttributesKey to choose keyword ("with" | "assert") (@doubleaa93, @lukastaegert)
+- [#5475](https://github.com/rollup/rollup/pull/5475): chore(deps): lock file maintenance minor/patch updates (@renovate[bot])
+- [#5477](https://github.com/rollup/rollup/pull/5477): Try to run emulated smoke tests for Linux environments (@lukastaegert)
+
+## 4.14.3
+
+_2024-04-15_
+
+### Bug Fixes
+
+- Support Alpine Linux and other MUSL builds on ARM (#5471)
+
+### Pull Requests
+
+- [#5471](https://github.com/rollup/rollup/pull/5471): Add linux arm musl build (@sapphi-red)
+
+## 4.14.2
+
+_2024-04-12_
+
+### Bug Fixes
+
+- Do not create invalid code when reexporting both a namespace and the default export from that namespace (#5466)
+- Ensure ppc64 platform is properly detected (#5460)
+
+### Pull Requests
+
+- [#5456](https://github.com/rollup/rollup/pull/5456): Add high-level architecture documentation (@lukastaegert)
+- [#5460](https://github.com/rollup/rollup/pull/5460): Fix ppc64le target (@lukastaegert)
+- [#5463](https://github.com/rollup/rollup/pull/5463): chore: tweak the comment about files should not be edited (@TrickyPi)
+- [#5466](https://github.com/rollup/rollup/pull/5466): Ensure reexported namespaces do not prevent creation of default export helpers (@lukastaegert)
+- [#5468](https://github.com/rollup/rollup/pull/5468): chore(deps): update dependency eslint-plugin-unicorn to v52 (@renovate[bot], @lukastaegert)
+- [#5469](https://github.com/rollup/rollup/pull/5469): chore(deps): lock file maintenance minor/patch updates (@renovate[bot])
+- [#5470](https://github.com/rollup/rollup/pull/5470): chore(deps): lock file maintenance (@renovate[bot])
+
+## 4.14.1
+
+_2024-04-07_
+
+### Bug Fixes
+
+- Show better error when running on musl Linux where the musl build is not supported (#5454)
+
+### Pull Requests
+
+- [#5451](https://github.com/rollup/rollup/pull/5451): chore: generate string constants from config (@TrickyPi)
+- [#5452](https://github.com/rollup/rollup/pull/5452): chore(deps): lock file maintenance minor/patch updates (@renovate[bot])
+- [#5453](https://github.com/rollup/rollup/pull/5453): chore(deps): lock file maintenance (@renovate[bot])
+- [#5454](https://github.com/rollup/rollup/pull/5454): Improve error message when running on unsupported MUSL Linux (@lukastaegert)
+- [#5455](https://github.com/rollup/rollup/pull/5455): Remove inlining logic in AST (de-)serializer (@lukastaegert)
+
+## 4.14.0
+
+_2024-04-03_
+
+### Features
+
+- Display error causes in Rollup CLI (#5422)
+- Add basic support for explicit resource management via "using" and "await using" (#5423)
+
+### Pull Requests
+
+- [#5422](https://github.com/rollup/rollup/pull/5422): feat: show all cause in Error (@devohda, @lukastaegert)
+- [#5444](https://github.com/rollup/rollup/pull/5444): feat: support explicit-resource-management (@TrickyPi)
+- [#5445](https://github.com/rollup/rollup/pull/5445): docs: add `@shikiji/vitepress-twoslash` (@sapphi-red)
+- [#5447](https://github.com/rollup/rollup/pull/5447): chore(deps): lock file maintenance minor/patch updates ( @renovate[bot])
+- [#5448](https://github.com/rollup/rollup/pull/5448): chore(deps): lock file maintenance (@renovate[bot])
+
## 4.13.2
_2024-03-28_
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 310ab6843..f59b6a89b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -115,6 +115,10 @@ will start the website locally in development mode via Vite. This will give you
A special feature of the website is that the REPL at `http://localhost:5173/repl/` is directly using the browser build of your local copy of Rollup created via Vite. It even supports full hot module replacement, which means that when you change anything within Rollup, the REPL will automatically rebundle the current code using your latest changes. This can come in very handy when working on a bug or tree-shaking improvement to allow extremely fast iterations.
+## Navigating the codebase
+
+See the [architecure documentation](ARCHITECTURE.md) for an overview of the codebase and a high-level explanation of how Rollup works.
+
## Submitting code
Any code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it. The pull request should also contain tests.
diff --git a/FUNDING.json b/FUNDING.json
new file mode 100644
index 000000000..fcb4f353d
--- /dev/null
+++ b/FUNDING.json
@@ -0,0 +1,7 @@
+{
+ "drips": {
+ "ethereum": {
+ "ownedBy": "0x3FF19163842E027ab536172B10123af20e3e4648"
+ }
+ }
+}
diff --git a/README.md b/README.md
index 883242200..fd88ab47d 100644
--- a/README.md
+++ b/README.md
@@ -48,9 +48,79 @@