From 4fedc7e34f5aefa1690da2e05bb877eff0aebb2d Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Tue, 2 Jun 2026 15:39:40 +0200 Subject: [PATCH 1/2] docs: Add Incremental Build Vitepress docs JIRA: CPOUI5FOUNDATION-1205 --- internal/documentation/docs/pages/Builder.md | 57 ++++++++++ .../documentation/docs/pages/Configuration.md | 3 + internal/documentation/docs/pages/Overview.md | 14 +++ internal/documentation/docs/pages/Server.md | 66 ++++++++++++ .../extensibility/CustomServerMiddleware.md | 27 +++++ .../docs/pages/extensibility/CustomTasks.md | 102 ++++++++++++++++++ .../documentation/docs/updates/migrate-v5.md | 101 +++++++++++++++++ 7 files changed, 370 insertions(+) diff --git a/internal/documentation/docs/pages/Builder.md b/internal/documentation/docs/pages/Builder.md index 2bf7a74fa46..262fe11bbf2 100644 --- a/internal/documentation/docs/pages/Builder.md +++ b/internal/documentation/docs/pages/Builder.md @@ -14,6 +14,63 @@ For every type there is a set of default tasks. You can disable single tasks usi +## Incremental Build and Caching + +Starting with UI5 CLI v5, UI5 project building integrates the **Incremental Build**. This architectural change brings significant benefits while introducing some behavioral differences compared to previous versions. Instead of rebuilding everything from scratch, the UI5 Builder tracks which resources have changed and which build tasks need to be re-executed: + +### How It Works + +When you start a project build with `ui5 build`: + +1. **Cache Population and Reuse**: The UI5 CLI builds your project caching build results and metadata +1. **File Watching**: When Watch Mode is enabled, the CLI monitors your source files for changes and triggers automatic rebuilds (see [Watch Mode](#watch-mode) section) +1. **Incremental Rebuilds**: When a rebuild is triggered, only relevant tasks are re-executed and cached results from unrelated ones are used +1. **Cached Results**: Build outputs are cached to gain performance during subsequent builds + +### Build Cache Control + +You can control the build cache behavior using the `--cache` option: + +- `--cache Default` (default): Use the cache if available, create it if missing +- `--cache Force`: Only use the cache; fail if the cache is unavailable or invalid +- `--cache ReadOnly`: Use existing cache but don't update it (useful for CI/CD) +- `--cache Off`: Disable caching entirely and always perform a full rebuild + +Example: +```sh +ui5 build --cache Off +``` +In this scenario, when a source file change is made, always perform a full rebuild (even if this source version already existed sometime ago). + +::: warning Important +Build caches created by `ui5 build` and `ui5 serve` are **separate and cannot be mixed**. Each command maintains its own cache optimized for its specific use case. +::: + +For more details on server caching, see the [UI5 Server documentation](./Server.md). + +### Watch Mode + +The `ui5 build` command supports a `--watch` flag that monitors source files for changes and automatically triggers incremental rebuilds: + +```sh +ui5 build --watch +``` + +When watch mode is enabled: +- Source files in your project are monitored for changes +- Incremental rebuilds are triggered automatically when changes are detected +- Only affected tasks are re-executed + +::: tip +Watch mode monitors your source files only. Changes to configuration files (`ui5.yaml`, `package.json`) or custom task implementations require restarting the build command. +::: + +::: info Info +For `ui5 serve`, this behavior is always turned on automatically. +::: + +TODO: check this section again once it's implemented + ## Tasks Tasks are specific build steps to be executed during build phase. diff --git a/internal/documentation/docs/pages/Configuration.md b/internal/documentation/docs/pages/Configuration.md index 03c6a4a2e99..661b06973e7 100644 --- a/internal/documentation/docs/pages/Configuration.md +++ b/internal/documentation/docs/pages/Configuration.md @@ -662,6 +662,9 @@ A project can also configure alternative default ports. If the configured port i The default and configured server ports can always be overwritten with the CLI parameter `--port`. + +TODO: Add Live Reload configuration once it's implemented + ## Extension Configuration ::: details Example diff --git a/internal/documentation/docs/pages/Overview.md b/internal/documentation/docs/pages/Overview.md index 5d0b510bf81..933473bc683 100644 --- a/internal/documentation/docs/pages/Overview.md +++ b/internal/documentation/docs/pages/Overview.md @@ -3,6 +3,20 @@ When developing a UI5 project on your local system, you should use the UI5 Serve However, you might have good reasons to also use the UI5 Builder during development. In such cases, feel free to let us know! Maybe your use case could be covered by a future enhancement of the UI5 Server. +## Incremental Build and Caching + +Starting with UI5 CLI v5, both `ui5 serve` and `ui5 build` use the **Incremental Build** to improve performance: + +- Build results are cached and reused across builds and server sessions +- Only modified resources and affected build tasks are reprocessed +- The server automatically watches source files and triggers rebuilds when changes are detected +- Custom build tasks from dependencies execute automatically — no manual middleware configuration needed + +For more details, see: +- [UI5 Server: Incremental Build and Caching](./Server.md#incremental-build-and-caching) +- [UI5 Builder: Incremental Build and Caching](./Builder.md#incremental-build-and-caching) +- [Migration Guide: Incremental Build](../updates/migrate-v5.md#incremental-build) + ## Project Dependencies UI5 CLI differentiates between "framework dependencies" and "project dependencies". diff --git a/internal/documentation/docs/pages/Server.md b/internal/documentation/docs/pages/Server.md index 64fd885fe4a..9725aa8fc28 100644 --- a/internal/documentation/docs/pages/Server.md +++ b/internal/documentation/docs/pages/Server.md @@ -23,6 +23,66 @@ Please be aware of the following risks when using the server: ::: + +## Development Server + +Starting with UI5 CLI v5, the development server integrates with the **Incremental Build**. This architectural change brings significant benefits while introducing some behavioral differences compared to previous versions. + +### How It Works + +When you start the server with `ui5 serve`: + +1. **On-Demand Building**: The server builds your project only when a request comes in, and only if no cache exists or the cache is stale +1. **File Watching**: The server monitors your source files for changes +1. **Incremental Rebuilds**: When changes are detected and a new request is sent, an automatic rebuild is triggered containing only relevant build tasks +1. **Live Reload**: If live reload is enabled, the browser automatically refreshes once a rebuild completes (see [Live Reload](#live-reload) section) +1. **Cached Results**: Build outputs are cached to gain performance during subsequent builds + +### Benefits + +- **Faster Subsequent Builds**: The incremental build cache significantly speeds up rebuilds after the first run +- **Automatic Dependency Task Execution**: Custom build tasks defined in your project's dependencies (libraries, modules) are now executed automatically during the build. You no longer need to configure custom middleware to handle these tasks. +- **Theme Pre-Compilation**: Themes are now pre-compiled by the `buildThemes` task during the build, improving performance (see [Removed Middleware](#standard-middleware) section) + +### Server Cache Control + +You can control the build cache behavior using the `--cache` option: + +- `--cache Default` (default): Use the cache if available, create it if missing +- `--cache Force`: Only use the cache; fail if the cache is unavailable or invalid +- `--cache ReadOnly`: Use existing cache but don't update it (useful for CI/CD) +- `--cache Off`: Disable caching entirely and always perform a full rebuild + +Example: +```sh +ui5 serve --cache Off +``` +In this scenario, when a source file change is made and a request comes in, always perform a full rebuild (even if this source version already existed sometime ago). + +::: warning Important +Build caches created by `ui5 build` and `ui5 serve` are **separate and cannot be mixed**. Each command maintains its own cache optimized for its specific use case. +::: + +For more details on build caching, see the [UI5 Builder documentation](./Builder.md). + +### Watch Mode Behavior + +The server automatically watches your source files and triggers rebuilds when changes are detected: + +- **Monitored files**: All files in your project's source directories (`src/`, `webapp/`, `test/`, etc.) +- **Not monitored**: Configuration files (`ui5.yaml`, `package.json`), custom task implementations, and dependency files + +::: tip +Changes to configuration files or custom tasks require a server restart to take effect. +::: + +### Live Reload + +When Live Reload is enabled, the server automatically triggers a rebuild (utilizing caches) and notifies connected browsers to automatically refresh the page. This feature requires: + +TODO: Add explanation once live reload is implemented (CLI option + yaml config) +TODO: Mention that this supersedes ui5-livereload-middleware + ## Standard Middleware ::: info Removed Middleware @@ -87,6 +147,12 @@ Answers all non-read requests (POST, PUT, DELETE, etc.) that have not been answe ### serveIndex In case a directory has been requested, this middleware renders an HTML with a list of the directory's content. +## Standard Tasks +With UI5 CLI v5, a set of Standard Tasks is executed during a server build... +(excluding "minify", "generateLibraryPreload", "generateComponentPreload", "generateBundle") +TODO: Add list/table of standard tasks for ui5 serve (similar to Builder docs) with reference to the API docs (for more info) +TODO: Add --exclude-task explanation once and whether it's merged: "You may exclude unnecessary tasks to speed up development even more: ui5 serve --exclude-task enhanceManifest + ## SSL Certificates When starting the UI5 Server in HTTPS- or HTTP/2 mode, for example by using UI5 CLI parameter `--h2`, you will be prompted for the automatic generation of a local SSL certificate if necessary. diff --git a/internal/documentation/docs/pages/extensibility/CustomServerMiddleware.md b/internal/documentation/docs/pages/extensibility/CustomServerMiddleware.md index 1b5f22cb0aa..59100892f79 100644 --- a/internal/documentation/docs/pages/extensibility/CustomServerMiddleware.md +++ b/internal/documentation/docs/pages/extensibility/CustomServerMiddleware.md @@ -34,6 +34,33 @@ There can be optional configuration parameters which are passed directly to the An optional mountPath for which the middleware function is invoked can be provided. It will be passed to the `app.use` call (see [express API reference](https://expressjs.com/en/4x/api.html#app.use)). +### With Incremental Build + +**Change in UI5 CLI v5:** The development server now integrates with the incremental build system. When a request comes in, the server builds the project on-demand (if no cache exists or the cache is stale) before serving resources. + +- **Custom build tasks from dependencies execute automatically**: If your reusable library or module defines custom build tasks, they will be executed during the build phase. You no longer need to configure custom middleware at the root project level to handle tasks from dependencies. + +- **Middleware receives pre-built resources**: The `resources` parameter passed to your middleware implementation provides access to fully built resources, including outputs from all build tasks (both standard and custom). + +#### Accessing Build Outputs in Middleware + +The `resources` readers provided to your middleware return pre-built resources: + +```js +export default function({resources, log}) { + return async function (req, res, next) { + // This returns the built resource, including all task transformations + const resource = await resources.all.byPath(req.path); + + if (resource) { + const content = await resource.getString(); + // The content has already been processed by all build tasks + } + next(); + } +} +``` + ### Execution order Note that middleware configurations are applied in the order they are defined. When referencing another custom middleware, it has to be defined *before* that reference. diff --git a/internal/documentation/docs/pages/extensibility/CustomTasks.md b/internal/documentation/docs/pages/extensibility/CustomTasks.md index 23c27aa1c76..9cffc496ad4 100644 --- a/internal/documentation/docs/pages/extensibility/CustomTasks.md +++ b/internal/documentation/docs/pages/extensibility/CustomTasks.md @@ -103,6 +103,108 @@ task: path: lib/tasks/renderMarkdownFiles.js ``` +## Incremental Build Support + +Starting with UI5 CLI v5, the UI5 Builder supports **incremental builds** by caching task data. Custom tasks can opt into this behavior to improve performance. + +### How Incremental Builds Work for Tasks + +1. **First Execution**: The task runs normally and its outputs are cached +1. **Resource Tracking**: The build system tracks which resources the task reads and writes +1. **Cache Validation**: On subsequent builds, if the task's inputs haven't changed, the cached outputs are reused and the task is skipped +1. **Incremental Execution**: If only some inputs changed, the task can optionally process only those changed resources (see [supportsDifferentialBuilds()](#supportsDifferentialBuilds()) below) + +### Making Your Task Cache-Aware (Differential Builds) + +Custom build tasks can now optionally support **differential builds** by implementing the following new features. + +::: info Info +When a task supports differential builds, it is the task author's responsibility to ensure correctness. Specifically, if a task's output for resource A depends on the content of resource B, the task must account for this when processing only the changed resources. Tasks that cannot reliably determine such cross-resource dependencies should not enable differential build support. For example, bundling tasks — where the output depends on the content of many input resources — may not support differential builds until a more robust solution is available. +::: + +#### `supportsDifferentialBuilds()` + +TODO: Check this section again + +Indicates whether your task can process only changed resources: + +```js +/** + * Indicates whether this task can perform differential builds + * + * @returns {boolean} True if the task can process only modified resources + */ +export function supportsDifferentialBuilds() { + return true; // This task can process only changed files +} +``` + +When this returns `true`, your task's main function receives an additional parameter indicating which resources have changed. The task can then process only those resources instead of all resources. + +#### `determineBuildSignature({log, options})` + +TODO: Check this section again + +Returns `undefined` or an arbitrary string representing the build signature for the task. This can be used to incorporate task-specific configuration files into the build signature of the project, causing the cache to be invalidated if those files change. The string should not be a hash value (the build signature hash is calculated later). If `undefined` is returned, or if the method is not implemented, it is assumed that the task's cache remains valid until relevant input resources change. + +This method is called once at the beginning of every build. The return value is used to calculate a unique signature for the task based on its configuration. This signature is then incorporated into the overall build signature of the project. + +```js +/** + * Determines the build signature for this task + * + * Configuration changes that affect output should be reflected in this signature + * + * @param {object} parameters + * @param {@ui5/logger/Logger} parameters.log Logger instance + * @param {object} parameters.options Task options from ui5.yaml + * @returns {Promise} Build signature string + */ +export async function determineBuildSignature({log, options}) { + return "TODO:"; +} +``` + +**Example use case:** A TypeScript compilation task that includes the TypeScript version and `tsconfig.json` settings in its signature, so the cache is invalidated when compiler settings change. + +#### `determineExpectedOutput({workspace, dependencies, log, options})` + +TODO: Check this section again + +Declares which resources the task is expected to produce. This allows the build system to detect and remove stale outputs when the task stops producing files it previously created. + +This method is called right before the task is being executed. It is used to detect stale output resources that were produced in a previous execution of the task, but are no longer produced in the current execution. Such stale resources must be removed from the build output to avoid inconsistencies. + +```js +/** + * Determines which resources this task is expected to produce + * + * @param {object} parameters + * @param {module:@ui5/fs.DuplexCollection} parameters.workspace Reader/Writer for project resources + * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader for dependency resources + * @param {@ui5/logger/Logger} parameters.log Logger instance + * @param {object} parameters.options Task options from ui5.yaml + * @returns {Promise>} Array of resource paths this task will produce + */ +export async function determineExpectedOutput({workspace, dependencies, log, options}) { + // Return the paths of resources this task will create + const sourceFiles = await workspace.byGlob("**/*.ts"); + return sourceFiles.map(resource => + resource.getPath().replace(/\.ts$/, ".js") + ); +} +``` + +**Example use case:** A code generator that creates JavaScript files from TypeScript sources. If a `.ts` file is deleted, the corresponding `.js` file should also be removed. + +### Best Practices for Cache-Aware Tasks + +1. **Keep tasks deterministic**: Given the same inputs, always produce the same outputs +2. **Use `determineBuildSignature`**: Include all configuration that affects output in the build signature +3. **Opt into differential builds carefully**: Only set `supportsDifferentialBuilds = true` if your task can safely process files independently +4. **Declare expected outputs**: Implement `determineExpectedOutput` if your task generates new files (not just modifies existing ones) +5. **Test cache behavior**: Verify that your task produces identical results whether running from cache or fresh execution + ## Task Implementation A custom task implementation needs to return a function with the following signature: diff --git a/internal/documentation/docs/updates/migrate-v5.md b/internal/documentation/docs/updates/migrate-v5.md index 1612bd6dfa9..f42ae0cbe7c 100644 --- a/internal/documentation/docs/updates/migrate-v5.md +++ b/internal/documentation/docs/updates/migrate-v5.md @@ -29,6 +29,107 @@ UI5 CLI 5.x introduces **Specification Version 5.0**, which enables the new Comp Projects using older **Specification Versions** are expected to be **fully compatible with UI5 CLI v5**. +## Incremental Build + +UI5 CLI v5 introduces **incremental builds with caching** for both commands `ui5 build` and `ui5 serve`. This fundamental architectural change significantly improves build performance by reusing cached results from previous builds. + +### What Changed + +**Previous Behavior (v4 and earlier):** +- Every source change resulted in an entire rebuild of all projects +- Every build executed all tasks from scratch +- No caching between builds or server sessions + +**New Behavior (v5):** +- Only relevant projects are rebuilt +- Only modified resources and affected tasks are reprocessed +- **For `ui5 build`**: Caches are used automatically when available +- **For `ui5 serve`**: When a source file change occured and a request was made, the server automatically detects this, tries to use caches and only rebuilds when none are available + +### Impact on Your Workflow + +#### Performance + +- **First build**: Probably slower, as the cache is populated with all build outputs +- **Subsequent builds**: Significantly faster — only modified resources and affected tasks are reprocessed +- **Quick iterations**: Changes to individual files typically rebuild very quickly +- **Cache reuse**: Caches are used between server restarts and multiple build sessions + +TODO: Include some performance stats? + +### New CLI Options + +#### `--cache` Option + +Both `ui5 build` and `ui5 serve` now support a `--cache` option to control this build cache behavior: + +| Mode | Description | +|------|-------------| +| `Default` | Use cache if available, create/update as needed (default) | +| `Force` | Only use cache; fail if unavailable or invalid | +| `ReadOnly` | Use cache but don't write to file system | +| `Off` | Disable caching and rebuild from scratch | + +Example: +```sh +ui5 serve --cache ReadOnly # Use a cache if available, rebuild if not (don't write) +ui5 serve --cache Off # Disable build caching +ui5 build --cache Force # Always try to use the cache and fail if not available +``` + +#### Watch Mode +
+ +##### ui5 serve +When using `ui5 serve`, the development server automatically: + +1. **Watches source files** for changes (files in `src/`, `webapp/`, `test/`, etc.) +1. **Triggers automatic rebuilds** when changes are detected and a request is made (when Live Reload is enabled, this is automatically handled) + +
+ +##### ui5 build +When using `ui5 build --watch`, the UI5 CLI also **watches source files** and **triggers automatic rebuilds** when changes are detected. + +::: tip +Watch mode monitors your source files only. Changes to configuration files (`ui5.yaml`, `package.json`) or custom task implementations require a server restart (or build restart for `ui5 build`). +::: + +#### Live Reload + +When using `ui5 serve --live-reload` or adding `liveReload` to the ui5.yaml config (TODO: Adjust UI5 CLI - Server Config docs), the development server **notifies the browser** to reload the page automatically. In this scenario, manual refreshes to trigger a rebuild are not required. + +TODO: Add bit more explanation about technical details (e.g. Websockets / SSE) once it's implemented. --> which browsers are supported? + +### Cache Management + +By default, the build cache is stored in `~/.ui5/buildCache/`. You can: + +- **Customize the location:** + see [Changing UI5 CLI's Data Directory](../pages/Troubleshooting.md#changing-ui5-clis-data-directory) + +- **Adjust caching behavior**: + ```sh + ui5 build --cache Off + ui5 serve --cache ReadOnly + ``` + +- **Clear the cache:** + ``` + TODO: Add cache clean command explanation + ``` + +- **Verify the cache:** + ``` + TODO: Add cache verify command explanation + ``` + +### Migration Checklist + +- **Specification Version**: Make sure to use at least **Specification Version 5.0** in your UI5 config +- **New performance expectations**: First build might be slower, but subsequent builds are much faster +- **Review custom middleware**: With this feature, tasks are executed in server sessions. For this reason, some (custom) middleware might be obsolete or cause problems (TODO: Add which specific middleware??). Projects might need to adapt their configuration + ## Rename of Command Option With UI5 CLI v5, the option `--cache-mode` (for commands `ui5 build` and `ui5 serve`) has been renamed to `--snapshot-cache`. From 492ca1935fa49142591b31986e3b34eb35f1f69c Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Thu, 11 Jun 2026 19:12:19 +0200 Subject: [PATCH 2/2] docs: Refactor pages - Drop phrase "Incremental Build" and use "Build Cache" instead - Remove "Starting with v5" everywhere except migration guide - Restructured migration guide section - Refactor Custom task, Builder and Server pages - Remove TODOs & Drop changes for unrelated pages --- internal/documentation/docs/pages/Builder.md | 84 ++++------- .../documentation/docs/pages/Configuration.md | 3 - internal/documentation/docs/pages/Overview.md | 14 -- internal/documentation/docs/pages/Server.md | 105 ++++++-------- .../extensibility/CustomServerMiddleware.md | 27 ---- .../docs/pages/extensibility/CustomTasks.md | 132 ++++-------------- .../documentation/docs/updates/migrate-v5.md | 92 +++--------- 7 files changed, 112 insertions(+), 345 deletions(-) diff --git a/internal/documentation/docs/pages/Builder.md b/internal/documentation/docs/pages/Builder.md index 262fe11bbf2..e314866932d 100644 --- a/internal/documentation/docs/pages/Builder.md +++ b/internal/documentation/docs/pages/Builder.md @@ -14,63 +14,6 @@ For every type there is a set of default tasks. You can disable single tasks usi -## Incremental Build and Caching - -Starting with UI5 CLI v5, UI5 project building integrates the **Incremental Build**. This architectural change brings significant benefits while introducing some behavioral differences compared to previous versions. Instead of rebuilding everything from scratch, the UI5 Builder tracks which resources have changed and which build tasks need to be re-executed: - -### How It Works - -When you start a project build with `ui5 build`: - -1. **Cache Population and Reuse**: The UI5 CLI builds your project caching build results and metadata -1. **File Watching**: When Watch Mode is enabled, the CLI monitors your source files for changes and triggers automatic rebuilds (see [Watch Mode](#watch-mode) section) -1. **Incremental Rebuilds**: When a rebuild is triggered, only relevant tasks are re-executed and cached results from unrelated ones are used -1. **Cached Results**: Build outputs are cached to gain performance during subsequent builds - -### Build Cache Control - -You can control the build cache behavior using the `--cache` option: - -- `--cache Default` (default): Use the cache if available, create it if missing -- `--cache Force`: Only use the cache; fail if the cache is unavailable or invalid -- `--cache ReadOnly`: Use existing cache but don't update it (useful for CI/CD) -- `--cache Off`: Disable caching entirely and always perform a full rebuild - -Example: -```sh -ui5 build --cache Off -``` -In this scenario, when a source file change is made, always perform a full rebuild (even if this source version already existed sometime ago). - -::: warning Important -Build caches created by `ui5 build` and `ui5 serve` are **separate and cannot be mixed**. Each command maintains its own cache optimized for its specific use case. -::: - -For more details on server caching, see the [UI5 Server documentation](./Server.md). - -### Watch Mode - -The `ui5 build` command supports a `--watch` flag that monitors source files for changes and automatically triggers incremental rebuilds: - -```sh -ui5 build --watch -``` - -When watch mode is enabled: -- Source files in your project are monitored for changes -- Incremental rebuilds are triggered automatically when changes are detected -- Only affected tasks are re-executed - -::: tip -Watch mode monitors your source files only. Changes to configuration files (`ui5.yaml`, `package.json`) or custom task implementations require restarting the build command. -::: - -::: info Info -For `ui5 serve`, this behavior is always turned on automatically. -::: - -TODO: check this section again once it's implemented - ## Tasks Tasks are specific build steps to be executed during build phase. @@ -256,3 +199,30 @@ sap.ui.define([], () => { text-decoration: inherit; } + +## Build Cache Control + +The UI5 Builder integrates **build caches**. Instead of rebuilding everything from scratch, the UI5 Builder tracks which resources have changed and which build tasks need to be re-executed: + +You can control the build cache behavior using the `--cache` option: + +- `--cache Default` (default): Use the cache if available, create it if missing +- `--cache Force`: Only use the cache; fail if the cache is unavailable or invalid +- `--cache ReadOnly`: Use existing cache but don't update it (useful for CI/CD) +- `--cache Off`: Disable caching entirely and always perform a full rebuild + +Example: +```sh +ui5 build --cache Off +``` +In this scenario, when a source file change is made, always perform a full rebuild (even if this source version already existed sometime ago). + +::: info +By default, the build cache is stored inside UI5 CLI's Data Dir (`~/.ui5/buildCache/`). You can customize the location (see [Changing UI5 CLI's Data Directory](./Troubleshooting#changing-ui5-cli-s-data-directory)). +::: + +::: info +Build caches created by `ui5 build` and `ui5 serve` are **separate and cannot be mixed**. Each command maintains its own cache optimized for its specific use case. For more details on server caching, see the [UI5 Server documentation](./Server.md). +::: + + diff --git a/internal/documentation/docs/pages/Configuration.md b/internal/documentation/docs/pages/Configuration.md index 661b06973e7..03c6a4a2e99 100644 --- a/internal/documentation/docs/pages/Configuration.md +++ b/internal/documentation/docs/pages/Configuration.md @@ -662,9 +662,6 @@ A project can also configure alternative default ports. If the configured port i The default and configured server ports can always be overwritten with the CLI parameter `--port`. - -TODO: Add Live Reload configuration once it's implemented - ## Extension Configuration ::: details Example diff --git a/internal/documentation/docs/pages/Overview.md b/internal/documentation/docs/pages/Overview.md index 933473bc683..5d0b510bf81 100644 --- a/internal/documentation/docs/pages/Overview.md +++ b/internal/documentation/docs/pages/Overview.md @@ -3,20 +3,6 @@ When developing a UI5 project on your local system, you should use the UI5 Serve However, you might have good reasons to also use the UI5 Builder during development. In such cases, feel free to let us know! Maybe your use case could be covered by a future enhancement of the UI5 Server. -## Incremental Build and Caching - -Starting with UI5 CLI v5, both `ui5 serve` and `ui5 build` use the **Incremental Build** to improve performance: - -- Build results are cached and reused across builds and server sessions -- Only modified resources and affected build tasks are reprocessed -- The server automatically watches source files and triggers rebuilds when changes are detected -- Custom build tasks from dependencies execute automatically — no manual middleware configuration needed - -For more details, see: -- [UI5 Server: Incremental Build and Caching](./Server.md#incremental-build-and-caching) -- [UI5 Builder: Incremental Build and Caching](./Builder.md#incremental-build-and-caching) -- [Migration Guide: Incremental Build](../updates/migrate-v5.md#incremental-build) - ## Project Dependencies UI5 CLI differentiates between "framework dependencies" and "project dependencies". diff --git a/internal/documentation/docs/pages/Server.md b/internal/documentation/docs/pages/Server.md index 9725aa8fc28..31b36fb6bb6 100644 --- a/internal/documentation/docs/pages/Server.md +++ b/internal/documentation/docs/pages/Server.md @@ -23,66 +23,6 @@ Please be aware of the following risks when using the server: ::: - -## Development Server - -Starting with UI5 CLI v5, the development server integrates with the **Incremental Build**. This architectural change brings significant benefits while introducing some behavioral differences compared to previous versions. - -### How It Works - -When you start the server with `ui5 serve`: - -1. **On-Demand Building**: The server builds your project only when a request comes in, and only if no cache exists or the cache is stale -1. **File Watching**: The server monitors your source files for changes -1. **Incremental Rebuilds**: When changes are detected and a new request is sent, an automatic rebuild is triggered containing only relevant build tasks -1. **Live Reload**: If live reload is enabled, the browser automatically refreshes once a rebuild completes (see [Live Reload](#live-reload) section) -1. **Cached Results**: Build outputs are cached to gain performance during subsequent builds - -### Benefits - -- **Faster Subsequent Builds**: The incremental build cache significantly speeds up rebuilds after the first run -- **Automatic Dependency Task Execution**: Custom build tasks defined in your project's dependencies (libraries, modules) are now executed automatically during the build. You no longer need to configure custom middleware to handle these tasks. -- **Theme Pre-Compilation**: Themes are now pre-compiled by the `buildThemes` task during the build, improving performance (see [Removed Middleware](#standard-middleware) section) - -### Server Cache Control - -You can control the build cache behavior using the `--cache` option: - -- `--cache Default` (default): Use the cache if available, create it if missing -- `--cache Force`: Only use the cache; fail if the cache is unavailable or invalid -- `--cache ReadOnly`: Use existing cache but don't update it (useful for CI/CD) -- `--cache Off`: Disable caching entirely and always perform a full rebuild - -Example: -```sh -ui5 serve --cache Off -``` -In this scenario, when a source file change is made and a request comes in, always perform a full rebuild (even if this source version already existed sometime ago). - -::: warning Important -Build caches created by `ui5 build` and `ui5 serve` are **separate and cannot be mixed**. Each command maintains its own cache optimized for its specific use case. -::: - -For more details on build caching, see the [UI5 Builder documentation](./Builder.md). - -### Watch Mode Behavior - -The server automatically watches your source files and triggers rebuilds when changes are detected: - -- **Monitored files**: All files in your project's source directories (`src/`, `webapp/`, `test/`, etc.) -- **Not monitored**: Configuration files (`ui5.yaml`, `package.json`), custom task implementations, and dependency files - -::: tip -Changes to configuration files or custom tasks require a server restart to take effect. -::: - -### Live Reload - -When Live Reload is enabled, the server automatically triggers a rebuild (utilizing caches) and notifies connected browsers to automatically refresh the page. This feature requires: - -TODO: Add explanation once live reload is implemented (CLI option + yaml config) -TODO: Mention that this supersedes ui5-livereload-middleware - ## Standard Middleware ::: info Removed Middleware @@ -148,10 +88,47 @@ Answers all non-read requests (POST, PUT, DELETE, etc.) that have not been answe In case a directory has been requested, this middleware renders an HTML with a list of the directory's content. ## Standard Tasks -With UI5 CLI v5, a set of Standard Tasks is executed during a server build... -(excluding "minify", "generateLibraryPreload", "generateComponentPreload", "generateBundle") -TODO: Add list/table of standard tasks for ui5 serve (similar to Builder docs) with reference to the API docs (for more info) -TODO: Add --exclude-task explanation once and whether it's merged: "You may exclude unnecessary tasks to speed up development even more: ui5 serve --exclude-task enhanceManifest +As with the UI5 Builder, a set of standard tasks is being executed during a server build. However, following tasks are being **excluded by default**: +- `minify` +- `generateLibraryPreload` +- `generateComponentPreload` +- `generateBundle` + +::: info +See [Builder Standard Tasks](./Builder.md#standard-tasks) for more explanation about each task. +::: + +## Build Cache Control + +The UI5 Server performs a build of the projects by utilizing **build caches**. + +You can control the build cache behavior using the `--cache` option: + +- `--cache Default` (default): Use the cache if available, create it if missing +- `--cache Force`: Only use the cache; fail if the cache is unavailable or invalid +- `--cache ReadOnly`: Use existing cache but don't update it (useful for CI/CD) +- `--cache Off`: Disable caching entirely and always perform a full rebuild + +Example: +```sh +ui5 serve --cache Off +``` +In this scenario, when a source file change is made and a request comes in, the server always performs a full rebuild (even if this source version already existed sometime ago). + +::: info +Build caches created by `ui5 build` and `ui5 serve` are **separate and cannot be mixed**. Each command maintains its own cache optimized for its specific use case. For more details on builder caching, see the [UI5 Builder documentation](./Builder.md). +::: + +### Watch Mode Behavior + +Once started with `ui5 serve`, the server automatically keeps watch over changes to the source files throughout the session. When a request arrives, it checks for cached results first and only triggers a rebuild of the respective resources and tasks if no cache is available. + +- **Monitored files**: All files in your project's source directories (`src/`, `webapp/`, `test/`, etc.) +- **Not monitored**: Configuration files (`ui5.yaml`, `package.json`), custom task implementations, and dependency files + +::: info +Changes to configuration files or custom tasks require a server restart to take effect. +::: ## SSL Certificates When starting the UI5 Server in HTTPS- or HTTP/2 mode, for example by using UI5 CLI parameter `--h2`, you will be prompted for the automatic generation of a local SSL certificate if necessary. diff --git a/internal/documentation/docs/pages/extensibility/CustomServerMiddleware.md b/internal/documentation/docs/pages/extensibility/CustomServerMiddleware.md index 59100892f79..1b5f22cb0aa 100644 --- a/internal/documentation/docs/pages/extensibility/CustomServerMiddleware.md +++ b/internal/documentation/docs/pages/extensibility/CustomServerMiddleware.md @@ -34,33 +34,6 @@ There can be optional configuration parameters which are passed directly to the An optional mountPath for which the middleware function is invoked can be provided. It will be passed to the `app.use` call (see [express API reference](https://expressjs.com/en/4x/api.html#app.use)). -### With Incremental Build - -**Change in UI5 CLI v5:** The development server now integrates with the incremental build system. When a request comes in, the server builds the project on-demand (if no cache exists or the cache is stale) before serving resources. - -- **Custom build tasks from dependencies execute automatically**: If your reusable library or module defines custom build tasks, they will be executed during the build phase. You no longer need to configure custom middleware at the root project level to handle tasks from dependencies. - -- **Middleware receives pre-built resources**: The `resources` parameter passed to your middleware implementation provides access to fully built resources, including outputs from all build tasks (both standard and custom). - -#### Accessing Build Outputs in Middleware - -The `resources` readers provided to your middleware return pre-built resources: - -```js -export default function({resources, log}) { - return async function (req, res, next) { - // This returns the built resource, including all task transformations - const resource = await resources.all.byPath(req.path); - - if (resource) { - const content = await resource.getString(); - // The content has already been processed by all build tasks - } - next(); - } -} -``` - ### Execution order Note that middleware configurations are applied in the order they are defined. When referencing another custom middleware, it has to be defined *before* that reference. diff --git a/internal/documentation/docs/pages/extensibility/CustomTasks.md b/internal/documentation/docs/pages/extensibility/CustomTasks.md index 9cffc496ad4..33a67d0f910 100644 --- a/internal/documentation/docs/pages/extensibility/CustomTasks.md +++ b/internal/documentation/docs/pages/extensibility/CustomTasks.md @@ -103,108 +103,6 @@ task: path: lib/tasks/renderMarkdownFiles.js ``` -## Incremental Build Support - -Starting with UI5 CLI v5, the UI5 Builder supports **incremental builds** by caching task data. Custom tasks can opt into this behavior to improve performance. - -### How Incremental Builds Work for Tasks - -1. **First Execution**: The task runs normally and its outputs are cached -1. **Resource Tracking**: The build system tracks which resources the task reads and writes -1. **Cache Validation**: On subsequent builds, if the task's inputs haven't changed, the cached outputs are reused and the task is skipped -1. **Incremental Execution**: If only some inputs changed, the task can optionally process only those changed resources (see [supportsDifferentialBuilds()](#supportsDifferentialBuilds()) below) - -### Making Your Task Cache-Aware (Differential Builds) - -Custom build tasks can now optionally support **differential builds** by implementing the following new features. - -::: info Info -When a task supports differential builds, it is the task author's responsibility to ensure correctness. Specifically, if a task's output for resource A depends on the content of resource B, the task must account for this when processing only the changed resources. Tasks that cannot reliably determine such cross-resource dependencies should not enable differential build support. For example, bundling tasks — where the output depends on the content of many input resources — may not support differential builds until a more robust solution is available. -::: - -#### `supportsDifferentialBuilds()` - -TODO: Check this section again - -Indicates whether your task can process only changed resources: - -```js -/** - * Indicates whether this task can perform differential builds - * - * @returns {boolean} True if the task can process only modified resources - */ -export function supportsDifferentialBuilds() { - return true; // This task can process only changed files -} -``` - -When this returns `true`, your task's main function receives an additional parameter indicating which resources have changed. The task can then process only those resources instead of all resources. - -#### `determineBuildSignature({log, options})` - -TODO: Check this section again - -Returns `undefined` or an arbitrary string representing the build signature for the task. This can be used to incorporate task-specific configuration files into the build signature of the project, causing the cache to be invalidated if those files change. The string should not be a hash value (the build signature hash is calculated later). If `undefined` is returned, or if the method is not implemented, it is assumed that the task's cache remains valid until relevant input resources change. - -This method is called once at the beginning of every build. The return value is used to calculate a unique signature for the task based on its configuration. This signature is then incorporated into the overall build signature of the project. - -```js -/** - * Determines the build signature for this task - * - * Configuration changes that affect output should be reflected in this signature - * - * @param {object} parameters - * @param {@ui5/logger/Logger} parameters.log Logger instance - * @param {object} parameters.options Task options from ui5.yaml - * @returns {Promise} Build signature string - */ -export async function determineBuildSignature({log, options}) { - return "TODO:"; -} -``` - -**Example use case:** A TypeScript compilation task that includes the TypeScript version and `tsconfig.json` settings in its signature, so the cache is invalidated when compiler settings change. - -#### `determineExpectedOutput({workspace, dependencies, log, options})` - -TODO: Check this section again - -Declares which resources the task is expected to produce. This allows the build system to detect and remove stale outputs when the task stops producing files it previously created. - -This method is called right before the task is being executed. It is used to detect stale output resources that were produced in a previous execution of the task, but are no longer produced in the current execution. Such stale resources must be removed from the build output to avoid inconsistencies. - -```js -/** - * Determines which resources this task is expected to produce - * - * @param {object} parameters - * @param {module:@ui5/fs.DuplexCollection} parameters.workspace Reader/Writer for project resources - * @param {module:@ui5/fs.AbstractReader} parameters.dependencies Reader for dependency resources - * @param {@ui5/logger/Logger} parameters.log Logger instance - * @param {object} parameters.options Task options from ui5.yaml - * @returns {Promise>} Array of resource paths this task will produce - */ -export async function determineExpectedOutput({workspace, dependencies, log, options}) { - // Return the paths of resources this task will create - const sourceFiles = await workspace.byGlob("**/*.ts"); - return sourceFiles.map(resource => - resource.getPath().replace(/\.ts$/, ".js") - ); -} -``` - -**Example use case:** A code generator that creates JavaScript files from TypeScript sources. If a `.ts` file is deleted, the corresponding `.js` file should also be removed. - -### Best Practices for Cache-Aware Tasks - -1. **Keep tasks deterministic**: Given the same inputs, always produce the same outputs -2. **Use `determineBuildSignature`**: Include all configuration that affects output in the build signature -3. **Opt into differential builds carefully**: Only set `supportsDifferentialBuilds = true` if your task can safely process files independently -4. **Declare expected outputs**: Implement `determineExpectedOutput` if your task generates new files (not just modifies existing ones) -5. **Test cache behavior**: Verify that your task produces identical results whether running from cache or fresh execution - ## Task Implementation A custom task implementation needs to return a function with the following signature: @@ -388,11 +286,37 @@ module.exports.determineRequiredDependencies = async function({availableDependen ``` ::: +### "Cache-aware" Tasks + +Due to UI5 Builder and UI5 Server supporting **build caches** of task data, custom tasks can opt into this behavior to improve performance. This is done by implementing the following features: + +#### `supportsDifferentialBuilds()` + +This method indicates whether your task can perform differential builds: + +```js +/** + * Indicates whether this task can perform differential builds + * + * @returns {boolean} True if the task can process only modified resources + */ +export function supportsDifferentialBuilds() { + return true; +} +``` + +When this returns `true`, your task's main function receives an additional parameter indicating which resources have changed. The task can then process only those resources instead of all resources. + +::: info Best Practices for Cache-aware Tasks +1. **Keep tasks deterministic**: Given the same inputs, always produce the same outputs +2. **Opt into differential builds carefully**: Only set `supportsDifferentialBuilds = true` if your task can safely process files independently +::: + ### Examples The following code snippets show examples for custom task implementations. -### Example: lib/tasks/renderMarkdownFiles.js +#### Example: lib/tasks/renderMarkdownFiles.js This example is making use of the `resourceFactory` [TaskUtil](https://ui5.github.io/cli/v5/api/@ui5_project_build_helpers_TaskUtil.html) API to create new resources based on the output of a third-party module for rendering Markdown files. The created resources are added to the build @@ -466,7 +390,7 @@ Tasks should ideally use the reader/writer APIs provided by UI5 CLI for working ::: -### Example: lib/tasks/compileLicenseSummary.js +#### Example: lib/tasks/compileLicenseSummary.js This example is making use of multiple [TaskUtil](https://ui5.github.io/cli/v5/api/@ui5_project_build_helpers_TaskUtil.html) APIs to retrieve additional information about the project currently being built (`taskUtil.getProject()`) and its direct dependencies diff --git a/internal/documentation/docs/updates/migrate-v5.md b/internal/documentation/docs/updates/migrate-v5.md index f42ae0cbe7c..bcb8d74ceb3 100644 --- a/internal/documentation/docs/updates/migrate-v5.md +++ b/internal/documentation/docs/updates/migrate-v5.md @@ -29,106 +29,46 @@ UI5 CLI 5.x introduces **Specification Version 5.0**, which enables the new Comp Projects using older **Specification Versions** are expected to be **fully compatible with UI5 CLI v5**. -## Incremental Build +## Build Cache -UI5 CLI v5 introduces **incremental builds with caching** for both commands `ui5 build` and `ui5 serve`. This fundamental architectural change significantly improves build performance by reusing cached results from previous builds. +UI5 CLI v5 introduces **builds with caching** for both commands `ui5 build` and `ui5 serve`. This fundamental architectural change significantly improves build performance by reusing cached results from previous builds. ### What Changed **Previous Behavior (v4 and earlier):** - Every source change resulted in an entire rebuild of all projects -- Every build executed all tasks from scratch +- Every build re-executed all tasks - No caching between builds or server sessions **New Behavior (v5):** - Only relevant projects are rebuilt -- Only modified resources and affected tasks are reprocessed -- **For `ui5 build`**: Caches are used automatically when available -- **For `ui5 serve`**: When a source file change occured and a request was made, the server automatically detects this, tries to use caches and only rebuilds when none are available +- Only modified resources and affected tasks are re-processed ### Impact on Your Workflow -#### Performance - -- **First build**: Probably slower, as the cache is populated with all build outputs +- **First build**: Probably slightly slower, as the cache is populated with all build outputs - **Subsequent builds**: Significantly faster — only modified resources and affected tasks are reprocessed - **Quick iterations**: Changes to individual files typically rebuild very quickly -- **Cache reuse**: Caches are used between server restarts and multiple build sessions - -TODO: Include some performance stats? - -### New CLI Options - -#### `--cache` Option - -Both `ui5 build` and `ui5 serve` now support a `--cache` option to control this build cache behavior: - -| Mode | Description | -|------|-------------| -| `Default` | Use cache if available, create/update as needed (default) | -| `Force` | Only use cache; fail if unavailable or invalid | -| `ReadOnly` | Use cache but don't write to file system | -| `Off` | Disable caching and rebuild from scratch | - -Example: -```sh -ui5 serve --cache ReadOnly # Use a cache if available, rebuild if not (don't write) -ui5 serve --cache Off # Disable build caching -ui5 build --cache Force # Always try to use the cache and fail if not available -``` - -#### Watch Mode -
+- **Cross-session**: Caches are used between server restarts and build runs -##### ui5 serve -When using `ui5 serve`, the development server automatically: +### For `ui5 build` -1. **Watches source files** for changes (files in `src/`, `webapp/`, `test/`, etc.) -1. **Triggers automatic rebuilds** when changes are detected and a request is made (when Live Reload is enabled, this is automatically handled) +When `ui5 build` is executed, build caches are automatically serialized and reused when available. -
- -##### ui5 build -When using `ui5 build --watch`, the UI5 CLI also **watches source files** and **triggers automatic rebuilds** when changes are detected. - -::: tip -Watch mode monitors your source files only. Changes to configuration files (`ui5.yaml`, `package.json`) or custom task implementations require a server restart (or build restart for `ui5 build`). +::: tip Tip for Single Builds (e.g. CI/CD) +If you plan to execute a build only once (e.g. during a CI run), consider using `--cache "Off"` (see [Build Cache Control](../pages/Builder.md#build-cache-control)) to skip cache serialization. ::: -#### Live Reload - -When using `ui5 serve --live-reload` or adding `liveReload` to the ui5.yaml config (TODO: Adjust UI5 CLI - Server Config docs), the development server **notifies the browser** to reload the page automatically. In this scenario, manual refreshes to trigger a rebuild are not required. - -TODO: Add bit more explanation about technical details (e.g. Websockets / SSE) once it's implemented. --> which browsers are supported? - -### Cache Management +### For `ui5 serve` -By default, the build cache is stored in `~/.ui5/buildCache/`. You can: +During a server session (started by `ui5 serve`), source changes are automatically being monitered. Then, if a request was made, the server detects this, tries to use caches and only rebuilds when none are available. For more information see [Watch Mode Behavior](../pages/Server.md#watch-mode-behavior). -- **Customize the location:** - see [Changing UI5 CLI's Data Directory](../pages/Troubleshooting.md#changing-ui5-clis-data-directory) +::: info Review custom middleware -- **Adjust caching behavior**: - ```sh - ui5 build --cache Off - ui5 serve --cache ReadOnly - ``` +With this feature, **build tasks are executed in server sessions**. For this reason, some custom middleware might be obsolete or cause problems. Projects utilizing such might need to adapt their configuration. -- **Clear the cache:** - ``` - TODO: Add cache clean command explanation - ``` - -- **Verify the cache:** - ``` - TODO: Add cache verify command explanation - ``` - -### Migration Checklist - -- **Specification Version**: Make sure to use at least **Specification Version 5.0** in your UI5 config -- **New performance expectations**: First build might be slower, but subsequent builds are much faster -- **Review custom middleware**: With this feature, tasks are executed in server sessions. For this reason, some (custom) middleware might be obsolete or cause problems (TODO: Add which specific middleware??). Projects might need to adapt their configuration +E.g. Middleware for browser live reloads is obsolete and can be removed. Also, middleware for Typescript transpilation is not required anymore (as long as the respective task is still set up). +::: ## Rename of Command Option