19. Migrating Legacy Projects

Migrating Legacy SAPUI5 Projects to Modern Tooling


Why migrate?

  • Legacy projects often use outdated UI5 versions, lack support for modern tools (TypeScript, UI5 Tooling, Fiori Tools), have poor test coverage, and are hard to maintain.
  • Migration simplifies maintenance, speeds up development, improves code quality, and enables CI/CD integration.

1. Audit the current state

Example:
Before:

  • All code in one /webapp folder, all controllers in one directory, no module separation.
  • Uses outdated Component-preload.js, no ui5.yaml.

After:

  • Clear separation: /src for new code, /webapp for legacy, ui5.yaml present, controllers organized in folders.

2. Switch to UI5 Tooling

Example ui5.yaml:

specVersion: '3.0'
metadata:
  name: my.legacy.app
type: application
resources:
  configuration:
    paths:
      webapp: webapp

Command:

npm install --save-dev @ui5/cli
ui5 build

3. Introduce TypeScript

Before:
LegacyController.controller.js

sap.ui.define([
  "sap/ui/core/mvc/Controller"
], function(Controller) {
  return Controller.extend("my.legacy.app.controller.LegacyController", {
    onInit: function() {
      // ...
    }
  });
});

After:
NewFancyController.ts

import Controller from "sap/ui/core/mvc/Controller";

export default class NewFancyController extends Controller {
  onInit(): void {
    // ...
  }
}

tsconfig.json — see 14. TypeScript


4. Refactor architecture

Before:
Each controller has its own utilities, code duplication.

After:
BaseController.ts

import Controller from "sap/ui/core/mvc/Controller";

export default class BaseController extends Controller {
  showError(message: string) {
    sap.m.MessageBox.error(message);
  }
}

MyPage.controller.ts

import BaseController from "./BaseController";

export default class MyPage extends BaseController {
  onError() {
    this.showError("Something went wrong");
  }
}

5. UI migration

Before:
Custom table in XML:

<Table>
  <columns>
    <Column><Text text="ID"/></Column>
    <Column><Text text="Name"/></Column>
  </columns>
  <items>
    <ColumnListItem>
      <cells>
        <Text text="{id}"/>
        <Text text="{name}"/>
      </cells>
    </ColumnListItem>
  </items>
</Table>

After:
Using SmartTable (Fiori Elements):

<smartTable:SmartTable
  entitySet="Products"
  tableType="Table"
  useExportToExcel="true"
  useVariantManagement="true"
  useTablePersonalisation="true"
  header="Products"
  showRowCount="true"/>

6. Introduce testing

Before:
No tests.

After:
/webapp/test/unit/model/formatter.js

QUnit.module("formatter", function () {
  QUnit.test("should return upper case", function (assert) {
    var sText = formatter.upperCase("test");
    assert.strictEqual(sText, "TEST");
  });
});

E2E:
/e2e/test.spec.js (wdi5)

describe("App", () => {
  it("should open the main page", async () => {
    await browser.url("/");
    const title = await browser.$("id=mainTitle");
    expect(await title.getText()).toBe("Main");
  });
});

7. Automation and CI/CD

Example GitHub Actions workflow:

name: UI5 CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install dependencies
        run: npm install
      - name: Build UI5 app
        run: ui5 build
      - name: Run unit tests
        run: npm test

Best practices

  • Migrate step by step: don’t try to rewrite everything at once. Start with infrastructure, then migrate individual modules.
  • Cover changes with tests: this reduces regression risks.
  • Use generators: for new modules and apps, use yo @sap/fiori.
  • Document architectural decisions: helps with onboarding new developers.
  • Remove legacy code: don’t be afraid to get rid of outdated utilities and patterns.

Pitfalls

Before:
Custom component that doesn’t work after UI5 update.

Solution:

  • Check the UI5 changelog.
  • Rewrite the component using standard APIs.
  • Add tests for critical functions.


Migration is not just about new tools, but about development culture:

  • Write tests for every new module.
  • Use linters and autotests.
  • Document architectural decisions.

Migration is not a one-time task, but a process. The sooner you start, the easier it will be to maintain the project in the future.


See also