This article is part of a series of tutorials that show you how to develop your first application:
Goal
In this tutorial, we show you how to deploy the Hello World application. We use Vite to bundle the JavaScript and HTML files of our application.
Once you have set up the LuciadRIA license loading as explained in the Hello World tutorial, you can use LuciadRIA just as you would use any other third-party library.
Creating a production bundle with Vite
In the package.json file within our hello-world project, we add an NPM script to create a production build:
{
"scripts": {
"build": "vite build"
}
}
Now, we can run the build script:
npm run build
vite build generates a production version of our application in the dist folder.
The dist folder now holds an index.html file and an assets folder containing a hashed JavaScript bundle, such as assets/index-4a3f9c2b.js.
Unlike the src/index.js file that Vite serves directly, unbundled, during development, this bundle is a lot larger because it has all JavaScript
modules needed to run your application.
That includes imported modules from your application’s dependencies, like LuciadRIA.
vite build runs in production mode by default and applies extra optimizations to the bundle, such as minification and tree-shaking,
reducing the size of the bundle.
Vite also rewrites the <script> tag in dist/index.html to point to the hashed bundle file automatically, so you don’t have to update it by hand.
Deploying the application
To deploy the application, just copy the dist folder to your favorite web server for static files, Apache or NGINX for example.
For demonstration purposes, we start a simple NodeJS server that serves the dist directory:
npx serve ./dist -l 8000
|
Since we used the |
When we browse to http://localhost:8000, we see our Hello World application. We successfully deployed a production build of our application.
Using your deployment license in production
You must use your deployment license in production mode, but you probably still want to use your development license for development.
One of the ways to set this up is by defining a Vite resolve alias for the license file. In production mode, this alias resolves to your deployment license file. In development, it resolves to the development license file.
In the Hello World application, create a vite.config.js file with the following contents:
import path from 'path';
import { fileURLToPath } from 'url';
import { defineConfig } from 'vite';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export default defineConfig(({ mode }) => {
const isProduction = mode === "production";
// The '?raw' suffix must be part of the alias target, not the import specifier.
const riaDeploymentLicense = path.resolve(__dirname, "src/luciadria_deployment.txt?raw");
const riaDevelopmentLicense = path.resolve(__dirname, "src/luciadria_development.txt?raw");
return {
resolve: {
alias: {
"ria-license": isProduction ? riaDeploymentLicense : riaDevelopmentLicense
}
}
};
});
|
The |
Next, update the license import in src/license-loader.js:
import {setLicenseText} from "@luciad/ria/util/License.js";
import license from 'ria-license'; // alias for actual license, see vite.config.js' resolve.alias
setLicenseText(license);
Now we use the deployment license file in production mode. We still use the development license file during development.
|
If you do not explicitly set the license as shown above, LuciadRIA will search for it in its default location. It will
first check for |
Trading off build times and bundle sizes
In this section we take a look at how we can trade off build time against bundle size.
|
The configuration updates in this section are optional. The default Vite configuration of the earlier sections will serve you just fine. This section only gives you some insight in how to further tune build time and bundle sizes, if you need to. |
By default, vite build minifies your production bundle using esbuild, which is much faster than the Terser-based minification tools older bundlers such as webpack use by default.
Note that each LuciadRIA module is already optimized, so re-minifying those modules results in only a minor reduction in bundle
size, and esbuild’s speed means you rarely need to trade anything off at all.
If you still want finer control, for example to keep the LuciadRIA modules in their own cacheable chunk that doesn’t change
as often as your application code, you can use the manualChunks option, which Vite exposes through build.rollupOptions:
import path from 'path';
import { fileURLToPath } from 'url';
import { defineConfig } from 'vite';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export default defineConfig(({ mode }) => {
const isProduction = mode === "production";
const riaDeploymentLicense = path.resolve(__dirname, "src/luciadria_deployment.txt?raw");
const riaDevelopmentLicense = path.resolve(__dirname, "src/luciadria_development.txt?raw");
return {
resolve: {
alias: {
"ria-license": isProduction ? riaDeploymentLicense : riaDevelopmentLicense
}
},
build: {
rollupOptions: {
output: {
manualChunks(id) {
// split LuciadRIA into its own chunk
if (id.includes("@luciad/ria")) {
return "ria-modules";
}
}
}
}
}
};
});
Unlike webpack, Vite doesn’t let you selectively skip minification for a single chunk — build.minify applies to the whole bundle.
That’s rarely a problem in practice, since esbuild’s minification is fast enough that excluding LuciadRIA from it saves very
little build time.
The main benefit of splitting LuciadRIA into its own chunk is caching: browsers can keep reusing the cached ria-modules chunk across deployments as long as your LuciadRIA dependency version doesn’t change, even when your own application code
does.
You don’t need to update index.html for this: Vite analyzes the module graph during the build and automatically injects the right <script> and pre-load tags for every chunk, including ria-modules.