Get the Newsletter

CLI's built-in Bundler Cookbook

Recipes for common usage of CLI's built-in bundler

Introduction

This page collects recipes for common usage of CLI's built-in bundler. Note all following recipes are not for using prepend.

  • Prepend is easier for some legacy JavaScript libraries.
  • Using CDN (Content Delivery Network) is easier for css libraries, specially for those with fonts and images.

jQuery

npm install jquery or yarn add jquery

    
  import $ from 'jquery';
  
  
    
  import * as $ from 'jquery';
  
  

normalize.css

npm install normalize.css or yarn add normalize.css

    
  <template>
    <require from="normalize.css"></require>
  </template>
  
  

normalize.css's package name is interesting, it has file extension .css which matches its main file node_modules/normalize.css/normalize.css. We can directly do <require from="normalize.css"></require> because .css tells Aurelia the correct file type, so Aurelia understands this is a css resource.

Full path <require from="normalize.css/normalize.css"></require> also works here.

For some npm package like some-css with main file node_modules/some-css/some.css, we cannot use <require from="some-css"></require> because Aurelia will mistake some-css as a JavaScript resource. We can only use <require from="some-css/some.css"></require>.

Bootstrap CSS v4

npm install jquery bootstrap popper.js

    
  import 'bootstrap'; // load bootstrap JavaScript
  
  
    
  import 'bootstrap'; // load bootstrap JavaScript
  
  
    
  <template>
    <require from="bootstrap/css/bootstrap.min.css"></require>
  </template>
  
  

Note both <require from="bootstrap/css/bootstrap.min.css"></require> and <require from="bootstrap/dist/css/bootstrap.min.css"></require> work.

Customize Bootstrap CSS v4

To customize Bootstrap, instead of using its CSS file, we need to use Bootstrap SCSS source files.

Start new app with au new demo, select following:

    1. Custom
    1. CLI's built-in bundler with RequireJS (or 3. SystemJS)
    1. Babel (or 2. TypeScript)
    1. Default (or 2, or 3)
    1. Sass
  • You choices on test, editor, then install dependencies with npm/yarn

npm install jquery bootstrap popper.js or yarn add jquery bootstrap popper.js

    
  import 'bootstrap'; // load bootstrap JavaScript
  
  
    
  import 'bootstrap'; // load bootstrap JavaScript
  
  
    
  // customize bootstrap to use 24 columns
  // check node_modules/bootstrap/scss/_variables.scss
  // for all possible customization
  $grid-columns: 24;
  // compile node_modules/bootstrap/scss/bootstrap.scss
  @import '../node_modules/bootstrap/scss/bootstrap';
  
  
    
  <template>
    <require from="./app.css"></require>
  </template>
  
  

With CLI Bundler, all scss files are compiled by aurelia_project/tasks/process-css.js before sending to bundler. CLI Bundler only sees the resulting app.css file not the source app.scss file. That's why we use ./app.css in app.html.

Difference with Webpack

Webpack behaves differently, it controls the whole scss compilation. With Webpack, you need <require from="./app.scss"></require> in app.html.

Bootstrap CSS v3 (legacy)

We need to use shim.

npm install jquery bootstrap@3.3.7 or yarn add jquery bootstrap@3.3.7

    
  "bundles": [
    // ...
    {
      "name": "vendor-bundle.js",
      "prepend": [ /* ... */ ],
      "dependencies": [
        // ...
        {
          "name": "bootstrap",
          "deps": ["jquery"],
          "path": "../node_modules/bootstrap",
          "main": "dist/js/bootstrap.min"
        }
      ]
    }
  ],
  "copyFiles": {
    "node_modules/bootstrap/dist/fonts/*": "bootstrap/fonts"
  }
  
  
    
  import 'bootstrap';
  
  
    
  import 'bootstrap';
  
  
    
  <template>
    <require from="bootstrap/css/bootstrap.min.css"></require>
  </template>
  
  

Note both <require from="bootstrap/css/bootstrap.min.css"></require> and <require from="bootstrap/dist/css/bootstrap.min.css"></require> work. But if you use bootstrap/dist/css/bootstrap.min.css, you need to adjust copyFiles target folder to bootstrap/dist/fonts.

    
  import $ from 'jquery';
  $('[data-toggle="popover"]').popover();
  
  
    
  import * as $ from 'jquery';
  $('[data-toggle="popover"]').popover();
  
  

Font Awesome v5 Free

npm install @fortawesome/fontawesome-free or yarn add @fortawesome/fontawesome-free

    
  "bundles": [
    // ...
  ],
  "copyFiles": {
    "node_modules/@fortawesome/fontawesome-free/webfonts/*": "@fortawesome/fontawesome-free/webfonts"
  }
  
  
    
  <template>
    <require from="@fortawesome/fontawesome-free/css/all.min.css"></require>
    optional v4-shims
    <require from="@fortawesome/fontawesome-free/css/v4-shims.min.css"></require>
    <i class="fas fa-cube"></i>
  </template>
  
  

Font Awesome v4

npm install font-awesome or yarn add font-awesome

    
  "bundles": [
    // ...
  ],
  "copyFiles": {
    "node_modules/font-awesome/fonts/*": "font-awesome/fonts"
  }
  
  
    
  <template>
    <require from="font-awesome/css/font-awesome.min.css"></require>
    <i class="fa fa-cube"></i>
  </template>
  
  

Foundation CSS v6

npm install jquery what-input foundation-sites or yarn add jquery what-input foundation-sites

    
  import 'what-input';
  import 'foundation-sites'; // load foundation JavaScript
  
  
    
  import 'what-input';
  import 'foundation-sites'; // load foundation JavaScript
  
  
    
  import $ from 'jquery';
  import Foundation from 'foundation-sites';
  
  export class App {
    attached() {
      // using ref="demo" in html template
      this.tooltip = new Foundation.Tooltip($(this.demo));
      // for better reuse, wrap foundation js features
      // behind Aurelia custom elements or attributes.
    }
    detached() {
      if (this.tooltip) {
        this.tooltip.destroy();
        this.tooltip = null;
      }
    }
  }
  
  
    
  import * as $ from 'jquery';
  import * as Foundation from 'foundation-sites';
  
  export class App {
    attached() {
      // using ref="demo" in html template
      this.tooltip = new Foundation.Tooltip($(this.demo));
      // for better reuse, wrap foundation js features
      // behind Aurelia custom elements or attributes.
    }
    detached() {
      if (this.tooltip) {
        this.tooltip.destroy();
        this.tooltip = null;
      }
    }
  }
  
  
    
  <template>
    <require from="foundation-sites/css/foundation.min.css"></require>
    <span ref="demo" data-tooltip class="top" tabindex="2" title="Fancy word for a beetle.">demo</span>
  </template>
  
  

Materialize CSS v1

npm install jquery materialize-css or yarn add jquery materialize-css

    
  import materialize from 'materialize-css';
  
  export class App {
    attached() {
      // using ref="modal" in html template
      materialize.Modal.init(this.modal);
      // for better reuse, wrap materialize js features
      // behind Aurelia custom elements or attributes.
    }
    detached() {
      const ins = materialize.Modal.getInstance(this.modal);
      if (ins) ins.destroy();
    }
  }
  
  
    
  import * as materialize from 'materialize-css';
  
  export class App {
    attached() {
      // using ref="modal" in html template
      materialize.Modal.init(this.modal);
      // for better reuse, wrap materialize js features
      // behind Aurelia custom elements or attributes.
    }
    detached() {
      const ins = materialize.Modal.getInstance(this.modal);
      if (ins) ins.destroy();
    }
  }
  
  
    
  <template>
    <require from="materialize-css/css/materialize.min.css"></require>
    <a class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>
    <div ref="modal" id="modal1" class="modal">
      <div class="modal-content">
        <h4>Modal Header</h4>
        <p>A bunch of text</p>
      </div>
      <div class="modal-footer">
        <a href="#!" class="modal-close waves-effect waves-green btn-flat">Agree</a>
      </div>
    </div>
  </template>
  
  

TypeORM with shimmed decorators

When using TypeORM in the frontend, you'll most likely experience issues due to leveraged node dependencies not available within the browser. To circumvent this import a wrapper instead. Most likely you're also going to share entities with your server part, so do not forget to add the paths entry in aurelia.json as well:

npm install typeorm or yarn add typeorm

    
  "bundles": [
    // ...
    {
      "name": "vendor-bundle.js",
      "prepend": [ /* ... */ ],
      "dependencies": [
        // ...
        {
          "name": "typeorm",
          "path": "../node_modules/typeorm",
          "main": "typeorm-model-shim"
        }
      ]
    }
  ],
  "paths": {
    ...
    "entities": "../../server/src/entity"
  }
  
  

This example expects the aurelia app and the node backend folder structure to located next to each other in frontend and respecitvely server, with server having subfolders src/entity containing all your entity files.

If you're using TypeScript for your project make sure to add an additional path mapping to your tsconfig.json as well:

    
  {
    ...
    "compilerOptions": {
      ...
      "paths": {
        "entities/*": ["../../server/src/entity/*"]
      },
      "baseUrl": "src"
    }
    ...
  }