Configuring Pug with Webpack 4 and the Aurelia CLI

Configuring Pug with Webpack 4 and the Aurelia CLI

Recently I needed to build an app with the Aurelia framework using Pug (formerly known as Jade). If you never heard about Aurelia, it’s one of those front-end frameworks that never get the chance to be popular as React, Angular or Vue.js and slowly falling with slow support, bad documentation and latest major version published a year ago.

The challenge with old frameworks is that there is no community, outdated guides and underdeveloped documentation. There was a GitHub how-to add Pug which now or never worked at least for me.

After all the ranting let me guide you through bootstrapping Aurelia with Pug:

Install Aurelia app

First, we need to create Aurelia app and to do that, we will use the help of Aurelia Cli which after 4 years got its first non beta version. We need to install globally the NPM package:

npm install aurelia-cli -g

To create a project type au new then we follow the wizard.

  1. Choose the project name
  2. Choose between default setups, I will go with Custom App.

    • If you choose the Default configuration, the wizard ask you to install NPM dependencies and will finish.
  3. Next step is to choose between Webpack and an AMD module loader. Will go with Webpack as I never heard about the second option.
  4. Choose HTTP Protocol, if you are not supporting legacy browsers and have SSL certificate use HTTP/2. If you are unsure use HTTP/1.1, but I recommend you to do the research.
  5. For this example we will choose simple web app without .Net Core.
  6. For simplicity we will choose Babel, but should be no difference if you go with TypeScript.
  7. Next will go with No markup processing.
  8. Doesn’t matter what will chose I always go with Sass.
  9. And will you Typical settings with autoprefixer and minification.
  10. Will skip testing.
  11. And integration testing.
  12. Will use VSCode as my editing tool.
  13. Will use the bare minimum Aurelia app configuration.
  14. Finally, will install all npm dependencies.

Install needed dependencies

After finishing the wizard we need to install 2 more packages related to the Pug’s template engine.

  1. Install Pug: npm install pug
  2. Install Pug HTML loader for webpack: npm install pug-html-loader

I waste fine amount of time fallowing other guides using loaders like: pug-loader and apply-loader.

Configured webpack.config.js

In module.rules array add the following object.

{
  test: /\.pug$/,
  exclude: ["/node_modules/"],
  use: [
    "html-loader",
    {
      loader: "pug-html-loader",
      options: {
        data: {
          metadata: { title, server, baseUrl }
        }
      }
    }
  ]
}

Basically, this means that will find all Pug files excluding node modules and will use HTML and Pug loaders. Will will leave the HTML-loader because sometimes there are dependencies that will use HTML files.

In module.plugins will replace new AureliaPlugin(), with: new AureliaPlugin( { viewsExtensions: [‘.pug‘, ‘.html‘] } ),. This will tell Webpack that all views are Pug or HTML files. Next will change the content of the HtmlWebpackPlugin. Replace current block of code:

new HtmlWebpackPlugin({
  template: ‘index.ejs’,
  metadata: {
    // available in index.ejs //
    title, server, baseUrl
  }
}),

with:

new HtmlWebpackPlugin({
  template: ‘index.pug’,
  inject: true
}),

This will change the index file from ejs to pug and will inject all dependent files like styles and scripts into pug files. Note we moved metadata object with properties title, server, baseUrl in the rules and omitted here in the HtmlWebpackPlugin

Converting files

app.html

Rename app.html to app.pug. And change the content from:

<template>
    <h1>${message}</h1>
</template>

to:

template
  h1 ${message}

index.ejs

Rename index.ejs to index.pug. And change the content from:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title><%- htmlWebpackPlugin.options.metadata.title %></title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <base href="<%- htmlWebpackPlugin.options.metadata.baseUrl %>“>
    <!-- imported CSS are concatenated and added automatically -->
  </head>
  <body aurelia-app=”main">
  </body>
</html>

to:

doctype html
html
  head
    meta(charset='utf-8')
    title= metadata.title
    meta(name='viewport' content='width=device-width, initial-scale=1')
    base(href=metadata.baseUrl)
  body(aurelia-app='main')

main.js

We a way to set Aurelia where to look for pug files. We can do this in the main.js file using the ViewLocator Class with its method convertOriginToViewUrl. The method is using to convert a view model origin to a view URL. In main.js you need to import ViewLocator Class and add it as shown below:

import ‘regenerator-runtime/runtime’;
import environment from./environment’;
import {PLATFORM} from ‘aurelia-pal’;
import {ViewLocator} from ‘aurelia-framework’

export function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .feature(PLATFORM.moduleName(‘resources/index’));

  aurelia.use.developmentLogging(environment.debug ? ‘debug’ : ‘warn’);

  if (environment.testing) {
    aurelia.use.plugin(PLATFORM.moduleName(‘aurelia-testing’));
  }

  ViewLocator.prototype.convertOriginToViewUrl = function (origin) {
    let moduleId = origin.moduleId;
    let id = (moduleId.endsWith(.js’) || moduleId.endsWith(.ts’)) ? moduleId.substring(0, moduleId.length - 3) : moduleId;
    return id +.pug’;
  }

  aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName(‘app’)));
}

That's it we finally have an working Aurelia app working with Webpack and Pug.

Related articles

© 2019 All rights reserved.