|
| 1 | +# Creating a custom UI5 Web Components package |
| 2 | + |
| 3 | +This tutorial explains how to: |
| 4 | + - create an NPM package for your own UI5 Web Components |
| 5 | + - use UI5 Web Components' standard build tools: `@ui5/webcomponents-tools` |
| 6 | + - gain all `@ui5/webcomponents` capabilities such as HBS template support, i18n, theming, test setup, etc... |
| 7 | + |
| 8 | +*Note:* Whether you use `npm` or `yarn` is a matter of preference. |
| 9 | + |
| 10 | +## Step 1 - create an empty NPM package |
| 11 | + |
| 12 | +`npm init` |
| 13 | + |
| 14 | +or |
| 15 | + |
| 16 | +`yarn init` |
| 17 | + |
| 18 | +The name that you give to your package will be used by the UI5 Web Components tools as the namespace for resource registration. |
| 19 | + |
| 20 | +## Step 2 - add the UI5 Web Components packages as dependencies |
| 21 | + |
| 22 | +`npm i --save @ui5/webcomponents-base @ui5/webcomponents-theme-base @ui5/webcomponents-tools` |
| 23 | + |
| 24 | +or |
| 25 | + |
| 26 | +`yarn add @ui5/webcomponents-base @ui5/webcomponents-theme-base @ui5/webcomponents-tools` |
| 27 | + |
| 28 | +These 3 will serve as foundation for your own package and web components. |
| 29 | + |
| 30 | +Package | Description |
| 31 | +----------------|----------------------- |
| 32 | +`@ui5/webcomponents-base` | Base classes and Framework |
| 33 | +`@ui5/webcomponents-theme-base` | Base theming assets |
| 34 | +`@ui5/webcomponents-tools` | Build and configuration assets |
| 35 | + |
| 36 | +## Step 3 - run the package initialization script |
| 37 | + |
| 38 | +Run the initialization script, optionally with parameters from the following table: |
| 39 | + |
| 40 | +Parameter | Description | Default value |
| 41 | +----------|-------------|-------------- |
| 42 | +port | Dev server port | 8080 |
| 43 | +tag | The sample web component's tag name | ui5-demo |
| 44 | + |
| 45 | +For example: |
| 46 | + |
| 47 | +`npx wc-init-ui5-package` |
| 48 | + |
| 49 | +to get all the default values, or: |
| 50 | + |
| 51 | +`npx wc-init-ui5-package --port=8081 --tag=ui5-my-new-component` |
| 52 | + |
| 53 | +to change the port and the tag of the sample web component that will be created in the empty package. |
| 54 | + |
| 55 | +The initialization script will set the directory structure and copy a couple of files. |
| 56 | + |
| 57 | +## Step 4 - run the dev server and test the build |
| 58 | + |
| 59 | +To run the dev server: |
| 60 | + |
| 61 | +`npm run start` |
| 62 | + |
| 63 | +or |
| 64 | + |
| 65 | +`yarn start` |
| 66 | + |
| 67 | +and once the project is built for the first time, open in your browser: |
| 68 | + |
| 69 | +`http://localhost:8080/test-resources/pages/index.html` |
| 70 | + |
| 71 | +*Note:* If you chose a different `port` earlier, change `8080` to its value. |
| 72 | + |
| 73 | +You can also run the tests: |
| 74 | + |
| 75 | +`npm run test` |
| 76 | + |
| 77 | +or |
| 78 | + |
| 79 | +`yarn test` |
| 80 | + |
| 81 | +and the production build: |
| 82 | + |
| 83 | +`npm run build` |
| 84 | + |
| 85 | +or |
| 86 | + |
| 87 | +`yarn build`. |
| 88 | + |
| 89 | +That's it! |
| 90 | + |
| 91 | +## Understanding the project structure |
| 92 | + |
| 93 | +### package.json |
| 94 | + |
| 95 | +The initialization script will create several NPM scripts for you in `package.json`. |
| 96 | + |
| 97 | +Task | Purpose |
| 98 | +-----|------- |
| 99 | +clean | Deletes the `dist/` directory with the build output |
| 100 | +build | Production build to the `dist/` directory |
| 101 | +lint | Run a static code scan with `eslint` |
| 102 | +start | Build the project for development and run the dev server |
| 103 | +test | Run the test specs from the `test/specs/` directory |
| 104 | +create-ui5-element | Create an empty web component with the given name |
| 105 | + |
| 106 | +### Files in the main directory |
| 107 | + |
| 108 | +The initialization script will create several files in your package's main directory. |
| 109 | + |
| 110 | +File | Purpose |
| 111 | +------|------- |
| 112 | +.eslintignore | Excludes the `dist/` and `test/` directories from static code scans |
| 113 | +package-scripts.js | An [nps](https://www.npmjs.com/package/nps) package scripts configuration file |
| 114 | +bundle.esm.js | Entry point for the ES6 bundle, used for development and tests. Intended for modern browsers. |
| 115 | +bundle.es5.js | Entry point for the ES5 bundle, used for development and tests. Intended for IE11 only. |
| 116 | + |
| 117 | +You'll likely only need to change `bundle.esm.js` to import your new components there. |
| 118 | + |
| 119 | +### The `config/` directory |
| 120 | + |
| 121 | +The `config/` directory serves as a central place for most build and test tools' configuration assets. Normally you |
| 122 | +don't need to change any files there. |
| 123 | + |
| 124 | +### The `src/` directory |
| 125 | + |
| 126 | +This is where you'll do most of the development. |
| 127 | +Let's see the necessary files for a `ui5-demo` component. |
| 128 | + |
| 129 | +#### Class and template files |
| 130 | + |
| 131 | +The main files describing a web component are: |
| 132 | + |
| 133 | +File | Purpose |
| 134 | +------------|------------- |
| 135 | +`src/Demo.js` | Web component class |
| 136 | +`src/Demo.hbs` | Handlebars template |
| 137 | + |
| 138 | +In order to understand how a UI5 Web Component works and what lies behind these two files, make sure you check the |
| 139 | +[Developing Web Components](./Developing%20Web%20Components.md) section of the documentation. |
| 140 | + |
| 141 | +For the purposes of this tutorial however, you don't need to understand their internals, as they are automatically generated by the |
| 142 | +script and are in a working state already. |
| 143 | + |
| 144 | +#### Theming-related files |
| 145 | + |
| 146 | +A single set of CSS rules will be used for all themes. The only difference between themes may be the values of CSS Variables. |
| 147 | +Some CSS Vars, such as `--sapBackgroundColor` and `--sapTextColor` are standard and automatically managed by the framework. |
| 148 | +In addition, you can define your own CSS Vars and provide different values for them for the different themes. Set these CSS Vars in the |
| 149 | +`parameters-bundle.css` file for each theme. These files are the entry points for the styles build script. |
| 150 | + |
| 151 | +File | Purpose |
| 152 | +------------|------------- |
| 153 | +`src/themes/Demo.css` | All CSS rules for the web component, same for all themes. Will be inserted in the shadow root. |
| 154 | +`src/themes/sap_belize/parameters-bundle.css` | Values for the component-specific CSS Vars for the `sap_belize` theme. |
| 155 | +`src/themes/sap_belize_hcb/parameters-bundle.css` | Values for the component-specific CSS Vars for the `sap_belize_hcb` theme. |
| 156 | +`src/themes/sap_fiori_3/parameters-bundle.css` | Values for the component-specific CSS Vars for the `sap_fiori_3` theme. |
| 157 | +`src/themes/sap_fiori_3_dark/parameters-bundle.css` | Values for the component-specific CSS Vars for the `sap_fiori_3_dark` theme. |
| 158 | + |
| 159 | +*Note:* It's up to you whether to put the CSS Vars directly in the `parameters-bundle.css` files for the different themes or to |
| 160 | +import them from separate `.css` files. You could have for example a `Demo-params.css` file for each theme and |
| 161 | +import it into the `parameters-bundle.css` file: `@import "Demo-params.css";`. |
| 162 | + |
| 163 | +Again, to know more about how these files work, you could have a look at the [Developing Web Components](./Developing%20Web%20Components.md#css) section of the documentation. |
| 164 | + |
| 165 | +#### i18n files |
| 166 | + |
| 167 | +You can define translatable texts as key-value pairs, separated by `=` in the `messagebundle.properties` file. Then you can provide translations for as many languages |
| 168 | +as needed. |
| 169 | + |
| 170 | +File | Purpose |
| 171 | +------------|------------- |
| 172 | +`src/i18n/messagebundle.properties` | Source file for all translatable texts |
| 173 | +`src/i18n/messagebundle_de.properties` | Translations in German |
| 174 | +`src/i18n/messagebundle_en.properties` | Translations in English |
| 175 | +etc... | etc... |
| 176 | + |
| 177 | +Let's have a look at the sample `messagebundle.properties` file, generated by the script. |
| 178 | + |
| 179 | +``` |
| 180 | +#please wait text for the demo component |
| 181 | +PLEASE_WAIT=wait |
| 182 | +``` |
| 183 | + |
| 184 | +Here's where you define all i18n texts, optionally with comments for the translators (`# Comment`). |
| 185 | + |
| 186 | +And now let's have a look at a sample file with translations, for example `messagebundle_es.properties`: |
| 187 | + |
| 188 | +``` |
| 189 | +PLEASE_WAIT=Espere |
| 190 | +``` |
| 191 | + |
| 192 | +#### Assets (additional themes, i18n texts, etc...) |
| 193 | + |
| 194 | +File | Purpose |
| 195 | +------------|------------- |
| 196 | +`src/Assets.js` | Entry point for your package's assets |
| 197 | + |
| 198 | +This module imports all base assets (such as `CLDR` and the base theme parameters), but also your own |
| 199 | +package's assets (i18n and package-specific theme parameters). |
| 200 | +Users of your package will have to import this module in their production applications in order to get additional themes support |
| 201 | +and i18n support. |
| 202 | + |
| 203 | +*Note:* For easier development and testing, `Assets.js` is also imported in the dev/test bundle `bundle.esm.js` by the initialization script. |
| 204 | + |
| 205 | +### The `test/` directory |
| 206 | + |
| 207 | +File | Purpose |
| 208 | +------------|------------- |
| 209 | +`test/pages/*` | Simple `.html` pages used for development and tests |
| 210 | +`src/specs/*` | Test specs, based on [WDIO](https://www.npmjs.com/package/wdio). They use the test pages for setup. |
| 211 | + |
| 212 | +You can execute all specs by running `yarn test` or `npm run test`. |
| 213 | + |
| 214 | +## Public consumption of your custom UI5 Web Components package |
| 215 | + |
| 216 | +Once you've developed your package and published it to NPM, application developers can import from the `dist/` directory |
| 217 | +of your package any of your Web Components, and optionally the `Assets.js` module, if they want additional themes and i18n. |
| 218 | + |
| 219 | +For example, if your package is called `my-ui5-webcomponents`, users will install it by: |
| 220 | + |
| 221 | +``` |
| 222 | +npm i my-ui5-webcomponents --save |
| 223 | +``` |
| 224 | + |
| 225 | +and then use it by: |
| 226 | + |
| 227 | +```js |
| 228 | +import "my-ui5-webcomponents/Assets.js"; // optional |
| 229 | +import "my-ui5-webcomponents/dist/Demo.js"; // for ui5-demo from this tutorial |
| 230 | +import "my-ui5-webcomponents/dist/SomeOtherComponent.js"; |
| 231 | +import "my-ui5-webcomponents/dist/YetAnotherComponent.js"; |
| 232 | +``` |
| 233 | + |
| 234 | +*Note about assets:* The `Assets.js` module may import some relatively big `JSON` modules, containing CLDR data, i18n texts and theming parameters. |
| 235 | +Therefore, it is recommended to guide your package's users to bundle their apps efficiently by configuring `rollup` or `webpack`, |
| 236 | +depending on their choice, to not include the content of the assets `JSON` modules in their javascript bundle. |
| 237 | +See the [Efficient asset bundling](../Assets.md#bundling) section of our [Assets](../Assets.md) documentation for details. |
0 commit comments