Bundlers
A comprehensive guide for configuring different bundlers with Aurelia 2 applications, including Webpack, Vite, and Parcel.
Last updated
Was this helpful?
A comprehensive guide for configuring different bundlers with Aurelia 2 applications, including Webpack, Vite, and Parcel.
Last updated
Was this helpful?
Was this helpful?
Aurelia is a framework that prides itself on flexibility and minimal boilerplate. This flexibility extends to how you bundle and build your application. Whether you prefer Webpack, Vite, Parcel, or another bundler, Aurelia 2 offers a straightforward approach to configuration.
Bundling is the process of gathering your source code, templates, styles, and related assets into optimized sets of files that are easier for browsers to load. Below, we'll walk through common bundler choices in Aurelia 2 and how to integrate them.
Webpack is a powerful and widely used bundler that allows deep customization of your build. Below is an overview of how to set up and configure a basic Aurelia 2 app with Webpack.
npm install --save-dev webpack webpack-cli webpack-dev-server
npm install --save-dev @aurelia/webpack-loader ts-loader
The @aurelia/webpack-loader
is essential for properly processing Aurelia's HTML templates and TypeScript files with Aurelia-specific transformations.
Tip: If you are migrating from Aurelia 1, you may already have a
webpack.config.js
that you can adapt for Aurelia 2, but you'll need to update the loader configuration.
Here's a complete webpack configuration for Aurelia 2:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = function(env, { mode }) {
const production = mode === 'production';
return {
target: 'web',
mode: production ? 'production' : 'development',
devtool: production ? 'source-map' : 'eval-cheap-source-map',
entry: {
app: './src/main.ts'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: production ? '[name].[contenthash].bundle.js' : '[name].bundle.js'
},
resolve: {
extensions: ['.ts', '.js'],
modules: [path.resolve(__dirname, 'src'), 'node_modules']
},
devServer: {
historyApiFallback: true,
open: !process.env.CI,
port: 9000
},
module: {
rules: [
// Asset loaders
{ test: /\.(png|gif|jpg|cur)$/i, loader: 'url-loader', options: { limit: 8192 } },
{ test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
{ test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
{ test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'file-loader' },
// CSS handling
{ test: /\.css$/i, use: ['style-loader', 'css-loader'] },
// TypeScript + Aurelia loader
{
test: /\.ts$/i,
use: ['ts-loader', '@aurelia/webpack-loader'],
exclude: /node_modules/
},
// Aurelia HTML templates
{
test: /\.html$/i,
use: '@aurelia/webpack-loader',
exclude: /node_modules/
}
]
},
plugins: [
new HtmlWebpackPlugin({ template: 'index.html' })
]
};
};
For development, you can alias Aurelia packages to their development builds for better debugging:
// In resolve.alias section
alias: {
...[
'aurelia',
'fetch-client',
'kernel',
'metadata',
'platform',
'platform-browser',
'route-recognizer',
'router',
'router',
'runtime',
'runtime-html',
'testing',
'state',
'ui-virtualization'
].reduce((map, pkg) => {
const name = pkg === 'aurelia' ? pkg : `@aurelia/${pkg}`;
map[name] = path.resolve(__dirname, 'node_modules', name, 'dist/esm/index.dev.mjs');
return map;
}, {})
}
To enable HMR for Aurelia components:
// In devServer
devServer: {
hot: true,
historyApiFallback: true,
port: 9000
},
// In module rules for TypeScript
{
test: /\.ts$/i,
use: [
'ts-loader',
{
loader: '@aurelia/webpack-loader',
options: {
hmr: true // Enable HMR for Aurelia
}
}
],
exclude: /node_modules/
}
For enhanced TypeScript support with template type checking:
{
test: /\.ts$/i,
use: [
'ts-loader',
{
loader: '@aurelia/webpack-loader',
options: {
experimentalTemplateTypeCheck: true
}
}
],
exclude: /node_modules/
}
Minification: Webpack 5+ includes Terser plugin by default for production builds
Code Splitting: Configure optimization.splitChunks
for better caching
Source Maps: Use 'source-map'
for production debugging
Content Hashing: Use [contenthash]
in filenames for long-term caching
Vite is a fast, modern bundler (and dev server) that works excellently with Aurelia. Its plugin system provides quick project startup, HMR (Hot Module Replacement), and speedy builds.
npm install --save-dev @aurelia/vite-plugin
In vite.config.js
:
import { defineConfig } from 'vite';
import aurelia from '@aurelia/vite-plugin';
export default defineConfig({
plugins: [aurelia()],
});
For TypeScript apps, add this declaration file to your project (usually generated by the Aurelia CLI):
html.d.ts
declare module '*.html' {
import { IContainer } from '@aurelia/kernel';
import { BindableDefinition } from '@aurelia/runtime';
export const name: string;
export const template: string;
export default template;
export const dependencies: string[];
export const containerless: boolean | undefined;
export const bindables: Record<string, BindableDefinition>;
export const shadowOptions: { mode: 'open' | 'closed'} | undefined;
export function register(container: IContainer);
}
The Aurelia Vite plugin accepts several configuration options:
import { defineConfig } from 'vite';
import aurelia from '@aurelia/vite-plugin';
export default defineConfig({
plugins: [
aurelia({
// Always use development bundles
useDev: true,
// File inclusion/exclusion patterns
include: 'src/**/*.{ts,js,html}',
exclude: 'node_modules/**',
// Plugin execution order
pre: true,
// Enable/disable conventions
enableConventions: true,
// HMR configuration
hmr: true
})
]
});
By default, the Aurelia Vite plugin automatically uses development bundles when in development mode:
export default defineConfig({
plugins: [
aurelia({
useDev: true // Force development bundles regardless of mode
})
]
});
Vite automatically optimizes for production. You can customize chunk splitting:
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
'vendor': ['aurelia'],
'router': ['@aurelia/router-direct', '@aurelia/router']
}
}
}
},
plugins: [aurelia()]
});
export default defineConfig({
build: {
sourcemap: true // Enable source maps in production
},
plugins: [aurelia()]
});
Parcel is a zero-configuration bundler that works well with Aurelia 2 through the official transformer.
npm install --save-dev @aurelia/parcel-transformer
npm install --save-dev @parcel/transformer-typescript-tsc # For TypeScript projects
Create a .parcelrc
file in your project root:
{
"extends": "@parcel/config-default",
"transformers": {
"*.ts": ["@aurelia/parcel-transformer", "@parcel/transformer-typescript-tsc"],
"*.html": ["@aurelia/parcel-transformer", "..."]
}
}
For JavaScript projects:
{
"extends": "@parcel/config-default",
"transformers": {
"*.js": ["@aurelia/parcel-transformer", "..."],
"*.html": ["@aurelia/parcel-transformer", "..."]
}
}
You can configure Aurelia-specific options in your package.json
:
{
"aurelia": {
"hmr": true,
"defaultShadowOptions": { "mode": "open" },
"useCSSModule": false
}
}
For TypeScript projects, add the same html.d.ts
declaration file mentioned in the Vite section.
Aurelia supports CSS modules with proper bundler configuration:
// Webpack
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
// Vite (built-in support)
// Just name your files with .module.css extension
Add SASS loaders for SCSS support:
npm install --save-dev sass sass-loader # Webpack
npm install --save-dev sass # Vite (built-in)
Ensure file extensions are properly configured in bundler resolve settings
Check that Aurelia loaders are properly configured for HTML and TypeScript files
For Webpack: Enable experiments.lazyCompilation
and proper development aliases
For Vite: Ensure useDev: true
is set in the Aurelia plugin options
Verify HMR is enabled in both bundler and Aurelia loader configurations
Check browser console for HMR-related warnings
Ensure proper HTML type definitions are included
Consider enabling experimentalTemplateTypeCheck
in webpack loader options
Use development bundles: Always alias to .dev.mjs
files during development
Enable code splitting: Configure manual chunks for better loading performance
Optimize assets: Use appropriate loaders for images, fonts, and other assets
Source map strategy: Use eval-cheap-source-map
for development, source-map
for production
Aurelia 2 provides excellent bundler flexibility through dedicated loaders and plugins. Vite offers the fastest development experience with minimal configuration, while Webpack provides maximum customization options. Parcel offers a good middle ground with zero-configuration setup.
Key points to remember:
Always use the official Aurelia bundler plugins/loaders
Configure proper TypeScript declarations for HTML modules
Use development bundles during development for better debugging
Enable HMR for the best development experience
For advanced configurations and bundler-specific optimizations, refer to the official documentation of your chosen bundler alongside Aurelia's guides.