Correct setup of vaadin-maven-plugin?

I have a multi-module maven project where we use vaadin-maven-plugin in “ptsmc-widgetset”.
It is not a standalone project in itself, but a dependency for several of the other modules.

We do not use vaadin-dev, so when we build, we want to always build prod.bundle
We check in everything under src. Goal is that only one dev has to go through any node build, and we always get the exact same bundle.

I’m having several kinds of problems with this setup:

If I do “mvn clean package” on the top project, several files, like src\main\frontend\generated\index.tsx are deleted.
If I do “mvn clean package” on ptsmc-widgetset, they are restored.

If I do Alt-F5 on ptsmc-widgetset (or all) in Eclipse, the files are also deleted.

Trying to fix this I ended up in a variety of other situations:

  • prod.bundle was constantly changed
  • Everything looked fine, but Eclipse didn’t copy META-INF/VAADIN to target

So, struggling with the right invocations to get the behavior I want.

We’re on Vaadin 25.1.1

pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

	<parent>
		<groupId>com.ec.ptsmc</groupId>
		<artifactId>ptsmc-wildfly-parent</artifactId>
		<version>${revision}${sha1}${changelist}</version>
		<relativePath>../ptsmc-wildfly-parent</relativePath>
	</parent>

	<artifactId>ptsmc-widgetset</artifactId>
	<packaging>jar</packaging>

	<dependencies>

        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-core</artifactId>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <groupId>com.vaadin</groupId>
                    <artifactId>hilla-dev</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.vaadin</groupId>
                    <artifactId>vaadin-dev</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
           <groupId>software.xdev.vaadin.maps-leaflet</groupId>
           <artifactId>flow</artifactId>
        </dependency>

        <dependency>
            <groupId>com.vaadin.componentfactory</groupId>
            <artifactId>selection-grid-flow</artifactId>
            <version>${selection.grid.version}</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <!--
                Take care of synchronizing java dependencies and imports in
                package.json and main.js files.
                It also creates webpack.config.js if not exists yet.
            -->
            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-frontend</goal>
                            <goal>build-frontend</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <optimizeBundle>false</optimizeBundle>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

directory structure:

+---src
¦   +---main
¦       +---bundles
¦       ¦       prod.bundle
¦       ¦       
¦       +---frontend
¦       ¦   ¦   index.html
¦       ¦   ¦   ptsmc-split-layout.ts
¦       ¦   ¦   
¦       ¦   +---generated
¦       ¦   ¦   ¦   app-shell-imports.d.ts
¦       ¦   ¦   ¦   app-shell-imports.js
¦       ¦   ¦   ¦   css.generated.d.ts
¦       ¦   ¦   ¦   css.generated.js
¦       ¦   ¦   ¦   index.tsx
¦       ¦   ¦   ¦   layouts.json
¦       ¦   ¦   ¦   routes.tsx
¦       ¦   ¦   ¦   vaadin-featureflags.js
¦       ¦   ¦   ¦   vaadin-react.tsx
¦       ¦   ¦   ¦   vaadin.ts
¦       ¦   ¦   ¦   
...
¦       ¦               
¦       +---java
¦           +---com
¦               +---ptsmc
¦                   +---widgetset
¦                       +---splitlayout
¦                               PtsmcSplitLayout.java
¦                               
+---target
    ¦   ptsmc-widgetset-5.17.0-SNAPSHOT.jar
    ¦   vaadin-dev-server-settings.json
    ¦   
    +---classes
    ¦   +---com
    ¦   ¦   +---ptsmc
    ¦   ¦       +---widgetset
    ¦   ¦           +---splitlayout
    ¦   ¦                   PtsmcSplitLayout$Orientation.class
    ¦   ¦                   PtsmcSplitLayout$SplitterDragEndEvent.class
    ¦   ¦                   PtsmcSplitLayout.class
    ¦   ¦                   
    ¦   +---META-INF
    ¦       +---VAADIN
    ¦           +---config
    ¦           ¦       bundle-size.html
    ¦           ¦       stats.json
    ¦           ¦       
    ¦           +---webapp
    ¦               ¦   index.html
    ¦               ¦   index.html.br
    ¦               ¦   
    ¦               +---VAADIN
    ¦                   +---build
    ¦                   ¦       commonjsHelpers-CqkleIqs.js
    ¦                   ¦       commonjsHelpers-CqkleIqs.js.br
    ¦                   ¦       FlowBootstrap-DSmR1u5w.js
    ¦                   ¦       FlowBootstrap-DSmR1u5w.js.br
    ¦                   ¦       FlowClient-BVwyxPyR.js
    ¦                   ¦       FlowClient-BVwyxPyR.js.br
    ¦                   ¦       generated-flow-imports-BSycH1-g.js
    ¦                   ¦       generated-flow-imports-BSycH1-g.js.br
    ¦                   ¦       indexhtml-r929Ks8_.js
    ¦                   ¦       indexhtml-r929Ks8_.js.br
    ¦                   ¦       
    ¦                   +---static
    ¦                       +---themes
    ¦                           +---ptsmc
    ¦                                   theme.json
    ...

I’m also interested /following.

I gave up a long time ago and build the “widgetset” for each module independently.

Did you find this project? GitHub - viritin/widgetset: A pre-built Vaadin Flow widgetset for simple pure Java web apps, for developers who are too busy to wait for front-end build. · GitHub

In the examples there is a custom-widgetset, where there is on custom widget shared with different modules. To that one could also add addons. That is still on 24 series (the maven published version on the top level that I use on some demos and own tools is cut from some 25.2 version IIRC).

As something to use, or as a demonstration of how to make it work?

I’m happy enough to build our own bundle, and since we have a couple of extra dependencies I guess we also have to. The build is also way less painful than it used to be. All I’m missing is control and understanding.

Comparing your core\pom.xml with mine, I see the following differences:

  • <phase>prepare-package</phase>
  • <frontendDirectory>target</frontendDirectory>

Adding <phase> seems to do something. At least I’ve not lost the generated files yet.
Googling default phase for vaadin-maven-plugin I got:

  • prepare-frontend : process-resources
  • build-frontend : process-classes

I see that the compile phase comes between these two process- phases. That might explain why I’ve been losing files (assuming prepare-frontend deletes stuff, and we stop at compile)
I’ll check in this and see if it works for everyone.

I am also interested in this! From the point of view that it should work.

I am not 100% sure I understand the goal though. What do you want the “widgetset” module exactly to do? Should it deal with all frontend stuff and just be a Maven dependency in an “app” module which is then pure Java?

Exactly! For example we have a multi module project with a shared base module and 4 Vaadin application all depending on this module with their specific views
Everything is shared - deps, styling, components etc.

But strict security requirements are in place so that each user role has they dedicated application and later deployment.

e.g.:

  • app 1: normal users
  • app 2: central administration
  • app 3: agency administration
  • app 4: auditing
1 Like

As a demo how to set it up (the second link). My guess is that vast majority can’t cope with the fixed module that is also pushed to Maven central. That is very handy and fast for trivial demos and getting started, but very limited real use cases.

I’ll try to update that example project for 25 era, IIRC something had to be changed (but these are most likely logged in the upper level project).

Our widgetset is Vaadin itself + any other web components that need to be compiled into prod.bundle.
We use this as a dependency for several wars; Separate entrypoints to our application with differing access. Same as @knoobie described.

We keep the styling in the war’s src/main/webapp and out of the prod.bundle, so the bundle ends up being pretty static, which again means we don’t need the dev frontend hackery which is fortunate, since it works so poorly for our setup.

Finally, we package this as “skinnywar” ear, so that the final ear only has 1 copy of the widgetset and the vaadin jars.

The custom widgetset example now updated to 25.2 era. I also added one add-on to the widgetset module as a dependency. So the example has trivial color picker component in it + relative time add-on as a dependency (that gets its client side stuff compiled into the “widgetset”).