# 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](https://docs.aurelia.io/developer-guides/component-library-development)
* [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.
