Generate JHipster + Svelte/Kit web applications
Tags: jhipster, svelte, javascript
Published: 2022-01-14 18:21:17

[JHipster]((https://www.jhipster.tech/)) is a development platform to quickly generate, develop, & deploy modern web applications and micro-service architectures. The default JHipster platform supports Angular, React, and Vue as the frontend framework. 

The JHipster platform allows code extension and customization via blueprints. In this blog post, we look into [Svelte Hipster](https://www.npmjs.com/package/generator-jhipster-svelte) blueprint that generates Svelte/Kit powered frontend applications.

## Svelte Hipster - A JHipster blueprint

`Svelte Hipster` is a JHipster blueprint that intends to use the following technical stack in generated applications:

- [Svelte](https://svelte.dev/)/[Kit](https://kit.svelte.dev/) - Client-side development framework
- [Tailwindcss](https://tailwindcss.com/) - CSS utility framework
- [Cypress](https://docs.cypress.io/) - End-to-End tests framework
- [Jest](https://jestjs.io/) - Javascript unit tests framework
- [Prettier](https://prettier.io/) - Opinionated code formatter
- [ESLint](https://eslint.org/) - Javascript Lint tool
- [Husky](https://typicode.github.io/husky/#/) - Git commit hooks

### Install Svelte Hipster blueprint

**Prerequisites**
- `NodeJS 16.x` and `NPM 8.x` are recommended versions
- `Java 11.x` is minimum supported Java version

As a very first step, we need to install the `generator-jhipster-svelte` npm package globally. Run the below command in your favorite terminal:
```fish
npm install -g generator-jhipster-svelte@0.7.1
```

### Generate a new monolithic application

`Svelte Hipster` blueprint exposes a `cli` to use the correct version of `JHipster`. Run the below command to interactively generate an application:

```fish
shipster
```
The `shipster` CLI prompts a series of questions to customize the generated web application. We chose the below options for our sample application:

```fish
? Which *type* of application would you like to create? Monolithic application (recommended for simple projects)
? What is the base name of your application? Blog
? Do you want to make it reactive with Spring WebFlux? No
? What is your default Java package name? org.github.vishal423
? Which *type* of authentication would you like to use? JWT authentication (stateless, with a token)
? Which *type* of database would you like to use? SQL (H2, PostgreSQL, MySQL, MariaDB, Oracle, MSSQL)
? Which *production* database would you like to use? PostgreSQL
? Which *development* database would you like to use? H2 with disk-based persistence
? Which cache do you want to use? (Spring cache abstraction) Caffeine (local cache, for a single node)
? Do you want to use Hibernate 2nd level cache? Yes
? Would you like to use Maven or Gradle for building the backend? Maven
? Do you want to use the JHipster Registry to configure, monitor and scale your application? No
? Which other technologies would you like to use?
? Besides Junit, which testing frameworks would you like to use?
? Would you like to install other generators from the JHipster Marketplace? (y/N) No
```

> PS: Svelte Hipster blueprint is still under active development.  You can refer to the [documentation](https://github.com/jhipster/generator-jhipster-svelte#supported-flows-and-integrations) listing supported options and integrations.

After successful application generation, the code is formatted with opinionated `Prettier` configurations and stored in the local git repository with an initial commit. We can also see instructions to start the backend and frontend development servers on the console.

### A sneak peek into generated application

As instructed on console, let's start the backend server with `./mvnw` command. By default, the command also compiles and deploys the frontend code. If you would like to skip the execution of unit tests, then, you can use `./mvnw -DskipTests` command.

You can browse the generated application at http://localhost:8080 and log-in with default `admin` or `user` credentials.
 
The default application consists of following screens:
* Sign In
* Sign Up
* Forgot Password
* Home
* Account
  * Change Password
  * Settings
  * Sign Out
* Administration
  * User Management (List, Create, Update, View, Delete)
  * Loggers 

In the following screencast, we navigate through generated screens and try out different flows:


![Generated Application Screens](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0odwdyyuk6lmok90uc0s.gif)

### Extend application to add business domain model

An application without a functional domain is not much useful. Let's extend our example application to add business domain entities. We are leveraging JHipster JDL to define structure and relationships. Refer to [JDL entity fields](https://www.jhipster.tech/jdl/entities-fields) documentation for all supported entity data types and constraints and [JDL relationships](https://www.jhipster.tech/managing-relationships/) documentation for supported relationships and syntax.

Save below entity JDL contents in a file (`entity.jdl` in this example)

```fish
entity Blog {
  name String required minlength(3)
  handle String required minlength(2)
}

entity Post {
  title String required
  content TextBlob required
  date Instant required
}

entity Tag {
  name String required minlength(2)
}

relationship ManyToOne {
  Blog{user(login)} to User
  Post{blog(name)} to Blog
}

relationship ManyToMany {
  Post{tag(name)} to Tag{entry}
}

paginate Post, Tag with pagination
```

Here, we define an entity named `Blog`, `Post`, and `Tag`. Refer to JDL documentation for supported data types and constraints.

In our domain model, a user can write multiple blogs and each blog can contain multiple posts. `User` is a special entity supported by JHipster to model read only relationships. Further, a post can be associated with multiple tags and same tag can be used in multiple posts.

`Post` and `Tag` entities are also marked to represent data in a paginated manner.

Run the below command to import entities domain model into our example application:

```fish
shipster import-jdl entity.jdl
```
Since we are updating our application to include business domain model, you will notice prompts to review the updated code. For now, we accept all modifications by entering `a` key. The new and updated files are not committed to Git and you can always review those using your favorite diff tool.

Restart the application with `./mvnw` command and log in with default `admin` credentials. Under the `Entities` menu, you will see `Blog`, `Post`, and `Tag` menu items. In the development profile, JHipster application also uses the `faker.js` library to generate test data.  

In the following screencast, we navigate through newly generated entity screens and create a new blog post:

![Blog Entities](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewnsyx9nhnmw7e7emk06.gif)

### Validate generated application code

So far we have generated an application and extended it to add a business domain model. However, we still haven't looked into the verification of generated code. 

Svelte Hipster blueprint supports validation of generated code via two means:
- Jest + Svelte Testing Library to validate an individual svelte component
- Cypress tests to validate end to end business flow

In the current release, we generate a limited set of unit tests. In the current form, these help to assert all associated library integrations. However, there is a ticket to improve overall unit test coverage and ensure the robustness of generated code.

Run the below command to execute unit tests:

```fish
npm run test
```
> You might observe a unit test failure. We have addressed that issue in the main code and the fix should be available in the next release.

We generate an exhaustive suite of end-to-end tests to ensure generated code meets functional requirements. Run the below command to execute cypress tests:

```fish
npm run e2e
```

After completion, you can see a summary report like below:

```fish

====================================================================================================

  (Run Finished)


       Spec                                              Tests  Passing  Failing  Pending  Skipped
  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ ✔  account/change-password.spec.js          00:12        7        7        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  account/register.spec.js                 00:15       10       10        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  account/reset/init-password.spec.js      00:04        5        5        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  account/settings.spec.js                 00:10        4        4        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  admin/logger.spec.js                     00:11        7        7        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  admin/user-management/user-create.s      00:15        7        7        -        -        - │
  │    pec.js                                                                                      │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  admin/user-management/user-delete.s      00:06        3        3        -        -        - │
  │    pec.js                                                                                      │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  admin/user-management/user-list.spe      00:12        7        7        -        -        - │
  │    c.js                                                                                        │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  admin/user-management/user-update.s      00:16        7        7        -        -        - │
  │    pec.js                                                                                      │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  admin/user-management/user-view.spe      00:03        2        2        -        -        - │
  │    c.js                                                                                        │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/blog/blog-create.spec.js        00:05        4        4        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/blog/blog-delete.spec.js        00:06        3        3        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/blog/blog-list.spec.js          00:04        3        3        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/blog/blog-update.spec.js        00:11        5        5        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/blog/blog-view.spec.js          00:03        2        2        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/post/post-create.spec.js        00:12        4        4        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/post/post-delete.spec.js        00:07        3        3        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/post/post-list.spec.js          00:06        5        5        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/post/post-update.spec.js        00:09        5        5        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/post/post-view.spec.js          00:02        2        2        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/tag/tag-create.spec.js          00:04        4        4        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/tag/tag-delete.spec.js          00:05        3        3        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/tag/tag-list.spec.js            00:06        5        5        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/tag/tag-update.spec.js          00:05        5        5        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  entities/tag/tag-view.spec.js            00:02        2        2        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  footer.spec.js                           550ms        1        1        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  home.spec.js                             00:03        4        4        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  login.spec.js                            00:06        8        8        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  navbar.spec.js                           00:11       14       14        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  routes.spec.js                           00:04        7        7        -        -        - │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘
    ✔  All specs passed!                        03:47      148      148        -        -        -

```

## Wrapping things up

In this post, we looked into an interactive way to generate an application and use entity JDL extend to add business domain models. We also looked into generated UI and approaches to validate the generated code. As Svelte Hipster blueprint is an open-source project and under active development, you can also contribute to its growth. 

If you have a suggestion then, feel free to raise a [ticket](https://github.com/jhipster/generator-jhipster-svelte/issues). 

If you like the Svelte Hipster project then, give it a star on [GitHub](https://github.com/jhipster/generator-jhipster-svelte) and retweet this blog.

You can follow me on [Twitter](https://twitter.com/vishal423)