Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 internal/documentation/docs/pages/Server.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The remote-connections warning (when `--accept-remote-connections` is used) is w
## Standard Middleware

::: info Removed Middleware
The `serveThemes` middleware has been removed in UI5 CLI v5. Theme compilation is now handled by the `buildThemes` build task, which pre-compiles all theme CSS files. The resulting CSS files (including `library.css`, `library-RTL.css`, `library-parameters.json`, and CSS Variables resources) are served via the `serveResources` middleware, providing the same functionality with better performance through build-time compilation and caching.
The `serveThemes` middleware has been removed in UI5 CLI v5. Theme compilation is now handled by the `buildThemes` build task, which pre-compiles all theme CSS files. The resulting CSS files (including `library.css`, `library-RTL.css`, `library-parameters.json`) are served via the `serveResources` middleware, providing the same functionality with better performance through build-time compilation and caching.

The `testRunner` middleware has also been removed in UI5 CLI v5. The QUnit TestRunner (`testrunner.html`, `testrunner.css`, `TestRunner.js`) is now provided by the UI5 framework (`sap.ui.core`) and is served via the `serveResources` middleware.

Expand Down
9 changes: 9 additions & 0 deletions internal/documentation/docs/updates/migrate-v5.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Or update your global install via: `npm i --global @ui5/cli@next`

- **@ui5/cli: `ui5 serve` renders a status banner in interactive terminals**

- **@ui5/cli: Option `--experimental-css-variables` has been removed**


## Node.js and npm Version Support

Expand Down Expand Up @@ -320,6 +322,13 @@ Update your `ui5.yaml` configuration to reference an existing middleware instead
| `serveThemes` | CSS files pre-built by `buildThemes` task and served via `serveResources` | `serveResources` |
| `testRunner` | TestRunner resources served via `serveResources` from the UI5 framework | `serveResources` |

## Removal of `--experimental-css-variables`

The SAP Theme Designer can create custom themes based on CSS variables instead of LESS variables. To establish a consistent and standardized approach to theme customization, this feature will no longer be supported in UI5 CLI.

With UI5 CLI v5, the `--experimental-css-variables` option has therefore been removed for the `ui5 build` command. For custom theme creation with CSS variables, please check out the **SAP Theme Designer**.


## Learn More

- [Project: Type `component`](../pages/Project#component)
Expand Down
33 changes: 2 additions & 31 deletions packages/builder/lib/processors/themeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@ export class ThemeBuilder {
* @param {@ui5/fs/Resource[]} resources Library files
* @param {object} [options] Build options
* @param {boolean} [options.compress=false] Compress build output (CSS / JSON)
* @param {boolean} [options.cssVariables=false] Generates the CSS variables
* (css-variables.css, css-variables.source.less) and the skeleton for a theme
* (library-skeleton.css, [library-skeleton-RTL.css])
* @returns {Promise<@ui5/fs/Resource[]>} Resolving with array of created files
*/
build(resources, {compress = false, cssVariables = false} = {}) {
build(resources, {compress = false} = {}) {
const files = [];

const compile = (resource) => {
Expand All @@ -61,7 +58,6 @@ export class ThemeBuilder {
compiler: {
compress
},
cssVariables
}).then((result) => {
const themeDir = posixPath.dirname(resource.getPath());

Expand All @@ -81,27 +77,6 @@ export class ThemeBuilder {
});

files.push(libCss, libCssRtl, libParams);

if (cssVariables) {
const libCssVarsSource = new Resource({
path: themeDir + "/css_variables.source.less",
string: result.cssVariablesSource
});
const libCssVars = new Resource({
path: themeDir + "/css_variables.css",
string: result.cssVariables
});
const libCssSkel = new Resource({
path: themeDir + "/library_skeleton.css",
string: result.cssSkeleton
});
const libCssSkelRtl = new Resource({
path: themeDir + "/library_skeleton-RTL.css",
string: result.cssSkeletonRtl
});

files.push(libCssVarsSource, libCssVars, libCssSkel, libCssSkelRtl);
}
}, (err) => {
log.error(`Error while compiling ${resource.getPath()}: ${err.message}`);
throw err;
Expand Down Expand Up @@ -130,9 +105,6 @@ export class ThemeBuilder {
* @public
* @typedef {object} ThemeBuilderOptions
* @property {boolean} [compress=false] Compress build output (CSS / JSON)
* @property {boolean} [cssVariables=false] Generates the CSS variables
* (css-variables.css, css-variables.source.less) and the skeleton for a theme
* (library-skeleton.css, [library-skeleton-RTL.css])
*/

/**
Expand All @@ -156,12 +128,11 @@ export default async function({
fs,
options = {}
}) {
const {compress, cssVariables} =
const {compress} =
/** @type {module:@ui5/builder/processors/ThemeBuilder~ThemeBuilderOptions} */ (options);
const themeBuilder = new ThemeBuilder({fs});
return themeBuilder.build(resources, {
compress,
cssVariables
}).then((files) => {
themeBuilder.clearCache();
return files;
Expand Down
4 changes: 0 additions & 4 deletions packages/builder/lib/tasks/buildThemes.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,12 @@ async function buildThemeInWorker(taskUtil, options, transferList) {
* @param {string} [parameters.options.librariesPattern] Search pattern for .library files
* @param {string} [parameters.options.themesPattern] Search pattern for sap.ui.core theme folders
* @param {boolean} [parameters.options.compress=true]
* @param {boolean} [parameters.options.cssVariables=false]
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
*/
export default async function({
workspace, dependencies, taskUtil,
options: {
projectName, inputPattern, librariesPattern, themesPattern, compress,
cssVariables
}
}) {
const combo = new ReaderCollectionPrioritized({
Expand Down Expand Up @@ -205,7 +203,6 @@ export default async function({
themeResources: await serializeResources([themeRes]),
options: {
compress,
cssVariables: !!cssVariables,
},
}, [port2]);

Expand All @@ -226,7 +223,6 @@ export default async function({
fs: fsInterface(combo),
options: {
compress,
cssVariables: !!cssVariables,
}
});
}
Expand Down
111 changes: 0 additions & 111 deletions packages/builder/lib/tasks/generateThemeDesignerResources.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,6 @@ import ReaderCollectionPrioritized from "@ui5/fs/ReaderCollectionPrioritized";
import Resource from "@ui5/fs/Resource";
import fsInterface from "@ui5/fs/fsInterface";

/**
* Returns a relative path from the given themeFolder to the root namespace.
*
* When combining the given themeFolder with the returned relative path it
* resolves to "/resources/". However the "/resources/" part is not important
* here as it doesn't exist within the theming engine environment where the
* UI5 resources are part of a "UI5" folder (e.g. "UI5/sap/ui/core/") that
* is next to a "Base" folder.
*
* @example
* getPathToRoot("/resources/sap/ui/foo/themes/base")
* > "../../../../../"
*
* @param {string} themeFolder Virtual path including /resources/
* @returns {string} Relative path to root namespace
*/
function getPathToRoot(themeFolder) {
// -2 for initial "/"" and "resources/"
return "../".repeat(themeFolder.split("/").length - 2);
}

/**
* Generates an less import statement for the given <code>filePath</code>
*
* @param {string} filePath The path to the desired file
* @returns {string} The less import statement
*/
function lessImport(filePath) {
return `@import "${filePath}";\n`;
}

function generateLibraryDotTheming({namespace, version, hasThemes}) {
const dotTheming = {
sEntity: "Library",
Expand All @@ -53,7 +22,6 @@ function generateLibraryDotTheming({namespace, version, hasThemes}) {
dotTheming.aFiles = [
"library",
"global", // Additional entry compared to UI5 root .theming
"css_variables",
];
}
if (!hasThemes) {
Expand Down Expand Up @@ -119,82 +87,6 @@ async function generateThemeDotTheming({workspace, combo, themeFolder}) {
return newDotThemingResource;
}

async function createCssVariablesLessResource({workspace, combo, themeFolder}) {
const pathToRoot = getPathToRoot(themeFolder);
const cssVariablesSourceLessFile = "css_variables.source.less";
const cssVariablesLessFile = "css_variables.less";

// posix as it is a virtual path (separated with /)
const themeName = posixPath.basename(themeFolder);
// The "base" theme of the baseLib is called "baseTheme"
const baseLibThemeName = themeName === "base" ? "baseTheme" : themeName;

// Some themes do not have a base.less file (e.g. sap_hcb)
const hasBaseLess = !!(await combo.byPath(`/resources/sap/ui/core/themes/${themeName}/base.less`));

let cssVariablesLess =
`/* NOTE: This file was generated as an optimized version of "${cssVariablesSourceLessFile}" \
for the Theme Designer. */\n\n`;

if (themeName !== "base") {
const cssVariablesSourceLessResource = await workspace.byPath(
posixPath.join(themeFolder, cssVariablesSourceLessFile)
);

if (!cssVariablesSourceLessResource) {
throw new Error(`Could not find file "${cssVariablesSourceLessFile}" in theme "${themeFolder}"`);
}

const cssVariablesSourceLess = await cssVariablesSourceLessResource.getString();

cssVariablesLess += lessImport(`../base/${cssVariablesLessFile}`);
cssVariablesLess += `
/* START "${cssVariablesSourceLessFile}" */
${cssVariablesSourceLess}
/* END "${cssVariablesSourceLessFile}" */

`;
}

if (hasBaseLess) {
cssVariablesLess += lessImport(`${pathToRoot}../Base/baseLib/${baseLibThemeName}/base.less`);
}
cssVariablesLess += lessImport(`${pathToRoot}sap/ui/core/themes/${themeName}/global.less`);

return new Resource({
path: posixPath.join(themeFolder, cssVariablesLessFile),
string: cssVariablesLess
});
}

async function generateCssVariablesLess({workspace, combo, namespace}) {
let cssVariablesSourceLessResourcePattern;
if (namespace) {
// In case of a library only check for themes directly below the namespace
cssVariablesSourceLessResourcePattern = `/resources/${namespace}/themes/*/css_variables.source.less`;
} else {
// In case of a theme-library check for all "themes"
cssVariablesSourceLessResourcePattern = `/resources/**/themes/*/css_variables.source.less`;
}

const cssVariablesSourceLessResource = await workspace.byGlob(cssVariablesSourceLessResourcePattern);

const hasCssVariables = cssVariablesSourceLessResource.length > 0;

if (hasCssVariables) {
await Promise.all(
cssVariablesSourceLessResource.map(async (cssVariableSourceLess) => {
const themeFolder = posixPath.dirname(cssVariableSourceLess.getPath());
log.verbose(`Generating css_variables.less for theme ${themeFolder}`);
const r = await createCssVariablesLessResource({
workspace, combo, themeFolder
});
return await workspace.write(r);
})
);
}
}

/**
* @public
* @module @ui5/builder/tasks/generateThemeDesignerResources
Expand Down Expand Up @@ -311,7 +203,4 @@ export default async function({workspace, dependencies, options}) {
await Promise.all(
libraryLessResources.map((resource) => workspace.write(resource))
);

// css_variables.less
await generateCssVariablesLess({workspace, combo, namespace});
}

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.

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