Deploying to Production
Deploying to a production server involves compiling and packaging the application to be suitable and optimized for the server.
While you may have launched your server directly from your IDE during development, for production you need to deploy the application as a WAR file (Java Servlet) or JAR file that includes your application server (Spring Boot & other embedded servers).
By default, Vaadin applications are set up to run in the development mode. This requires a bit more memory and CPU power, but enables easier debugging. When deploying your app to your users, you will want to switch to the production mode instead.
The main difference between the development and production modes is that in the development mode Vaadin uses webpack to serve JavaScript files to the browser, instead of the Java server the app is running on. This is so that if you change a JS or CSS file, your changes are picked up and served automatically. When in production mode, you do not want this extra overhead since the files will not change; it is more efficient to prepare JavaScript and CSS files once, during build, and let one server (the Java Server) serve all requests. At the same time, the client resources can be optimized and minified to reduce the load on the network and browser even further.
Enabling the Production Mode
The pom.xml
file in a Vaadin project has the following built-in Maven configuration for creating a production mode build:
pom.xml
<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 app is running in, but all of the variations do two things:
Setting the property
vaadin.productionMode
totrue
Calling the Maven goal
vaadin:build-frontend
. The Maven goalvaadin:prepare-frontend
is also required, but that is often declared already in the development build.
To create a production build, you can call mvn clean package -Pproduction
. This will build 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.
If you do not have the the production Maven profile in your POM 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 file.
Having production mode be a separate Maven profile is recommended so that you do not get any unexpected problems due to production settings when running in the development mode.
Note | Building for 64-bit If your operating system is 64-bit, make sure to use a 64-bit JDK installation as well. |
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 in the development mode.
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.
Splitting the Webpack Bundle Into Multiple Chunks
This is currently not possible. In case it would be important for you to be able to split the bundle, please let us know in the issue: https://github.com/vaadin/flow/issues/5537.
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 frontend dependencies and webpack which bundles the frontend files served to client.
Note | Automatic installation of Node.js and npm is available since Vaadin 14.2. Older platform versions in the 14 series requires manual installation, either globally or in the project directory using a Maven plugin. |
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 frontend. 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 wherepackage.json
file is located. Default is project root folder.webpackTemplate (default:
webpack.config.js
): Copy thewebapp.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 thewebapp.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
): Available since Vaadin 14.2. If set totrue
, always prefer Node.js automatically downloaded and installed into the.vaadin
directory in the user’s home.
build-frontend
This goal builds the frontend 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 ofwar
packaging istarget/${artifactId}-${version}/build
and in case ofjar
packaging istarget/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 frontend source files.
generateBundle (default: true
)
Whether to generate a bundle from the project frontend 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 embeddable web components from WebComponentExporter inheritors.
optimizeBundle (default: true
)
Whether to include only frontend 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 mode.
pnpmEnable (default: false
)
Whether to use the pnpm or npm tool to handle frontend resources. By default npm is used.