Production Build

To create a production build, run the following command:

mvn clean package -Pproduction

This builds a JAR or WAR file with all the dependencies and transpiled front-end resources, ready to be deployed. The file can be found in the target folder after the build completes.

Enabling Production Builds

The production build command should work out of the box for Vaadin starter projects, for example, ones that are generated with start.vaadin.com. The starter projects come with the necessary Maven configuration. If you have created your project’s pom.xml file manually, add the following Maven profile to enable production builds:

<profiles>
    <profile>
        <id>production</id>
        <properties>
            <vaadin.productionMode>true</vaadin.productionMode>
        </properties>

        <!--
		.. configuration depending on environment ..
		 -->
         <executions>
             <execution>
                 <goals>
                     <goal>build-frontend</goal>
                 </goals>
                 <phase>compile</phase>
             </execution>
         </executions>
		 <!--
		 .. more configuration ..
		 -->
    </profile>
</profiles>

The actual content of the profile will depend on what environment your application is running in, but all of the variations do two things:

  1. Set the property vaadin.productionMode to true

  2. Call the Maven goal vaadin:build-frontend. The Maven goal vaadin:prepare-frontend is also required, but that is often declared already in the development build.

Once the Maven profile is added, you can call the production build command.

If you do not have the production Maven profile in your pom.xml file, the easiest way to get it is to get a project base from https://start.vaadin.com (for Spring Boot projects) or from https://vaadin.com/hello-world-starters (for other stacks such as Jakarta EE, or plain Java), and then copy the production profile from the downloaded pom.xml file.

Having the production build as a separate Maven profile is recommended to avoid unexpected problems due to production settings during development.

Note
Building for 64-bit
If your operating system is 64-bit, make sure to use a 64-bit JDK installation as well.

Excluding the Development Server Module

The webpack server integration and live reload features, which are available only in development builds, are contained in the module com.vaadin:vaadin-dev-server. When building the application for production, it is recommended to exclude this module. This can be achieved by adding the following dependency exclusion to the <dependencies> section in the production profile:

<profiles>
    <profile>
        <id>production</id>

        <!-- above production build configuration -->

        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin</artifactId>
                <exclusions>
                    <exclusion>
                        <groupId>com.vaadin</groupId>
                        <artifactId>vaadin-dev-server</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </profile>
</profiles>

This results in less code and dependency libraries being bundled in the production application.

Transpilation and Bundling

Transpilation in Vaadin means converting all ES6 JavaScript to ES5 JavaScript format for older browsers. All Vaadin components are written using ES6, and consist of several JavaScript and CSS files. Transpilation makes sure this newer JavaScript code also works in browsers which do not support all the latest JavaScript features.

During the build, minimization is done to make the files smaller. When minifying code, it is often obscured, which makes it harder to read, hence this is not done for development builds.

Bundling is an optimization where we merge multiple files to a single collection so that the browser doesn’t need to request so many files from the server. This makes the application load faster.

Plugin Goals and Goal Parameters

prepare-frontend

This goal validates whether the node and npm tools are installed and not too old (node version 10 or later and npm version 5.6 or later), and also installs them automatically to the .vaadin folder in the user’s home directory if they are missing. If they are installed globally but too old, there will be an error message suggesting to install newer versions instead. Node.js is needed to run npm for installing front-end dependencies and webpack which bundles the front-end files served to client.

In addition, it visits all resources used by the application and copies them under node_modules folder so they are available when webpack builds the front end. It also creates or updates package.json, webpack.config.json and webpack.generated.json files.

Goal Parameters

  • includes (default: **/*.js,**/*.css): Comma separated wildcards for files and directories that should be copied. Default is only .js and .css files.

  • npmFolder (default: ${project.basedir}): The folder where package.json file is located. Default is project root folder.

  • webpackTemplate (default: webpack.config.js): Copy the webapp.config.js from the specified URL if missing. Default is the template provided by this plugin. Set it to empty string to disable the feature.

  • webpackGeneratedTemplate (default: webpack.generated.js): Copy the webapp.config.js from the specified URL if missing. Default is the template provided by this plugin. Set it to empty string to disable the feature.

  • generatedFolder (default: ${project.build.directory}/frontend/): The folder where Flow will put generated files that will be used by webpack.

  • require.home.node (default: false): If set to true, always prefer Node.js automatically downloaded and installed into the .vaadin directory in the user’s home.

build-frontend

This goal builds the front-end bundle. This is a complex process involving several steps:

  • update package.json with all @NpmPackage annotation values found in the classpath and automatically install these dependencies.

  • update the JavaScript files containing code for importing everything used in the application. These files are generated in the target/frontend folder, and will be used as entry point of the application.

  • create webpack.config.js if not found, or updates it in case some project parameters have changed.

  • generate JavaScript bundles, chunks and transpile to ES5 using webpack server. Target folder in case of war packaging is target/${artifactId}-${version}/build and in case of jar packaging is target/classes/META-INF/resources/build.

Goal Parameters

npmFolder (default: ${project.basedir}

The folder where package.json file is located. Default is project root folder.

generatedFolder (default: ${project.build.directory}/frontend/)

The folder where Flow will put generated files that will be used by webpack.

frontendDirectory (default: ${project.basedir}/frontend)

A directory with project’s front-end source files.

generateBundle (default: true)

Whether to generate a bundle from the project front-end sources or not.

runNpmInstall (default: true)

Whether to run pnpm install (or npm install, depending on pnpmEnable parameter value) after updating dependencies.

generateEmbeddableWebComponents (default: true)

Whether to generate embedded web components from WebComponentExporter inheritors.

optimizeBundle (default: true)

Whether to include only front-end resources used from application entry points (the default) or to include all resources found on the class path. Should normally be left to the default, but a value of false can be useful for faster production builds or debugging discrepancies between development and production builds.

pnpmEnable (default: false)

Whether to use the pnpm or npm tool to handle front-end resources. By default npm is used.

useGlobalPnpm (default: false)

Whether to use a globally installed pnpm tool instead of the default supported version of pnpm.

clean-frontend

This goal will clean-frontend files that may cause inconsistencies when changing versions. It is suggested to not add the goal as a default to pom.xml and instead use it with mvn vaadin:clean-frontend when necessary.

Executing the clean-frontend goal will remove

  • the package lock file

  • the generated front-end folder (by default frontend/generated)

  • node_modules folder (this might need manual deletion)

The goal will also clean all dependencies that are framework managed, and any dependencies that target the build folder from the package.json file.

The clean-frontend goal supports the same parameters as prepare-frontend.