Skip to content

Ui5Library ​

Introduction ​

A Ui5Library is a frontend-only artifact in LaravelUi5 that encapsulates a reusable UI5 library developed outside the Laravel application. Typical use cases include formatting utilities, reusable UI components, or shared business logic intended to be consumed by multiple UI5 apps.

Each library is integrated into the Laravel app as part of a Ui5Module, and can later be discovered, versioned, and served through the LaravelUi5 registry.

πŸ“ Note
A module can contain either a UI5 app or a UI5 library β€” but never both.

Conceptual Overview ​

LaravelUi5 supports importing fully built UI5 libraries and wrapping them as native Laravel modules. This integration includes:

  • Direct access to all build assets (e.g., preload files, message bundles).
  • Rich metadata extracted from .library, package.json, and ui5.yaml.
  • Clean namespacing on both the backend (PHP) and frontend (JavaScript).

Unlike apps, libraries do not support subordinate artifacts such as cards, tiles, or reports. They serve purely as shared dependencies.

How to Generate ​

Use the following Artisan command to generate a new UI5 library:

bash
php artisan ui5:lib Charts

This assumes a source folder exists in one of the following forms:

plaintext
../ui5-charts-lib/                ← LaravelUi5 naming convention
../com.acme.charts/          ← SAP Easy UI5 convention

Before running the command, make sure to build the library via:

bash
npm install && npm run build

πŸ“ Scaffolding the source side with yo easy-ui5 When you generate the UI5 source project via SAP's Easy UI5 generator, it will ask "Would you like to omit the namespace in the src and test folder?" β€” answer Y. LaravelUi5 reads the built library from dist/resources/{namespace-as-path}/, which ui5 build produces correctly either way; but the flat src/ layout is what ui5:lib has been exercised against, and it keeps the source tree shallow. The namespace-folded src/ variant is untested with the LaravelUi5 generator β€” pick the flat one unless you have a reason not to.

Options ​

OptionDescription
--createScaffold a new library module (fails if it already exists)
--refreshRefresh metadata and assets from the source project
--no-buildSkip the UI5 build before importing assets (build runs by default)
--php-ns-prefixPHP namespace prefix (default: Pragmatiqu)
--js-ns-prefixJS namespace prefix (default: io.pragmatiqu)

⚠️ Pass --create or --refresh explicitly. Without either, the command only reports whether the module exists, names the flag to use, and writes nothing.

Output ​

Upon successful execution, the following artifacts are generated inside the Laravel project:

plaintext
ui5/Charts/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ ChartsLibrary.php         ← Library metadata class
β”‚   └── ChartsModule.php          ← Module wrapper
└── resources/ui5/                ← UI5 assets (preloads, messages, etc.)

The build assets are copied from the following folder:

plaintext
../ui5-charts-lib/dist/resources/com/acme/charts/

Metadata Resolution ​

LaravelUi5 reads library metadata from three locations in the source folder β€” but only one of them supplies the values that end up in the class.

ui5.yaml ​

Supplies the UI5 namespace, which is what tells the generator where to look for everything else:

yaml
metadata:
  name: com.acme.charts

.library XML ​

The real metadata source. The generator reads the built descriptor at dist/resources/{namespace-as-path}/.library and takes all five values from it:

.library elementBecomes
<name>NAMESPACE
<version>VERSION
<title>TITLE
<documentation>DESCRIPTION
<vendor>getVendor()

Because it reads the built file, a missing dist/ is a hard error naming the build command rather than a class full of placeholders: a Missing .library file error that names the project folder and the build script to run.

package.json ​

Supplies the build command the generator runs (and names in that error). The library's version reaches the class through .library, not from here β€” though the UI5 build is what copies it across, so the two agree by construction.

Class Structure ​

ChartsLibrary.php ​

Extends AbstractUi5Library and implements Ui5LibraryInterface. Identity is baked in as class constants at generate time β€” read from the source project, then written into the class:

php
use LaravelUi5\Core\Ui5\AbstractUi5Library;

class ChartsLibrary extends AbstractUi5Library
{
    public const string NAMESPACE   = 'com.acme.charts';
    public const string VERSION     = '1.2.0';
    public const string TITLE       = 'Charts';
    public const string DESCRIPTION = 'Shared charting controls.';

    public function getVendor(): string
    {
        return 'Acme GmbH';
    }
}

The matching getters β€” getNamespace(), getVersion(), getTitle(), getDescription() β€” come from the HasArtifactIdentity trait; they read the constants, they do not re-read ui5.yaml or package.json at runtime. A --refresh re-derives the values and rewrites the class.

All five values come from the built .library descriptor β€” see Metadata Resolution above.

getType() (returning ArtifactType::Library), getModule() and getSource() come from the base and are not re-declared.

⚠️ A library has no base/leaf split β€” and this class is rewritten. Unlike Ui5App, ui5:lib emits a single Library class and --refresh rewrites it in full, so anything you hand-add here is lost on the next refresh. That is safe by design: a library carries no developer-authored members β€” no OData schema, no manifest fragment, no access gate β€” so there is nothing a leaf would need to protect. The PHP namespace is the one exception; like ui5:app, --refresh reads it back out of the existing class and aborts rather than clobber it if it cannot be parsed.

ChartsModule.php ​

The namespace-keyed container. It returns the Library from getLibrary() as its root artifact and derives its own namespace from ChartsLibrary::NAMESPACE.

Unlike the Library class, the Module is written once at --create and never regenerated β€” because its getCards() / getTiles() / getActions() / … methods are where you register the module's sub-artifacts by hand, and a refresh would wipe those registrations. So the ownership line in a library module runs between the two files: the Library is the framework's, the Module is yours.

Module Integration ​

Each library is part of a domain-specific module. Modules are registered as a class-only array in your application's config/ui5.php β€” the registry derives the namespace from the module's root artifact (here, from ChartsLibrary::NAMESPACE):

php
// config/ui5.php
return [
    'modules' => [
        \Acme\Charts\ChartsModule::class,
    ],
];

No keyed slugs. The namespace is single-sourced from the Library class, and every asset URL is derived from it.

Best Practices ​

  • Keep each library focused on a single responsibility
  • Follow semantic versioning in package.json
  • Use consistent naming between the JS namespace, folder name, and PHP class
  • Avoid bundling business logic into libraries β€” delegate that to apps