Vite Configuration
Each and every project will be unique regarding structure, expected outputs and general development needs. The following is intended to provide coverage for general expectations using Adobe's AEM Archetype as a reference.
Recommended configuration
Below is an example vite.config.js
which intentionally uses the vite-tsconfig-paths
as Adobe have adopted TypeScript in their archetype.
What you can see is the same output structures being used align to the structure described previously. Some other things that are also going on:
- Sets the
base
path correctly for bothcommand
types - Sets the
publicDir
path tosrc/assets
. Change this to match your source structure - Disables brotli compression calculations (saves 2-5 seconds per prod build)
- Disables the
manifest.json
file - Disables minification when running in development mode
- Disables sourcemaps when not using the Vite DevServer
- Prefer
terser
overesbuild
for minification - Enfore the server origin for static assets via
server.origin
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig(({ command, mode }) => ({
base: command === 'build' ? '/etc.clientlibs/<project>/clientlibs/' : '/',
publicDir: command === 'build' ? false : 'src/assets',
build: {
brotliSize: false,
manifest: false,
minify: mode === 'development' ? false : 'terser',
outDir: 'dist',
sourcemap: command === 'serve' ? 'inline' : false,
rollupOptions: {
output: {
assetFileNames: 'clientlib-site/resources/[ext]/[name][extname]',
chunkFileNames: 'clientlib-site/resources/chunks/[name].[hash].js',
entryFileNames: 'clientlib-site/resources/js/[name].js',
},
},
},
plugins: [tsconfigPaths()],
server: {
origin: 'http://localhost:3000',
},
}));
See module imports which explains the reasoning behind the rollup output
structure.
Base path
A base
path is required to support static assets and dynamic imports as it will ensure that certain files are loaded from the correct AEM path.
Specific build modes
By default Vite runs its DevServer in development mode, but standard builds always run in production which is fine for non-AEM projects whereas AEM needs more control. The above configuration enables us to do things like the below.
vite build --mode development
# or
vite build --mode production
Now that you can build both development and production bundles, you can toggle between having features such as sourcemaps and console logging if you wish to test code outside of Vite's DevServer.
Source structure
Where your inputs come from isn't important as Vite simply consumes anything you provide to it. It is, however, recommended that you consider your main website CSS and JavaScript separate entries.
The below example demonsrates this but you will need to keep in mind that the input
keys should be unqiue otherwise rollup will automatically append an number to the end of the filename. See rollup's input documentation for more information.
export default defineConfig(() => ({
build: {
rollupOptions: {
input: {
bundle: 'src/main/webpack/js/app.ts',
styles: 'src/main/webpack/css/app.scss',
},
},
},
}));
Making CSS its own entry
Due to how AEM handles CSS it is not recommended to import it directly in your JavaScript modules as this can result in undesired outputs. For consistency, you main CSS outputs should be declared explicitly in your Vite rollupOptions.input
object. All other CSS specific to things such as React can be imported directly via JavaScript.
Plugins
Please refer to Vite's plugin documentation for instructions on using plugins in Vite.
Code output
The process of how your bundled code gets handled shouldn't change if you won't need it to. The design of AEM Vite enables you to use any structure you wish but recommends ours for the best compatibility. Tools such as Adobe's aem-clientlib-generator
will work perfectly fine with AEM Vite as it is executed after a build.
DevServer
If you want to customise how the Vite DevServer behaves you can do so via Vite's server
configuration. By default Vite will attempt to start the server on port 3000
but will automatically increment to the next available port if 3000
is already in use. To ensure this doesn't happen, it is recommended to set a more specific port that you don't expect to change.
Please refer to Vite's server api documention for more information.
export default defineConfig(() => ({
server: {
port: 5000,
},
}));
Static assets
Vite supports static assets without any configuration which works for external projects, but not AEM. To ensure static assets are served correctly in AEM you can use a configuration like the below.
export default defineConfig(({ command }) => ({
base: command === 'build' ? '/etc.clientlibs/<project>/clientlibs/' : '/',
build: {
assetsDir: 'clientlib-site/resources/static',
rollupOtions: {
assetFileNames(chunk) {
return chunk.name?.endsWith('.css')
? 'clientlib-site/resources/css/[name][extname]'
: 'clientlib-site/resources/static/[name].[hash][extname]';
},
}
},
}));
What this does is:
- Sets the base url for assets to
clientlib-site/resources/static
when runningbuild
, notserve
- Allow CSS and other assets to be separated which avoids everything been dumped into the
base
folder