From c1509fb4e3ef86d0bccc2eade2d5f43cff72b482 Mon Sep 17 00:00:00 2001 From: Merlin Beutlberger Date: Tue, 3 Apr 2018 16:59:57 +0200 Subject: [PATCH 1/3] [RFC] 0001 Type Extensibility --- rfcs/0001-type-extensibility.md | 74 +++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 rfcs/0001-type-extensibility.md diff --git a/rfcs/0001-type-extensibility.md b/rfcs/0001-type-extensibility.md new file mode 100644 index 0000000000..5d549b15c5 --- /dev/null +++ b/rfcs/0001-type-extensibility.md @@ -0,0 +1,74 @@ +- Start Date: 2018-04-03 +- RFC PR: [#4](https://github.com/SAP/ui5-tooling/pull/4) +- Issue: - +- Affected components + + [x] [ui5-builder](https://github.com/SAP/ui5-builder) + + [ ] [ui5-server](https://github.com/SAP/ui5-server) + + [ ] [ui5-cli](https://github.com/SAP/ui5-cli) + + [ ] [ui5-fs](https://github.com/SAP/ui5-fs) + + [x] [ui5-project](https://github.com/SAP/ui5-project) + + [ ] [ui5-logger](https://github.com/SAP/ui5-logger) + +# RFC 0001 Type Extensibility +## Summary +Add a feature to customize how a specific UI5 project is being built. + +## Motivation +Currently the UI5 build is only capable of building UI5 projects of types "application" and "library" with a fixed set of tasks it executes. + +A UI5 project (for example a library) may want to add or modify build steps (for example execute custom bundling). For this, an extensibility mechanism is needed. + +Multiple UI5 projects may require the same kind of "customized" build. Therefore reuse should be possible. + +## Detailed design +### Extensibility of types +Leverage the existing mechanism of types (currently for application and library), allow for a custom type and do the necessary adaption via regular JS language features (i.e. object-orientation, deriving and overriding). + +The `AbstractBuilder` (as well as any subclass-implementation) offers a set of functions which can be overwritten. + +#### Combined list of tasks executed by application- and library types +- replaceCopyright +- replaceVersion +- buildThemes +- generateLibraryPreload +- createDebugFiles +- uglify +- generateFlexChangesBundle +- generateManifestBundle +- generateAppPreload +- generateStandaloneAppBundle +- generateVersionInfo + +#### Functions of the `AbstractBuilder` ("Phases") +1. preprocess() + - replaceCopyright + - replaceVersion +1. process() + - createDebugFiles() + - buildThemes() +1. bundle() +1. postprocess() / optimize() + - uglify() + +A custom types `Builder` module shall extend another types builder or the generic `AbstractBuilder`: +```js +class MyCustomBuilder extends AbstractBuilder { + bundle() { + super.bundle(); + myCustomBundle(); + } +} +``` + +### Collecting and applying type extensions + +## How we teach this +TBD + +## Drawbacks +TBD + +## Alternatives +There are ways to consume (and thereby possibly adapt) the existing tooling through its API via taskrunners such as grunt or gulp, or using a custom node.js script. But this offers only limited possibilities, especially when it comes to building transient dependencies. + +## Unresolved questions From 4e1252f28ede88b3731e874f527302a1a694fb1e Mon Sep 17 00:00:00 2001 From: Merlin Beutlberger Date: Tue, 3 Apr 2018 18:06:30 +0200 Subject: [PATCH 2/3] Add information about type extension declaration and application --- rfcs/0001-type-extensibility.md | 49 ++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/rfcs/0001-type-extensibility.md b/rfcs/0001-type-extensibility.md index 5d549b15c5..4c5d10457c 100644 --- a/rfcs/0001-type-extensibility.md +++ b/rfcs/0001-type-extensibility.md @@ -50,7 +50,7 @@ The `AbstractBuilder` (as well as any subclass-implementation) offers a set of f 1. postprocess() / optimize() - uglify() -A custom types `Builder` module shall extend another types builder or the generic `AbstractBuilder`: +A custom types `Builder`-module shall extend another types builder or the generic `AbstractBuilder` and overwrite relevant functions: ```js class MyCustomBuilder extends AbstractBuilder { bundle() { @@ -60,7 +60,54 @@ class MyCustomBuilder extends AbstractBuilder { } ``` +### Generic handling of extension +A "Type Extension" will be only one way to extend the UI5 Build and Development Tooling. Other possible extensions include "Shims" (see RFC 0002), server middlewares, translators. + +Therefore a somewhat generic concept for dealing with extensions is needed. + +To separate "UI5 Projects" (i.e. things that represent UI5-artifacts for the browser) from tooling specific things like "extensions", an additional attribute "kind" is added to the ui5.yaml. + + +#### Example type extension +```yaml +specVersion: "0.1" +kind: extension +type: project-type +metadata: + name: my-custom-library +``` + +#### Example library +```yaml +specVersion: "0.1" +kind: project +type: my-custom-library +metadata: + name: my.application +``` + +The `kind` attribute defaults to `project`. + ### Collecting and applying type extensions +A type extension might be a standalone module or part of a project. In the above "type extension"/"library" example, the library declares a dependency to the type extension module. `ui5-project` should resolve the dependency, identify it as an extension and run the appropriate formatter/type for the extension type. This will then add the type as "my-custom-library" to the type repository. + +If the type extension is part of a project, the single `ui5.yaml` for above example looks like this: + +```yaml +specVersion: "0.1" +kind: project +type: my-custom-library +metadata: + name: my.application +---- +specVersion: "0.1" +kind: extension +type: project-type +metadata: + name: my-custom-library +``` + +In this case the type extension is no dependency of any kind but automatically collected and processed with the processing of the project. ## How we teach this TBD From a63033f5cdeb9a5a23b3ca5df53eca8890db44cf Mon Sep 17 00:00:00 2001 From: Merlin Beutlberger Date: Thu, 12 Apr 2018 17:31:00 +0200 Subject: [PATCH 3/3] [RFC] Remove build phases As discussed today between @matz3, @tommyvinhlam, @codeworrior, @randombyte Build phases would allow for more precise extensibility of a types build execution. Mainly scenarios where only a single task should be replaced or added could overwrite one of the build phases to hook in-between of certain sets of tasks. Instead, they will have to overwrite the whole build function containing all tasks. The main reason for this decision is the lack of known extensibility use-cases. Therefore we do not want to decide on the naming and semantics of any build phases yet as changing them later on will hardly be possible. --- rfcs/0001-type-extensibility.md | 36 ++++++--------------------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/rfcs/0001-type-extensibility.md b/rfcs/0001-type-extensibility.md index 4c5d10457c..0426cf9efc 100644 --- a/rfcs/0001-type-extensibility.md +++ b/rfcs/0001-type-extensibility.md @@ -22,40 +22,16 @@ Multiple UI5 projects may require the same kind of "customized" build. Therefore ## Detailed design ### Extensibility of types -Leverage the existing mechanism of types (currently for application and library), allow for a custom type and do the necessary adaption via regular JS language features (i.e. object-orientation, deriving and overriding). - -The `AbstractBuilder` (as well as any subclass-implementation) offers a set of functions which can be overwritten. - -#### Combined list of tasks executed by application- and library types -- replaceCopyright -- replaceVersion -- buildThemes -- generateLibraryPreload -- createDebugFiles -- uglify -- generateFlexChangesBundle -- generateManifestBundle -- generateAppPreload -- generateStandaloneAppBundle -- generateVersionInfo - -#### Functions of the `AbstractBuilder` ("Phases") -1. preprocess() - - replaceCopyright - - replaceVersion -1. process() - - createDebugFiles() - - buildThemes() -1. bundle() -1. postprocess() / optimize() - - uglify() +Leverage the existing mechanism of types (currently for application and library), allow for a custom type and do the necessary adaption via regular JavaScript language features (i.e. object-orientation, deriving and overriding). + +The `AbstractBuilder` (as well as any subclass-implementation) offers a set of functions which can be overwritten. Mainly the `build` function. A custom types `Builder`-module shall extend another types builder or the generic `AbstractBuilder` and overwrite relevant functions: ```js class MyCustomBuilder extends AbstractBuilder { - bundle() { - super.bundle(); - myCustomBundle(); + build() { + super.build(); + myCustomBuildTask(); } } ```