Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/documentation/docs/pages/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A projects UI5 CLI configuration is typically located in a [YAML](https://yaml.org/) file named `ui5.yaml`, located in the root directory.

::: info Info
This document describes the configuration of UI5 CLI-based projects and extensions. It represents **[Specification Version 3.0](#specification-versions)**.
This document describes the configuration of UI5 CLI-based projects and extensions. It represents **[Specification Version 5.0](#specification-versions)**.

:::

Expand Down
67 changes: 35 additions & 32 deletions packages/documentation/docs/pages/Project.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,30 @@ Also see [UI5 Project: Configuration](./Configuration.md#general-configuration)
### component
*Available since [Specification Version 5.0](./Configuration.md#specification-version-50)*

> **Note:** The term `component` as used in the UI5 CLI project type differs from the `type` property in the `manifest.json` file at runtime. In most cases, a CLI project of type `component` is still a runtime "application". For details on the `type` property in `manifest.json`, refer to the [manifest documentation](https://ui5.sap.com/#/topic/be0cf40f61184b358b5faedaec98b2da.html#loiobe0cf40f61184b358b5faedaec98b2da/section_sap_app).
> **Note:** The term `component` as used in the UI5 CLI project type differs from the `sap.app/type` property in the `manifest.json` file at runtime. In most cases, a CLI project of type `component` is still a runtime "application". For details on the `sap.app/type` property in `manifest.json`, refer to the [manifest documentation](https://ui5.sap.com/#/topic/be0cf40f61184b358b5faedaec98b2da.html#loiobe0cf40f61184b358b5faedaec98b2da/section_sap_app).

Projects of the `component` type are typical component-like UI5 applications. They usually run in a container-like root application, such as the SAP Fiori launchpad (FLP) sandbox, alongside other UI5 applications.
Projects of the `component` type cover a range of use cases beyond typical standalone UI5 applications:

- **Application components:** These are typical UI5 applications, designed to run in container-like application such as the SAP Fiori launchpad (FLP). These generally inherit from `sap.ui.core.UIComponent` (or a subclass) and define the `manifest.json` property `sap.app/type: application`.
- **Reusable UI components:** Provide UI elements or features that can be embedded in different contexts. These typically inherit from `sap.ui.core.UIComponent` and define the `manifest.json` property `sap.app/type: component`.
- **Faceless components:** Provide functionality without a user interface. These are defined with `manifest.json` property `sap.app/type: component` and inherit from `sap.ui.core.Component` (not `UIComponent`).

Please also refer to the [components documentation](https://ui5.sap.com/#/topic/958ead51e2e94ab8bcdc90fb7e9d53d0) for more details.

To allow multiple component projects to coexist in the same environment, each project is served under its own namespace, for example `/resources/my/bookstore/admin`. In contrast, `application`-type projects act as root projects and are served at `/`, without a namespace.

By default, component projects use the same directory structure as library projects: they include `src` and `test` directories in the root. The integrated server uses both directories. However, when you build the project, the `test` directory is ignored because it shouldn't be deployed to production environments. Both directories can have either a flat or a namespace structure. If you use a flat structure, the project namespace derives from the `"sap.app".id` property in the `manifest.json`.
By default, component projects use the same directory structure as library projects: they include `src` and `test` directories in the root. Both directories can have either a flat or a namespace structure. If you use a flat structure, the project namespace derives from the `"sap.app".id` property in the `manifest.json`.

A component project must contain both, a `Component.js` and a `manifest.json` file.

Unlike `application`-type projects, component projects typically don't have dedicated `index.html` files in their regular resources (`src/`). However, you can still run them standalone. You can do this by using a dedicated HTML file located in their test resources or by declaring a development dependency to an application-type project that can serve the component, such as the FLP sandbox.

Component projects support all [output styles](./CLI.md#ui5-build) that library projects currently support. This allows a deployment where you can omit the namespace from the final directory structure using the output style: `flat`.
Component projects support all [output styles](#build-output-style) that library projects currently support. This allows a deployment where you can omit the namespace from the final directory structure using the output style: `flat`.

For more details, see also [RFC 0018 Component Type](https://github.com/UI5/cli/blob/rfc-component-type/rfcs/0018-component-type.md#rfc-0018-component-type).

### application
Projects of the type `application` typically serve as the main or root project. In a project's dependency tree, there should be only one project of this type. If the system detects additional application projects, it ignores those that are further away from the root.
Projects of the `application` type typically serve as the main or root project. In a project's dependency tree, there shouldn't be more than one project of this type. If the system detects additional application projects, it ignores those that are further away from the root.

The source directory of an application (typically named `webapp`) is mapped to the virtual root path `/`.

Expand All @@ -38,7 +46,7 @@ An applications source directory may or may not contain a `Component.js` file. I
### library
UI5 libraries are often referred to as reuse-, custom- or [control libraries](https://github.com/SAP/openui5/blob/-/docs/controllibraries.md). They are a key component in sharing code across multiple projects in UI5.

A project of type `library` must have a source directory (typically named `src`). It may also feature a "test" directory. These directories are mapped to the virtual directories `/resources` for the sources and `/test-resources` for the test resources.
A project of the `library` type must have a source directory (typically named `src`). It may also feature a "test" directory. These directories are mapped to the virtual directories `/resources` for the sources and `/test-resources` for the test resources.

These directories should contain a directory structure representing the namespace of the library (e.g. `src/my/first/library`) to prevent name clashes between the resources of different libraries.

Expand All @@ -61,32 +69,27 @@ The _Output Style_ offers you control over your project's build output folder. N

In the table below you can find the available combinations of project type & output style.

| Project Type / Requested Output Style | Resulting Style |
|---|---|
| **application** | |
| `Default` | Root project is written `Flat`-style. ^1^ |
| `Flat` | Same as `Default`. |
| `Namespace` | Root project is written `Namespace`-style (resources are prefixed with the project's namespace). ^1^ |
| **component** | |
| `Default` | Root project is written `Namespace`-style. ^1^ |
| `Flat` | Root project is written `Flat`-style (without its namespace, logging warnings for resources outside of it). ^1^ |
| `Namespace` | Same as `Default`. |
| **library** | |
| `Default` | Root project is written `Namespace`-style. ^1^ |
| `Flat` | Root project is written `Flat`-style (without its namespace, logging warnings for resources outside of it). ^1^ |
| `Namespace` | Same as `Default`. |
| **theme-library** | |
| `Default` | Root project is written in the style of the sources (multiple namespaces). ^1^ |
| `Flat` | **Unsupported** ^2^ |
| `Namespace` | **Unsupported** ^2^ |
| **module** | |
| `Default` | Root project is written with the [configured paths](https://ui5.github.io/cli/v5/pages/Configuration/#available-path-mappings). ^1^ |
| `Flat` | **Unsupported** ^3^ |
| `Namespace` | **Unsupported** ^3^ |

^1^ The Output Style is only applied to the root project's output folder structure. Any dependencies included in the build would retain their `Default` output style.
^2^ Theme libraries in most cases have more than one namespace.
^3^ Modules have explicit path mappings configured and no namespace concept.
| Project Type | Requested Output Style | Resulting Style |
| :--- | :--- | :--- |
| **component** | `Default` | Root project is written `Namespace`-style.¹ |
| | `Flat` | Root project is written `Flat`-style (without its namespace, logging warnings for resources outside of it).¹ |
| | `Namespace` | Same as `Default`. |
| **application** | `Default` | Root project is written `Flat`-style.¹ |
| | `Flat` | Same as `Default`. |
| | `Namespace` | Root project is written `Namespace`-style (resources are prefixed with the project's namespace).¹ |
| **library** | `Default` | Root project is written `Namespace`-style.¹ |
| | `Flat` | Root project is written `Flat`-style (without its namespace, logging warnings for resources outside of it).¹ |
| | `Namespace` | Same as `Default`. |
| **theme-library** | `Default` | Root project is written in the style of the sources (multiple namespaces).¹ |
| | `Flat` | **Unsupported** ² |
| | `Namespace` | **Unsupported** ² |
| **module** | `Default` | Root project is written with the [configured paths](https://ui5.github.io/cli/v5/pages/Configuration/#available-path-mappings).¹ |
| | `Flat` | **Unsupported** ³ |
| | `Namespace` | **Unsupported** ³ |

¹ The Output Style is only applied to the root project's output folder structure. Any dependencies included in the build would retain their `Default` output style.
² Theme libraries in most cases have more than one namespace.
³ Modules have explicit path mappings configured and no namespace concept.


<div style="margin: 1rem 0;">
Expand Down
2 changes: 1 addition & 1 deletion packages/project/lib/build/TaskRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class TaskRunner {
buildDefinition = "./definitions/library.js";
break;
case "component":
buildDefinition = "./definitions/application.js";
buildDefinition = "./definitions/component.js";
break;
case "module":
buildDefinition = "./definitions/module.js";
Expand Down
128 changes: 128 additions & 0 deletions packages/project/lib/build/definitions/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {enhancePatternWithExcludes} from "./_utils.js";
import {enhanceBundlesWithDefaults} from "../../validation/validator.js";

/**
* Get tasks and their configuration for a given component project
*
* @private
* @param {object} parameters
* @param {object} parameters.project
* @param {object} parameters.taskUtil
* @param {Function} parameters.getTask
*/
export default function({project, taskUtil, getTask}) {
const tasks = new Map();
tasks.set("escapeNonAsciiCharacters", {
options: {
encoding: project.getPropertiesFileSourceEncoding(),
pattern: "/**/*.properties"
}
});

tasks.set("replaceCopyright", {
options: {
copyright: project.getCopyright(),
pattern: "/**/*.{js,json}"
}
});

tasks.set("replaceVersion", {
options: {
version: project.getVersion(),
pattern: "/**/*.{js,json}"
}
});

// Support rules should not be minified to have readable code in the Support Assistant
Copy link
Member

Choose a reason for hiding this comment

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

Support rules are AFAIK a concept for libraries, so I wonder why we also do this for applications. But as we do, I think we should also do it here to stay consistent.

const minificationPattern = ["/**/*.js", "!**/*.support.js"];
const minificationExcludes = project.getMinificationExcludes();
if (minificationExcludes.length) {
enhancePatternWithExcludes(minificationPattern, minificationExcludes, "/resources/");
}

tasks.set("minify", {
options: {
pattern: minificationPattern
}
});

tasks.set("enhanceManifest", {});

tasks.set("generateFlexChangesBundle", {});

const bundles = project.getBundles();
const existingBundleDefinitionNames =
bundles.map(({bundleDefinition}) => bundleDefinition.name).filter(Boolean);

const componentPreloadPaths = project.getComponentPreloadPaths();
const componentPreloadNamespaces = project.getComponentPreloadNamespaces();
const componentPreloadExcludes = project.getComponentPreloadExcludes();
if (componentPreloadPaths.length || componentPreloadNamespaces.length) {
tasks.set("generateComponentPreload", {
options: {
paths: componentPreloadPaths,
namespaces: componentPreloadNamespaces,
excludes: componentPreloadExcludes,
skipBundles: existingBundleDefinitionNames
}
});
} else {
// Default component preload
tasks.set("generateComponentPreload", {
options: {
namespaces: [project.getNamespace()],
excludes: componentPreloadExcludes,
skipBundles: existingBundleDefinitionNames
}
});
}

if (bundles.length) {
tasks.set("generateBundle", {
requiresDependencies: true,
taskFunction: async ({workspace, dependencies, taskUtil, options}) => {
const generateBundleTask = await getTask("generateBundle");
// Async resolve default values for bundle definitions and options
const bundlesDefaults = await enhanceBundlesWithDefaults(bundles, taskUtil.getProject());

return bundlesDefaults.reduce(async function(sequence, bundle) {
return sequence.then(function() {
return generateBundleTask.task({
workspace,
dependencies,
taskUtil,
options: {
projectName: options.projectName,
bundleDefinition: bundle.bundleDefinition,
bundleOptions: bundle.bundleOptions
}
});
});
}, Promise.resolve());
}
});
} else {
// No bundles defined. Just set task so that it can be referenced by custom tasks
tasks.set("generateBundle", {
taskFunction: null
});
}

tasks.set("generateVersionInfo", {
requiresDependencies: true,
options: {
rootProject: project,
pattern: "/resources/**/.library"
}
});

tasks.set("generateCachebusterInfo", {
options: {
signatureType: project.getCachebusterSignatureType(),
}
});

tasks.set("generateResourcesJson", {requiresDependencies: true});

return tasks;
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading