@eui/cli 22.0.0-alpha.20 → 22.0.0-alpha.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +303 -90
  2. package/lib/app-utils/build.js +26 -0
  3. package/lib/app-utils/serve.js +32 -0
  4. package/lib/build.js +28 -7
  5. package/lib/cli.js +16 -2
  6. package/lib/config.js +10 -1
  7. package/lib/skeletons/_angular/base/package.json +3 -2
  8. package/lib/skeletons/_angular/base-mobile/package.json +1 -1
  9. package/lib/skeletons/_angular/options/eds/src/app/app.component.html +35 -0
  10. package/lib/skeletons/_angular/options/eds/src/app/app.component.spec.ts +56 -0
  11. package/lib/skeletons/_angular/options/eds/src/app/app.component.ts +44 -0
  12. package/lib/skeletons/_angular/options/eds/src/index.html +21 -0
  13. package/lib/skeletons/_angular/options/pnpm/package.json +97 -47
  14. package/lib/skeletons/_react/base/README.md +65 -0
  15. package/lib/skeletons/_react/base/eslint.config.mjs +17 -0
  16. package/lib/skeletons/_react/base/gitignore_TO_REPLACE +34 -0
  17. package/lib/skeletons/_react/base/index.html +13 -0
  18. package/lib/skeletons/_react/base/mock/app/models/user.js +6 -0
  19. package/lib/skeletons/_react/base/mock/app/routes/index.js +5 -0
  20. package/lib/skeletons/_react/base/mock/app/routes/user_routes.js +44 -0
  21. package/lib/skeletons/_react/base/mock/db/db.json +10 -0
  22. package/lib/skeletons/_react/base/mock/server.js +23 -0
  23. package/lib/skeletons/_react/base/package.json +29 -0
  24. package/lib/skeletons/_react/base/public/.gitkeep +0 -0
  25. package/lib/skeletons/_react/base/src/App.tsx +73 -0
  26. package/lib/skeletons/_react/base/src/main.tsx +30 -0
  27. package/lib/skeletons/_react/base/src/pages/about.tsx +27 -0
  28. package/lib/skeletons/_react/base/src/pages/home.tsx +50 -0
  29. package/lib/skeletons/_react/base/src/routes.ts +18 -0
  30. package/lib/skeletons/_react/base/src/styles.css +37 -0
  31. package/lib/skeletons/_react/base/src/vite-env.d.ts +1 -0
  32. package/lib/skeletons/_react/base/tsconfig.app.json +18 -0
  33. package/lib/skeletons/_react/base/tsconfig.json +7 -0
  34. package/lib/skeletons/_react/base/tsconfig.node.json +15 -0
  35. package/lib/skeletons/_react/base/vite.config.ts +77 -0
  36. package/lib/skeletons/_react/options/pnpm/package.json +45 -0
  37. package/lib/utils.js +24 -0
  38. package/package.json +1 -1
  39. package/sonar-project.properties +0 -14
package/README.md CHANGED
@@ -1,157 +1,370 @@
1
1
  # @eui/cli
2
2
 
3
- Command-line interface for scaffolding and managing eUI applications.
3
+ Command-line interface for **scaffolding, serving and building eUI applications**. It generates a
4
+ ready-to-run project (Angular, React, mobile, or a Java web module) pre-wired with the eUI design
5
+ system, then acts as the app's build/serve tool so every eUI app is driven the same way regardless
6
+ of its underlying framework.
7
+
8
+ - [Installation](#installation)
9
+ - [Quick start](#quick-start)
10
+ - [`eui-cli new` — generate an application](#eui-cli-new--generate-an-application)
11
+ - [The interactive wizard, step by step](#the-interactive-wizard-step-by-step)
12
+ - [Application types explained](#application-types-explained)
13
+ - [Non-interactive / automated mode](#non-interactive--automated-mode)
14
+ - [Full configuration reference](#full-configuration-reference)
15
+ - [Working with a generated app](#working-with-a-generated-app)
16
+ - [`eui-cli serve-app`](#eui-cli-serve-app)
17
+ - [`eui-cli build-app`](#eui-cli-build-app)
18
+ - [`eui-cli lint-app`](#eui-cli-lint-app)
19
+ - [`eui-cli inject-config-app`](#eui-cli-inject-config-app)
20
+ - [`eui-cli generate-sprite`](#eui-cli-generate-sprite)
21
+ - [Generated project layouts](#generated-project-layouts)
22
+ - [Requirements](#requirements)
23
+ - [License](#license)
24
+
25
+ ---
4
26
 
5
27
  ## Installation
6
28
 
29
+ Install globally to get the `eui-cli` binary on your `PATH`:
30
+
7
31
  ```sh
8
32
  npm install -g @eui/cli
9
33
  ```
10
34
 
11
- ## Usage with npx
12
-
13
- Run without installing globally:
35
+ Or run it on demand without installing, using `npx`:
14
36
 
15
37
  ```sh
16
38
  npx @eui/cli new
17
39
  ```
18
40
 
19
- ## Usage
20
-
21
- ### Generate a new application
41
+ Check the installed version at any time:
22
42
 
23
43
  ```sh
24
- eui-cli new
44
+ eui-cli --version
25
45
  ```
26
46
 
27
- Or simply:
47
+ ---
48
+
49
+ ## Quick start
28
50
 
29
51
  ```sh
30
- eui-cli
52
+ # 1. create an empty folder and move into it
53
+ mkdir my-app && cd my-app
54
+
55
+ # 2. scaffold interactively (answers a few questions)
56
+ eui-cli new
57
+
58
+ # 3. once generated + installed, start the app (opens http://localhost:4200)
59
+ npm start
31
60
  ```
32
61
 
33
- The CLI will prompt you to configure your application:
62
+ > The generator **requires an empty target directory**. If the current (or `--targetPath`) folder
63
+ > is not empty, the CLI stops with `DIR_NOT_EMPTY` to avoid overwriting your files.
34
64
 
35
- 1. **Application Type**: Choose between:
36
- - Desktop (Angular)
37
- - Mobile Ionic
38
- - eUI + Spring Boot web module (requires JDK + Maven)
39
- - eUI + Maven web module (JEE Spring, requires JDK + Maven)
65
+ ---
40
66
 
41
- 2. **Maven Configuration** (for web-spring-boot type only):
42
- - groupId (e.g., `ec.europa.digit`)
43
- - artifactId (e.g., `myapp`)
67
+ ## `eui-cli new` — generate an application
44
68
 
45
- 3. **Additional Options** (not available for Mobile):
46
- - eUI ECL app-shell template (for ec.europa.eu apps)
47
- - If selected, choose between EC theme or EU theme
69
+ `new` is the default command, so `eui-cli` and `eui-cli new` are equivalent. It asks a series of
70
+ questions, scaffolds the matching skeleton into the target folder, optionally installs
71
+ dependencies, optionally sets up [eui-skills](https://sdlc.webcloud.ec.europa.eu/csdr/eui-skills.git),
72
+ and can start the app immediately.
48
73
 
49
- 4. **Dependency Installation**: Choose whether to install dependencies automatically
50
- 5. **Package Manager**: Select Yarn 1.x or Pnpm (experimental)
51
- 6. **eui-skills Setup**: Optionally install [eui-skills](https://sdlc.webcloud.ec.europa.eu/csdr/eui-skills.git) after generation
52
- - **Install all** (`--all`): install all skills to all agents without prompts
53
- - Or configure individually:
54
- - **Agent(s)**: target specific agents (e.g. `cursor`, `claude-code`, or `*` for all)
55
- - **Skill(s)**: specific skill names to install (or `*` for all)
56
- - **Global**: install at user-level instead of project-level
57
- - **Skip confirmations**: auto-confirm all skills prompts
74
+ ```sh
75
+ eui-cli new [--targetPath <dir>] [--config <string>] [skills flags…]
76
+ ```
58
77
 
59
- #### CLI Flags
78
+ | Flag | Description |
79
+ | --- | --- |
80
+ | `-t, --targetPath <dir>` | Folder to generate into. Created if missing. Defaults to the current directory. |
81
+ | `-c, --config <string>` | Non-interactive config string (see [automated mode](#non-interactive--automated-mode)). When present, **all prompts are skipped**. |
82
+ | `--skills` | Set up eui-skills after generation (enables the skills sub-flags). |
83
+ | `--skillsAll` | Install all skills to all agents, no prompts. Requires `--skills`. |
84
+ | `--skillsAgent <agents>` | Target agent(s), space-separated, or `*` for all. Requires `--skills`. |
85
+ | `--skillsSkill <skills>` | Skill name(s), space-separated, or `*` for all. Requires `--skills`. |
86
+ | `--skillsGlobal` | Install skills at user level instead of project level. Requires `--skills`. |
87
+ | `--skillsYes` | Auto-confirm all skills prompts. Requires `--skills`. |
88
+
89
+ > All `--skills*` sub-flags require `--skills`; using one without it exits with an error.
90
+
91
+ ### The interactive wizard, step by step
92
+
93
+ Running `eui-cli new` with no `--config` walks you through these prompts. Some are conditional —
94
+ they only appear for certain earlier answers.
95
+
96
+ 1. **Application type** — the main choice. See
97
+ [Application types explained](#application-types-explained) below. Determines which skeleton is
98
+ generated and which of the following prompts appear.
99
+
100
+ 2. **Maven groupId / artifactId** — *only for the Spring Boot web module.* Standard Maven
101
+ coordinates for the generated Java module (e.g. `ec.europa.digit` / `myapp`). Both are required.
102
+
103
+ 3. **App-shell option** — *only for `Desktop` (plain Angular); skipped for Desktop EDS, React EDS,
104
+ Mobile, and the Java web modules.* Choose the shell/theme layer:
105
+ - **eUI default app-shell** — the standard `@eui/components` `eui-app` layout.
106
+ - **eUI ECL app-shell** — the Europa Component Library site layout, for `ec.europa.eu` apps.
107
+ If selected, a follow-up prompt asks for the **ECL theme**: **EC theme** (`ecl-ec`) or
108
+ **EU theme** (`ecl-eu`).
109
+
110
+ > Desktop EDS pre-selects the EDS app-shell up-front, so it never shows this prompt.
111
+
112
+ 4. **Install dependencies now?** — `Yes` runs the package manager right after scaffolding; `No`
113
+ leaves you to install manually later.
114
+
115
+ 5. **Package manager** — *only if you chose to install.* **Yarn 1.x** (default) or
116
+ **pnpm** (experimental). The choice also selects the matching `package.json` variant for
117
+ Angular and React skeletons (pnpm needs all dependencies listed explicitly rather than via the
118
+ `@eui/deps-*` meta-packages).
119
+
120
+ 6. **Set up eui-skills?** — `No` by default. `Yes` reveals the skills sub-flow:
121
+ - **Install all** (`--all`) — install every skill to every detected agent with no further
122
+ questions, **or**
123
+ - **Configure individually**:
124
+ - **Agent(s)** — which AI agents to install into (e.g. `cursor`, `claude-code`, `*` for all;
125
+ empty = default).
126
+ - **Skill(s)** — which skills to install (space-separated names, `*` for all, empty = all).
127
+ - **Global** — install at user level instead of project level.
128
+ - **Skip confirmations** — auto-confirm the skills installer's prompts.
129
+
130
+ 7. **Start the app?** — when dependencies were installed, the CLI can launch the app immediately
131
+ (`npm start`), opening the browser on `http://localhost:4200`.
132
+
133
+ ### Application types explained
134
+
135
+ The **primary choice** is the application type. The two flagship desktop tracks are
136
+ **Desktop / Desktop EDS** (Angular) and **React EDS** (React); the remaining types cover mobile and
137
+ server-rendered Java web modules.
138
+
139
+ | Menu entry | Stack | App shell / UI layer | Notes |
140
+ | --- | --- | --- | --- |
141
+ | **Desktop** | Angular | `@eui/components` (`eui-app`) — legacy app-shell | Prompts for the app-shell option (default vs ECL theme). The classic eUI desktop app. |
142
+ | **Desktop EDS** | Angular | `@eui/eds` (`eds-shell` + EDS components) — modern design system | Same desktop skeleton as *Desktop* (identical routes, features, config, HTTP interceptors) but the shell is composed with `eds-shell`, `eds-user-profile`, `eds-icon-button`, etc. Skips the app-shell prompt. |
143
+ | **React EDS** | React + Vite | `@eui/eds-react` (`EdsShell` + pure-React EDS components) | A Vite React app with an `EdsShell` (toolbar + collapsible sidebar + routed content) and example pages, using React Router (`HashRouter`). |
144
+ | **Mobile Ionic** | Angular + Ionic | eUI mobile layer | A mobile app skeleton. No app-shell / ECL prompt. |
145
+ | **eUI + Spring Boot web module** | Angular inside a Spring Boot Maven module | eUI (default or ECL) | Generates a Java Spring Boot web module with an embedded Angular front-end. **Requires JDK + Maven.** Prompts for Maven `groupId` / `artifactId`. |
146
+ | **eUI + Maven web module** | Angular inside a JEE/Spring Maven module | eUI (default or ECL) | Generates a JEE Spring Maven web module with an embedded Angular front-end. **Requires JDK + Maven.** |
147
+
148
+ **Desktop vs Desktop EDS** — pick *Desktop EDS* for new applications that should adopt the modern
149
+ EU Design System (EDS) look and components; pick *Desktop* if you need the legacy `@eui/components`
150
+ shell or the ECL site layout for `ec.europa.eu` public sites. Both share the same underlying
151
+ Angular application structure, so switching later is mostly a shell/template change.
152
+
153
+ **React EDS** — the React equivalent of Desktop EDS, built on `@eui/eds-react`. It ships a working
154
+ `EdsShell` app (toolbar, collapsible icon sidebar, routed content, Home + About pages) and is
155
+ served/built through the same `eui-cli` commands as the Angular apps (see
156
+ [Working with a generated app](#working-with-a-generated-app)).
157
+
158
+ ### Non-interactive / automated mode
159
+
160
+ Pass `--config` (with an optional `--targetPath`) to skip **all** prompts — ideal for CI, scripts,
161
+ or reproducible scaffolding. The value is a comma-separated list of `key:value` pairs; any option
162
+ you omit falls back to its default.
60
163
 
61
- Skip prompts by passing flags directly:
164
+ ```sh
165
+ eui-cli new --config <config-string> --targetPath <output-directory>
166
+ ```
167
+
168
+ Examples for the main tracks:
62
169
 
63
170
  ```sh
64
- # Generate with skills setup (interactive sub-prompts)
65
- eui-cli new --skills
171
+ # Desktop (plain Angular), no install
172
+ eui-cli new --config appType:angular,npmInstall:false --targetPath eui-desktop
173
+
174
+ # Desktop with the ECL app-shell, EC theme
175
+ eui-cli new --config appType:angular,appOptions:ecl,appOptionsEclTheme:ecl-ec,npmInstall:false --targetPath eui-desktop-ecl
176
+
177
+ # Desktop EDS (Angular + eds-shell)
178
+ eui-cli new --config appType:angular,appOptions:eds,npmInstall:false --targetPath eui-desktop-eds
66
179
 
67
- # Install all skills to all agents without prompts
68
- eui-cli new --skills --skillsAll
180
+ # React EDS (React + Vite + @eui/eds-react)
181
+ eui-cli new --config appType:react,npmInstall:false --targetPath eui-react-eds
69
182
 
70
- # Target specific agents and skip confirmations
71
- eui-cli new --skills --skillsAgent "cursor claude-code" --skillsYes
183
+ # Spring Boot web module (needs JDK + Maven)
184
+ eui-cli new --config appType:web-spring-boot,groupId:ec.europa.digit,artifactId:myapp,npmInstall:false --targetPath eui-web
72
185
 
73
- # Install a specific skill globally
74
- eui-cli new --skills --skillsSkill "pr-review" --skillsGlobal
186
+ # Fully automated with pnpm + install + skills
187
+ eui-cli new --config appType:angular,appOptions:eds,npmInstall:true,packageManager:pnpm --skills --skillsAll --targetPath eui-app
75
188
  ```
76
189
 
77
- > Skills sub-options (`--skillsAgent`, `--skillsSkill`, `--skillsGlobal`, `--skillsYes`, `--skillsAll`) require `--skills` to be set, otherwise the CLI will exit with an error.
190
+ > **Note on `appOptions`.** In a `--config` string, `appOptions` accepts multiple values joined by
191
+ > an underscore (e.g. `ecl_something`) and is parsed into a list. Use `appOptions:eds` for the EDS
192
+ > desktop shell and `appOptions:ecl` (with `appOptionsEclTheme`) for the ECL shell.
193
+
194
+ ### Full configuration reference
195
+
196
+ Every key accepted in the `--config` string (and its interactive-prompt equivalent):
197
+
198
+ | Key | Values | Applies to | Meaning |
199
+ | --- | --- | --- | --- |
200
+ | `appType` | `angular` · `react` · `mobile` · `web-spring-boot` · `web-maven` | all | The skeleton to generate. `Desktop` and `Desktop EDS` both use `angular` (differentiated by `appOptions`). `React EDS` uses `react`. |
201
+ | `appOptions` | `''` (default) · `ecl` · `eds` (underscore-join for multiple) | Angular | App-shell layer. Empty = default eUI shell; `ecl` = ECL site shell; `eds` = EDS desktop shell. |
202
+ | `appOptionsEclTheme` | `ecl-ec` · `ecl-eu` | Angular + `appOptions:ecl` | ECL theme flavor (EC vs EU). |
203
+ | `groupId` | any Maven groupId | `web-spring-boot` | Maven groupId (e.g. `ec.europa.digit`). |
204
+ | `artifactId` | any Maven artifactId | `web-spring-boot` | Maven artifactId (e.g. `myapp`). |
205
+ | `npmInstall` | `true` · `false` | all | Install dependencies right after scaffolding. |
206
+ | `packageManager` | `yarn` · `pnpm` | all (when installing) | Package manager to install with; also selects the pnpm `package.json` variant. |
207
+ | `appStart` | `true` · `false` | all | Start the app (`npm start`) after a successful install. Only runs when `npmInstall` is `true`. |
208
+ | `skills` | `true` · `false` | all | Set up eui-skills after generation. |
209
+ | `skillsAll` | `true` · `false` | with `skills` | Install all skills to all agents, no prompts. |
210
+ | `skillsAgent` | agent name(s), space-separated or `*` | with `skills` | Target agents. |
211
+ | `skillsSkill` | skill name(s), space-separated or `*` | with `skills` | Skills to install. |
212
+ | `skillsGlobal` | `true` · `false` | with `skills` | Install at user level instead of project level. |
213
+ | `skillsYes` | `true` · `false` | with `skills` | Auto-confirm skills prompts. |
214
+
215
+ ---
216
+
217
+ ## Working with a generated app
78
218
 
79
- #### Automated Mode
219
+ Every generated app exposes the same npm scripts, which delegate to `eui-cli`. The CLI's
220
+ `serve-app` and `build-app` are **framework-aware**: they detect whether the project is an Angular
221
+ app (`angular.json`) or a Vite React app (`vite.config.*`) and run the correct toolchain. This is
222
+ what lets both Desktop/Desktop EDS (Angular) and React EDS (Vite) be driven with identical commands.
80
223
 
81
- Generate an application without prompts using a configuration string:
224
+ Common scripts in the generated `package.json`:
225
+
226
+ | Script | Angular apps | React EDS app |
227
+ | --- | --- | --- |
228
+ | `npm start` | Mock server + `eui-cli serve-app` (proxy-mock) in parallel | Mock server + `eui-cli serve-app` (Vite dev server) in parallel |
229
+ | `npm run start-local` | `eui-cli serve-app` (no proxy) | `eui-cli serve-app` (Vite) |
230
+ | `npm run build` | `eui-cli build-app` | `tsc -b && eui-cli build-app` (Vite build) |
231
+
232
+ ### `eui-cli serve-app`
233
+
234
+ Serves the application on a local dev server.
82
235
 
83
236
  ```sh
84
- eui-cli new --config <config-string> --targetPath <output-directory>
237
+ eui-cli serve-app [options]
85
238
  ```
86
239
 
87
- Configuration format:
240
+ | Option | Angular | React (Vite) |
241
+ | --- | --- | --- |
242
+ | `-c, --configuration <config>` | Angular build configuration | ignored |
243
+ | `-p, --port <port>` | dev-server port (default 4200) | Vite port |
244
+ | `-h, --host <host>` | host to bind | Vite host |
245
+ | `--proxyConfig <path>` | proxy config file | ignored (use `vite.config.ts` `server.proxy`) |
246
+ | `--baseHref, --base-href <href>` | base href | ignored |
247
+ | `--servePath <path>` | serve path | ignored |
248
+ | `--open <value>` | open browser (default on; `--open=false` to disable) | `--open` / `--no-open` |
249
+ | `--configEnvTarget <target>` | inject env config before serving | ignored |
250
+ | `--noLiveReload` | disable live reload | ignored |
251
+ | `--disableHostCheck` | disable host check | ignored |
252
+ | `--maxSpaceSize` | raise Node memory to 8 GB | ignored |
253
+ | `-d, --debug` | verbose logging | verbose logging |
254
+
255
+ ### `eui-cli build-app`
256
+
257
+ Builds the application for production.
258
+
259
+ ```sh
260
+ eui-cli build-app [options]
88
261
  ```
89
- appType:angular,appOptions:ecl,appOptionsEclTheme:ecl-ec,npmInstall:false
262
+
263
+ | Option | Angular | React (Vite) |
264
+ | --- | --- | --- |
265
+ | `--skipLint` | skip `ng lint` | n/a (lint is a separate script) |
266
+ | `--skipTest` | skip unit tests | n/a |
267
+ | `--skipCompile` | skip the final compile step | n/a |
268
+ | `-c, --configuration <config>` | Angular build configuration (default `production`) | ignored |
269
+ | `--baseHref, --base-href <href>` | base href | mapped to Vite `--base` |
270
+ | `--servePath <path>` | serve path | ignored |
271
+ | `--statsJson` | emit `stats.json` | ignored |
272
+ | `--sourceMap` | emit source maps | ignored |
273
+ | `--deployUrl <url>` | deploy URL | ignored |
274
+ | `--configEnvTarget <target>` | inject env config before build | ignored |
275
+ | `--maxSpaceSize` | raise Node memory to 8 GB | ignored |
276
+ | `--ci` | disable progress output | ignored |
277
+ | `--dryRun` | print commands without running them | print without running |
278
+ | `-w, --watch` | watch mode for tests | ignored |
279
+ | `-d, --debug` | verbose logging | verbose logging |
280
+
281
+ > For React apps, TypeScript type-checking stays in the app's own `tsc -b` step (part of the
282
+ > `build` npm script); `eui-cli build-app` runs the Vite bundle step. The Angular-only quality
283
+ > gates (`--skipLint` / `--skipTest`) and env-config injection do not apply to React.
284
+
285
+ ### `eui-cli lint-app`
286
+
287
+ Lints an Angular application.
288
+
289
+ ```sh
290
+ eui-cli lint-app [-p, --project <name>] [-d, --debug]
90
291
  ```
91
292
 
92
- Available options:
93
- - `appType`: `angular`, `mobile`, `web-spring-boot`, `web-maven`
94
- - `groupId`: Maven groupId (for web-spring-boot, e.g., `ec.europa.digit`)
95
- - `artifactId`: Maven artifactId (for web-spring-boot, e.g., `myapp`)
96
- - `appOptions`: `ecl` (use underscore for multiple: `ecl_option2`)
97
- - `appOptionsEclTheme`: `ecl-ec`, `ecl-eu`
98
- - `npmInstall`: `true`, `false`
99
- - `packageManager`: `yarn`, `pnpm`
100
- - `skills`: `true`, `false`
101
- - `skillsAll`: `true`, `false`
102
- - `skillsAgent`: agent name(s), space-separated or `*`
103
- - `skillsSkill`: skill name(s), space-separated or `*`
104
- - `skillsGlobal`: `true`, `false`
105
- - `skillsYes`: `true`, `false`
293
+ ### `eui-cli inject-config-app`
106
294
 
107
- ### Build application
295
+ Injects an environment-specific configuration file (`env-json-config-<target>.json`) into the app
296
+ before serving/building. Used by the Angular `build-*` / `start-*` scripts via `--configEnvTarget`.
108
297
 
109
298
  ```sh
110
- eui-cli build-app [options]
299
+ eui-cli inject-config-app -c, --configEnvTarget <target> [-d, --debug]
111
300
  ```
112
301
 
113
- Options:
114
- - `--skipLint` - Skip linting step
115
- - `--skipTest` - Skip testing step
116
- - `--skipCompile` - Skip compilation step
117
- - `-c, --configuration <config>` - Angular build configuration
118
- - `--baseHref, --base-href <href>` - Base href for the application
119
- - `--statsJson` - Generate stats.json file
120
- - `--sourceMap` - Generate source maps
302
+ ### `eui-cli generate-sprite`
121
303
 
122
- ### Serve application
304
+ Generates an SVG sprite from a folder of individual SVG files.
123
305
 
124
306
  ```sh
125
- eui-cli serve-app [options]
307
+ eui-cli generate-sprite -i <input-folder> -o <output-file.svg>
126
308
  ```
127
309
 
128
- Options:
129
- - `-c, --configuration <config>` - Angular build configuration
130
- - `-p, --port <port>` - Port number (default: 4200)
131
- - `-h, --host <host>` - Host to serve on
132
- - `--proxyConfig <path>` - Path to proxy configuration file
133
- - `--open` - Open browser automatically
310
+ | Option | Description |
311
+ | --- | --- |
312
+ | `-i, --inFolder <path>` | Input folder containing SVG files (**required**). |
313
+ | `-o, --outFile <filename>` | Output sprite filename; must end in `.svg` (**required**). |
314
+ | `-d, --debug` | Verbose logging. |
134
315
 
135
- ### Lint application
316
+ ---
136
317
 
137
- ```sh
138
- eui-cli lint-app
318
+ ## Generated project layouts
319
+
320
+ ### Angular (Desktop / Desktop EDS)
321
+
322
+ ```
323
+ ├── angular.json # Angular workspace (EDS variant also wires @eui/eds-styles)
324
+ ├── package.json # scripts delegate to eui-cli; deps via @eui/deps-base(+dev)
325
+ ├── proxy.conf.json # dev proxy to a real backend
326
+ ├── proxy-mock.conf.json # dev proxy to the local mock server
327
+ ├── mock/ # json-server mock API (server.js, db/, app/routes, app/models)
328
+ └── src/
329
+ ├── index.html # Desktop EDS adds class="eui-21" on <body> (EDS token scope)
330
+ ├── main.ts
331
+ ├── styles.scss
332
+ ├── config/ # eUI app config
333
+ ├── environments/ # environment.ts / environment.prod.ts
334
+ └── app/
335
+ ├── app.component.* # Desktop = eui-app shell · Desktop EDS = eds-shell
336
+ ├── app.config.ts # providers, HTTP interceptors, i18n, app initializer
337
+ ├── app.routes.ts # lazy-loaded feature routes
338
+ └── features/ # home / module1 / module2 sample features
139
339
  ```
140
340
 
141
- ### Generate SVG sprite
341
+ ### React EDS
142
342
 
143
- ```sh
144
- eui-cli generate-sprite -i <input-folder> -o <output-file>
343
+ ```
344
+ ├── index.html # <body class="eui-21"> (EDS token scope)
345
+ ├── vite.config.ts # Vite config; serves EDS icon sprites, proxies /api to the mock
346
+ ├── tsconfig*.json # project references (app + node)
347
+ ├── eslint.config.mjs # flat ESLint config (single quotes, TS recommended)
348
+ ├── package.json # scripts delegate to eui-cli; deps via @eui/deps-base-react
349
+ ├── mock/ # json-server mock API (same shape as the Angular mock)
350
+ ├── public/ # host-owned static assets
351
+ └── src/
352
+ ├── main.tsx # mounts <App/> in a HashRouter; loads EDS + component styles
353
+ ├── App.tsx # the EdsShell (toolbar + sidebar + routed content)
354
+ ├── routes.ts # sidebar/route table
355
+ ├── styles.css # app-level styles
356
+ └── pages/ # home / about example pages
145
357
  ```
146
358
 
147
- Options:
148
- - `-i, --inFolder <path>` - Input folder containing SVG files (required)
149
- - `-o, --outFile <filename>` - Output sprite filename with .svg extension (required)
359
+ ---
150
360
 
151
361
  ## Requirements
152
362
 
153
- - Node.js 24.x or higher
154
- - npm or yarn
363
+ - **Node.js** `^20.19.0 || ^22.12.0 || >=24.15.0`
364
+ - **Yarn** `>=1.22.4 <2` (or pnpm, experimental)
365
+ - **JDK + Maven** — only for the `web-spring-boot` / `web-maven` application types.
366
+
367
+ ---
155
368
 
156
369
  ## License
157
370
 
@@ -51,6 +51,11 @@ module.exports.run = () => {
51
51
  prjName = project;
52
52
  }
53
53
 
54
+ // Vite React app — build with the Vite bundler instead of the Angular CLI.
55
+ if (utils.detectAppTool() === 'vite') {
56
+ return buildVite({ baseHref, dryRun });
57
+ }
58
+
54
59
  utils.logTitle(`Building application : ${prjName}...`);
55
60
 
56
61
  const ng = path.resolve(process.cwd(), 'node_modules', '@angular', 'cli', 'bin', 'ng');
@@ -140,3 +145,24 @@ module.exports.run = () => {
140
145
  }
141
146
  };
142
147
 
148
+ /**
149
+ * Builds a standalone Vite React app via the local `vite` binary. TypeScript type-checking is
150
+ * done by the app's own `tsc -b` (kept in the app's `build` script chain); this runs the bundle
151
+ * step so the `eui-cli build-app` surface stays the same for both Angular and React apps.
152
+ */
153
+ const buildVite = ({ baseHref, dryRun }) => {
154
+ utils.logTitle('Building Vite React application...');
155
+
156
+ const args = ['vite', 'build'];
157
+
158
+ if (baseHref) {
159
+ args.push(`--base=${baseHref}`);
160
+ }
161
+
162
+ utils.logInfo(`vite build with args ${args.join(' ')}`);
163
+
164
+ if (!dryRun) {
165
+ execSync(`npx ${args.join(' ')}`, { cwd: process.cwd(), stdio: 'inherit' });
166
+ }
167
+ };
168
+
@@ -32,6 +32,11 @@ module.exports.run = () => {
32
32
 
33
33
  let { configuration, baseHref, servePath, host, proxyConfig, maxSpaceSize, port, disableHostCheck, open, debug, configEnvTarget, noLiveReload, project } = utils.getArgs();
34
34
 
35
+ // Vite React app — serve with the Vite dev server instead of the Angular CLI.
36
+ if (utils.detectAppTool() === 'vite') {
37
+ return serveVite({ port, host, open });
38
+ }
39
+
35
40
  const ng = path.resolve(process.cwd(), 'node_modules', '@angular', 'cli', 'bin', 'ng');
36
41
 
37
42
  let prjName = 'app';
@@ -93,3 +98,30 @@ module.exports.run = () => {
93
98
 
94
99
  return execSync(`node ${args.join(' ')}`, { cwd: process.cwd(), stdio: 'inherit' });
95
100
  }
101
+
102
+ /**
103
+ * Serves a standalone Vite React app via the local `vite` binary. Maps the shared serve options
104
+ * (port / host / open) onto Vite's flags so the `eui-cli serve-app` surface stays the same for
105
+ * both Angular and React apps.
106
+ */
107
+ const serveVite = ({ port, host, open }) => {
108
+ utils.logTitle('Serving Vite React application...');
109
+
110
+ const args = ['vite'];
111
+
112
+ if (port) {
113
+ args.push(`--port=${port}`);
114
+ }
115
+ if (host) {
116
+ args.push(`--host=${host}`);
117
+ }
118
+ if (open === 'false') {
119
+ args.push('--no-open');
120
+ } else {
121
+ args.push('--open');
122
+ }
123
+
124
+ utils.logInfo(`vite serve with args ${args.join(' ')}`);
125
+
126
+ return execSync(`npx ${args.join(' ')}`, { cwd: process.cwd(), stdio: 'inherit' });
127
+ };
package/lib/build.js CHANGED
@@ -5,11 +5,7 @@ const utils = require('./utils');
5
5
  const config = require('./config');
6
6
 
7
7
  module.exports.start = (options) => {
8
- try {
9
- build(options.config, options.targetPath)
10
- } catch (e) {
11
- throw e;
12
- }
8
+ build(options.config, options.targetPath);
13
9
  }
14
10
 
15
11
  const build = (cliConfig, targetPath) => {
@@ -33,6 +29,14 @@ const build = (cliConfig, targetPath) => {
33
29
  copyAngular(angularPath, cliConfig, true);
34
30
  }
35
31
 
32
+ // BUILD REACT
33
+ if (appType === 'react') {
34
+ console.log('---building react');
35
+ const reactPath = utils.getAngularPath(targetPath, appName, appType, artifactId);
36
+ console.log(reactPath);
37
+ copyReact(reactPath, cliConfig);
38
+ }
39
+
36
40
  // BUILD web-maven
37
41
  if (appType === 'web-maven') {
38
42
  console.log('--building web-maven');
@@ -63,12 +67,29 @@ const copyAngular = (targetPath, cliConfig, overwrite = true) => {
63
67
  utils.copydir(config.angularBaseMobilePath, targetPath, overwrite);
64
68
  }
65
69
 
66
- if (cliConfig.appOptions === 'ecl') {
70
+ // appOptions may be a plain string (interactive mode) or an array (automated `--config`
71
+ // parses `appOptions` on `_`, e.g. `ecl_something` -> ['ecl', ...]). Normalize to an array.
72
+ const appOptions = [].concat(cliConfig.appOptions || []);
73
+
74
+ if (appOptions.includes('ecl')) {
67
75
  console.log(`eUI ECL theme selected : ` + cliConfig.appOptionsEclTheme);
68
76
  utils.copydir(config.optionsPath[cliConfig.appOptionsEclTheme], targetPath, true);
69
77
  }
70
78
 
79
+ if (appOptions.includes('eds')) {
80
+ console.log(`eUI EDS desktop app-shell selected`);
81
+ utils.copydir(config.edsOptionPath, targetPath, true);
82
+ }
83
+
84
+ if (cliConfig.packageManager === 'pnpm') {
85
+ utils.copy(path.join(config.pnpmOptionPath.angular, 'package.json'), path.join(targetPath, 'package.json'));
86
+ }
87
+ }
88
+
89
+ const copyReact = (targetPath, cliConfig) => {
90
+ utils.copydir(config.reactBasePath, targetPath, true);
91
+
71
92
  if (cliConfig.packageManager === 'pnpm') {
72
- utils.copy(path.join(config.pnpmOptionPath, 'package.json'), path.join(targetPath, 'package.json'));
93
+ utils.copy(path.join(config.pnpmOptionPath.react, 'package.json'), path.join(targetPath, 'package.json'));
73
94
  }
74
95
  }
package/lib/cli.js CHANGED
@@ -50,9 +50,11 @@ module.exports.start = async (options) => {
50
50
 
51
51
  const appTypePrompt = new Select({
52
52
  name: 'appType',
53
- message: 'Select an eUI Angular application type :',
53
+ message: 'Select an eUI application type :',
54
54
  choices: [
55
55
  'Desktop',
56
+ 'Desktop EDS',
57
+ 'React EDS',
56
58
  'Mobile Ionic',
57
59
  'eUI + Spring Boot web module - JDK + Maven required !!!',
58
60
  'eUI + Maven web module (JEE Spring maven web module) - JDK + Maven required !!!'
@@ -64,12 +66,22 @@ module.exports.start = async (options) => {
64
66
  // Map display name to value
65
67
  const appTypeMap = {
66
68
  'Desktop': 'angular',
69
+ 'Desktop EDS': 'angular',
70
+ 'React EDS': 'react',
67
71
  'Mobile Ionic': 'mobile',
68
72
  'eUI + Spring Boot web module - JDK + Maven required !!!': 'web-spring-boot',
69
73
  'eUI + Maven web module (JEE Spring maven web module) - JDK + Maven required !!!': 'web-maven'
70
74
  };
71
75
  answers.appType = appTypeMap[appTypeChoice];
72
76
 
77
+ // "Desktop EDS" is an Angular desktop app whose shell is composed with @eui/eds (eds-shell +
78
+ // EDS components) instead of the legacy @eui/components app-shell. It pre-selects the `eds`
79
+ // app-shell option, so the ECL/default app-shell prompt below is skipped for it.
80
+ const isEdsDesktop = appTypeChoice === 'Desktop EDS';
81
+ if (isEdsDesktop) {
82
+ answers.appOptions = 'eds';
83
+ }
84
+
73
85
  if (answers.appType === 'web-spring-boot') {
74
86
  const groupIdPrompt = new Input({
75
87
  name: 'groupId',
@@ -88,7 +100,9 @@ module.exports.start = async (options) => {
88
100
  answers.artifactId = await artifactIdPrompt.run();
89
101
  }
90
102
 
91
- if (answers.appType !== 'mobile') {
103
+ // ECL app-shell options apply to the Angular-based types only (not mobile, not react, and
104
+ // not when the EDS desktop shell was already chosen up-front).
105
+ if (answers.appType !== 'mobile' && answers.appType !== 'react' && !isEdsDesktop) {
92
106
  const appOptionsPrompt = new Select({
93
107
  name: 'appOptions',
94
108
  message: 'Select one or more additional configuration options :',