Get the Newsletter

A Basic Example

If you're interested in setting up Webpack from scratch to build projects, this article will give you everything you need to know.

Introduction

To get Aurelia running with Webpack, there are only 2 Aurelia-specific details you need to know:

  • The app entry point must be 'aurelia-bootstrapper'.
  • aurelia-webpack-plugin must be added to your configuration.

PLATFORM.moduleName

From your application's perspective, there is also one important detail: each module reference must be wrapped in PLATFORM.moduleName(...). This allows aurelia-loader-webpack to translate Aurelia's conventions to something Webpack understands.

Examples

    
  // globalResources
  aurelia.use.globalResources([
    './my-custom-element' // WRONG
  ])
  aurelia.use.globalResources([
    PLATFORM.moduleName('./my-custom-element') // OK
  ])
  
  // setRoot
  aurelia.setRoot('app') // WRONG
  aurelia.setRoot(PLATFORM.moduleName('app')) // OK
  
  // features
  aurelia.use.feature('./my-awesome-feature') // WRONG
  aurelia.use.feature(PLATFORM.moduleName('./my-awesome-feature')) // OK
  
  // plugins
  aurelia.use.plugin('some-awesome-plugin') // WRONG
  aurelia.use.plugin(PLATFORM.moduleName('some-awesome-plugin')) // OK
  
  // router configuration
  config.map([
    {
      route: '',
      moduleId: 'pages/home' // WRONG
    }
  ])
  config.map([
    {
      route: '',
      moduleId: PLATFORM.moduleName('pages/home') // OK
    }
  ])
  
  

Webpack Documentation

For everything else related to optimizations, loaders, and so forth, kindly consult the official Webpack documentation. We haven't provided those details here since any Webpack-specific documentation would be duplicated effort and likely become stale in time.

Useful Links

Basic Config Example

Below is a basic webpack.config.js for a TypeScript project that supports two modes:

  • webpack-dev-server will start a development server and watch for file changes.
  • webpack --env=production only builds the bundle with production optimizations enabled.
    
  const { AureliaPlugin } = require('aurelia-webpack-plugin');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
  const { resolve } = require('path');
  
  module.exports = function (mode) {
    return {
      mode: mode || 'development',
      resolve: {
        extensions: ['.ts', '.js'],
        modules: [
          resolve(__dirname, 'src'),
          resolve(__dirname, 'node_modules')
        ]
      },
      entry: {
        // the 'aurelia-bootstrapper' entry point is responsible for resolving your app code
        app: ['aurelia-bootstrapper']
      },
      output: {
        filename: '[name].js',
        path: resolve(__dirname, 'dist')
      },
      watch: mode === 'development',
      devtool: mode === 'development' ? 'inline-source-map' : 'source-map',
      devServer: {
        contentBase: './dist'
      },
      module: {
        rules: [
          { test: /\.html$/i, loader: 'html-loader' },
          { test: /\.ts$/i, loader: 'ts-loader' }
        ]
      },
      plugins: [
        // the AureliaPlugin translates Aurelia's conventions to something Webpack understands
        // and must be included in order for Webpack to work
        new AureliaPlugin(),
        new HtmlWebpackPlugin({
          template: 'index.ejs',
          metadata: { dev: mode !== 'production' }
        })
      ]
    };
  };
  
  

Other Files Used

    
  {
    "scripts": {
      "build": "webpack --env=production",
      "dev": "webpack-dev-server"
    },
    "dependencies": {
      "aurelia-bootstrapper": "^2.3.0",
      "aurelia-framework": "^1.3.0"
    },
    "devDependencies": {
      "@types/node": "^10.12.2",
      "aurelia-webpack-plugin": "^3.0.0",
      "html-loader": "^0.5.5",
      "html-webpack-plugin": "^3.2.0",
      "ts-loader": "^5.3.0",
      "typescript": "^3.1.6",
      "webpack-cli": "^3.1.2",
      "webpack-dev-server": "^3.1.10",
      "webpack": "^4.24.0"
    }
  }
  
  
    
  {
    "compilerOptions": {
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true,
      "importHelpers": true,
      "lib": ["es2016", "dom"],
      "module": "esnext",
      "moduleResolution": "node",
      "sourceMap": true,
      "target": "es2016"
    },
    "include": ["src"]
  }
  
  
    
  <!DOCTYPE html>
  <html>
  <head>
    <meta charset="utf-8">
    <title>Aurelia</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <div aurelia-app="main">
      <% if (htmlWebpackPlugin.options.metadata.dev) { %>
        <script src="/webpack-dev-server.js"></script>
      <% } %>
    </div>
  </body>
  </html>
  
  
    
  import { Aurelia, PLATFORM } from 'aurelia-framework';
  
  export async function configure(au: Aurelia) {
    au.use.standardConfiguration();
    au.use.developmentLogging();
  
    await au.start();
    await au.setRoot(PLATFORM.moduleName('app')); // Note the PLATFORM.moduleName
  }
  
  
    
  export class App {
    message = 'Hello world!';
  }
  
  
    
  <template>
    ${message}
  </template>