# Modern Build Tools

Aurelia 2 provides official support for modern build tools that offer fast development servers, optimized builds, and excellent developer experience. Choose the tool that best fits your project needs and team preferences.

## Quick Start Recommendations

* **🚀 New Projects**: Use [Vite](#vite-recommended) for fastest development and modern features
* **🏢 Enterprise/Existing**: Use [Webpack](#webpack) for maximum configurability and ecosystem
* **⚡ Simple Projects**: Use [Parcel](#parcel) for zero-config builds

## Vite (Recommended)

Vite provides lightning-fast development with instant hot module replacement and optimized production builds. **Recommended for new projects.**

### Why Vite?

* ⚡ Instant server start and HMR
* 🎯 Modern ES modules in development
* 📦 Optimized Rollup builds for production
* 🔧 Minimal configuration required

### Installation

```bash
npm install -D @aurelia/vite-plugin vite
```

### Configuration

Create `vite.config.js`:

```js
import { defineConfig } from 'vite';
import aurelia from '@aurelia/vite-plugin';

export default defineConfig({
  plugins: [aurelia()],
  server: {
    port: 9000, // Optional: custom dev server port
    open: true  // Optional: auto-open browser
  },
  build: {
    target: 'es2020', // Modern browser support
    sourcemap: true   // Source maps for production debugging
  }
});
```

### TypeScript Support

For TypeScript projects, add this type declaration file:

**`src/html.d.ts`** (auto-generated by Aurelia CLI):

```typescript
declare module '*.html' {
  import { IContainer } from '@aurelia/kernel';
  import { BindableDefinition } from '@aurelia/runtime-html';
  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);
}
```

### Advanced Vite Configuration

```js
import { defineConfig } from 'vite';
import aurelia from '@aurelia/vite-plugin';

export default defineConfig({
  plugins: [
    aurelia({
      useDev: true,  // Force dev bundles (useful for debugging)
    })
  ],
  resolve: {
    alias: {
      '@': '/src',  // Path aliasing
    }
  },
  css: {
    modules: {
      localsConvention: 'camelCase'  // CSS Modules support
    }
  }
});
```

## Webpack

Webpack offers maximum configurability and is well-suited for complex applications with specific build requirements.

### Installation

```bash
npm install -D webpack webpack-cli webpack-dev-server
npm install -D @aurelia/webpack-loader ts-loader
```

### Basic Configuration

Create `webpack.config.js`:

```js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/main.ts',
  resolve: {
    extensions: ['.ts', '.js', '.html'],
    modules: [path.resolve(__dirname, 'src'), 'node_modules']
  },
  module: {
    rules: [
      // TypeScript files
      { 
        test: /\.ts$/i, 
        use: ['ts-loader', '@aurelia/webpack-loader'], 
        exclude: /node_modules/ 
      },
      // HTML templates
      { 
        test: /\.html$/i, 
        use: '@aurelia/webpack-loader', 
        exclude: /node_modules/ 
      },
      // CSS files
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'index.html'
    })
  ],
  devServer: {
    port: 9000,
    historyApiFallback: true, // SPA routing support
    open: true
  }
};
```

### Production Configuration

Create `webpack.prod.js` for optimized builds:

```js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

module.exports = {
  mode: 'production',
  entry: './src/main.ts',
  resolve: {
    extensions: ['.ts', '.js', '.html'],
    modules: [path.resolve(__dirname, 'src'), 'node_modules']
  },
  module: {
    rules: [
      { 
        test: /\.ts$/i, 
        use: ['ts-loader', '@aurelia/webpack-loader'], 
        exclude: /node_modules/ 
      },
      { 
        test: /\.html$/i, 
        use: {
          loader: '@aurelia/webpack-loader',
          options: {
            defaultShadowOptions: { mode: 'open' }, // Optional: Shadow DOM
            useCSSModule: false // Optional: CSS Modules
          }
        }, 
        exclude: /node_modules/ 
      }
    ]
  },
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'index.html',
      minify: true
    }),
    // Uncomment to analyze bundle size
    // new BundleAnalyzerPlugin()
  ]
};
```

## Parcel

Parcel offers zero-configuration bundling with excellent performance and modern features out of the box.

### Installation

```bash
npm install -D @aurelia/parcel-transformer parcel
```

### Configuration

Create `.parcelrc`:

```json
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.ts": ["@aurelia/parcel-transformer", "..."],
    "*.html": ["@aurelia/parcel-transformer", "..."]
  }
}
```

### Optional Package.json Configuration

Add Aurelia-specific options to `package.json`:

```json
{
  "aurelia": {
    "defaultShadowOptions": { "mode": "open" },
    "useCSSModule": false
  },
  "scripts": {
    "dev": "parcel index.html",
    "build": "parcel build index.html"
  }
}
```

### TypeScript Support

Add the same `html.d.ts` file as shown in the Vite section.

## Tool Comparison

| Feature               | Vite         | Webpack      | Parcel         |
| --------------------- | ------------ | ------------ | -------------- |
| **Development Speed** | ⚡ Fastest    | 🟡 Moderate  | ⚡ Fast         |
| **Production Builds** | 🎯 Excellent | 🎯 Excellent | 🎯 Good        |
| **Configuration**     | 🟢 Minimal   | 🔴 Complex   | 🟢 Zero-config |
| **Ecosystem**         | 🟡 Growing   | 🎯 Mature    | 🟡 Good        |
| **Hot Reload**        | ⚡ Instant    | 🟡 Good      | ⚡ Fast         |
| **Bundle Analysis**   | 🟢 Built-in  | 🎯 Excellent | 🟡 Basic       |
| **Learning Curve**    | 🟢 Easy      | 🔴 Steep     | 🟢 Easy        |

## Common Development Patterns

### Environment Variables

**Vite:**

```js
// vite.config.js
export default defineConfig({
  define: {
    __DEV__: JSON.stringify(process.env.NODE_ENV === 'development')
  }
});
```

**Webpack:**

```js
// webpack.config.js
const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    })
  ]
};
```

### CSS Processing

**Vite with PostCSS:**

```js
// vite.config.js
export default defineConfig({
  css: {
    postcss: {
      plugins: [
        require('autoprefixer'),
        require('cssnano')
      ]
    }
  }
});
```

**Webpack with PostCSS:**

```js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      }
    ]
  }
};
```

### Asset Handling

All bundlers automatically handle common assets:

```typescript
// Import images, fonts, etc.
import logo from './assets/logo.svg';
import styles from './component.module.css';

// Use in templates
export class MyComponent {
  logoUrl = logo;
  styles = styles;
}
```

## Performance Optimization

### Bundle Splitting

**Vite:**

```js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['@aurelia/kernel', '@aurelia/runtime'],
          ui: ['./src/components/index']
        }
      }
    }
  }
});
```

**Webpack:**

```js
module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  }
};
```

### Tree Shaking

All modern bundlers automatically tree-shake unused code. Ensure your imports are ES module compatible:

```typescript
// ✅ Good - allows tree shaking
import { DI } from '@aurelia/kernel';

// ❌ Avoid - imports entire module
import * as Aurelia from 'aurelia';
```

## Migration Between Tools

### From Create React App to Vite

1. Install Vite and Aurelia plugin
2. Move `public/index.html` to project root
3. Update imports to use `/src` instead of relative paths
4. Replace `react-scripts` commands with Vite commands

### From Webpack to Vite

1. Replace webpack configs with `vite.config.js`
2. Update dev scripts to use `vite` instead of `webpack-dev-server`
3. Convert webpack-specific features to Vite equivalents
4. Test that all dynamic imports still work

## Troubleshooting

### Common Issues

**Vite: "Failed to resolve import"**

```js
// Add to vite.config.js
export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  }
});
```

**Webpack: "Module not found"**

```js
// Add to webpack.config.js
module.exports = {
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules']
  }
};
```

**Parcel: "Cannot resolve dependency"**

```json
// Add to package.json
{
  "alias": {
    "@/*": "./src/*"
  }
}
```

### Development vs Production Differences

* **Development**: Use source maps, hot reload, and unminified code
* **Production**: Enable minification, tree shaking, and bundle splitting
* **Testing**: Consider using the same bundler for tests to catch bundler-specific issues

## Next Steps

* [Component Development Patterns](/developer-guides/component-library-development.md)
* [Performance Optimization](https://github.com/aurelia/aurelia/blob/master/docs/user-docs/developer-guides/scenarios/performance-optimization.md)
* [Deployment Strategies](https://github.com/aurelia/aurelia/blob/master/docs/user-docs/developer-guides/scenarios/production-deployment.md)

Choose your preferred build tool and start building amazing Aurelia applications! 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' })
]
```

}; };

````

### Advanced Configuration Options

#### Development Aliases
For development, you can alias Aurelia packages to their development builds for better debugging:

```js
// 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;
  }, {})
}
````

#### Hot Module Replacement (HMR)

To enable HMR for Aurelia components:

```js
// 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/
}
```

#### TypeScript Type Checking

For enhanced TypeScript support with template type checking:

```js
{
  test: /\.ts$/i,
  use: [
    'ts-loader',
    {
      loader: '@aurelia/webpack-loader',
      options: {
        experimentalTemplateTypeCheck: true
      }
    }
  ],
  exclude: /node_modules/
}
```

### Production Optimizations

* **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

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.

### Installing

```bash
npm install --save-dev @aurelia/vite-plugin
```

### Basic Usage

In `vite.config.js`:

```js
import { defineConfig } from 'vite';
import aurelia from '@aurelia/vite-plugin';

export default defineConfig({
  plugins: [aurelia()],
});
```

### TypeScript Support

For TypeScript apps, add this declaration file to your project (usually generated by the Aurelia CLI):

`html.d.ts`

```ts
declare module '*.html' {
  import { IContainer } from '@aurelia/kernel';
  import { BindableDefinition } from '@aurelia/runtime-html';
  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);
}
```

### Plugin Configuration Options

The Aurelia Vite plugin accepts several configuration options:

```js
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
    })
  ]
});
```

#### Development Configuration

By default, the Aurelia Vite plugin automatically uses development bundles when in development mode:

```js
export default defineConfig({
  plugins: [
    aurelia({
      useDev: true  // Force development bundles regardless of mode
    })
  ]
});
```

#### Production & Code Splitting

Vite automatically optimizes for production. You can customize chunk splitting:

```js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor': ['aurelia'],
          'router': ['@aurelia/router']
        }
      }
    }
  },
  plugins: [aurelia()]
});
```

#### Source Maps and Debugging

```js
export default defineConfig({
  build: {
    sourcemap: true  // Enable source maps in production
  },
  plugins: [aurelia()]
});
```

***

## Parcel

Parcel is a zero-configuration bundler that works well with Aurelia 2 through the official transformer.

### Installing

```bash
npm install --save-dev @aurelia/parcel-transformer
npm install --save-dev @parcel/transformer-typescript-tsc  # For TypeScript projects
```

### Configuration

Create a `.parcelrc` file in your project root:

```json
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.ts": ["@aurelia/parcel-transformer", "@parcel/transformer-typescript-tsc"],
    "*.html": ["@aurelia/parcel-transformer", "..."]
  }
}
```

For JavaScript projects:

```json
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.js": ["@aurelia/parcel-transformer", "..."],
    "*.html": ["@aurelia/parcel-transformer", "..."]
  }
}
```

### Package.json Configuration

You can configure Aurelia-specific options in your `package.json`:

```json
{
  "aurelia": {
    "hmr": true,
    "defaultShadowOptions": { "mode": "open" },
    "useCSSModule": false
  }
}
```

### TypeScript Support

For TypeScript projects, add the same `html.d.ts` declaration file mentioned in the Vite section.

***

## CSS and Styling

### CSS Modules

Aurelia supports CSS modules with proper bundler configuration:

```js
// Webpack
{
  test: /\.css$/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        modules: true
      }
    }
  ]
}

// Vite (built-in support)
// Just name your files with .module.css extension
```

### SCSS/SASS Support

Add SASS loaders for SCSS support:

```bash
npm install --save-dev sass sass-loader  # Webpack
npm install --save-dev sass              # Vite (built-in)
```

***

## Troubleshooting

### Common Issues

#### "Cannot resolve module" errors

* Ensure file extensions are properly configured in bundler resolve settings
* Check that Aurelia loaders are properly configured for HTML and TypeScript files

#### Slow development builds

* For Webpack: Enable `experiments.lazyCompilation` and proper development aliases
* For Vite: Ensure `useDev: true` is set in the Aurelia plugin options

#### HMR not working

* Verify HMR is enabled in both bundler and Aurelia loader configurations
* Check browser console for HMR-related warnings

#### TypeScript template errors

* Ensure proper HTML type definitions are included
* Consider enabling `experimentalTemplateTypeCheck` in webpack loader options

### Performance Tips

1. **Use development bundles**: Always alias to `.dev.mjs` files during development
2. **Enable code splitting**: Configure manual chunks for better loading performance
3. **Optimize assets**: Use appropriate loaders for images, fonts, and other assets
4. **Source map strategy**: Use `eval-cheap-source-map` for development, `source-map` for production

***

## Conclusion

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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aurelia.io/developer-guides/bundlers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
