Skip to content

Latest commit

 

History

History
228 lines (185 loc) · 5.98 KB

how-to-add-pug-to-cli-with-webpack.md

File metadata and controls

228 lines (185 loc) · 5.98 KB

Configuring Pug and Stylus with Webpack and the Aurelia CLI

The Aurelia CLI (currently v1.0.2) does not directly support Pug templates. Here we show how to modify webpack.config.js and organize a project with pug and stylus support. This example should help with any html or css preprocessor.

The configuration:

  • adds pug support
  • shows use of HTML and CSS preprocessors in the same project

Configure

Create a new aurelia project using the Aurelia CLI. These are the options used in this example.

  • Custom App
  • Bundler - Webpack
  • HTTP Protocol - either
  • What platform are you targeting? - Web
  • Transpiler - Your choice
  • HTML template setup - None
  • CSS preprocessor - Stylus is what I am using in this example
  • PostCSS processing - Typical
  • Unit test runner - Your choice
  • Configure integration testing - Your choice
  • Default code editor - Your choice
  • Features scaffolded into project? - Minimum

Within the project folder, add the following dependencies. pug is needed to process pug files, and pug-html-loader is needed to load pug files into webpack.

npm install -D pug pug-html-loader

webpack.config.js

Within webpack.config.js there are rules and plugin initialization changes.

Rules

In the module.rules array you should modify the .css and .styl rules to test for pug as well as html files.

rules: [
  {
    test: /\.css$/i,
    issuer: [{ not: [{ test: /\.(html|pug)$/i }] }],  // <-- modify
    use: extractCss
      ? [ { loader: MiniCssExtractPlugin.loader }, 'css-loader' ]
      : ['style-loader', ...cssRules]
  },
  {
    test: /\.css$/i,
    issuer: [{ test: /\.(html|pug)$/i }],             // <-- modify
    use: cssRules
  },
  {
    test: /\.styl$/i,
    use: extractCss
      ? [ { loader: MiniCssExtractPlugin.loader }, ...cssRules, 'stylus-loader' ]
      : ['style-loader', ...cssRules, 'stylus-loader'],
    issuer: /\.[tj]s$/i
  },
  {
    test: /\.styl$/i,
    use: ['css-loader', 'stylus-loader'],
    issuer: /\.(html|pug)$/i                          // <-- modify
  },

Also add pug-html-loader to the front of the .html loaders list.

  {
    test: /\.html$/i,
    loader: ["html-loader", "pug-html-loader"]
  },

And of course add this new .pug rule.

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

Note above how we are passing variables to the pug pages using options. These are just variables available within the webpack.config.js file.

Plugins

Within the list of plugins you'll need to:

  • configure webpack to load your index.pug file rather than the Aurelia CLI default index.ejs file
  • tell Aurelia that your view files are .pug or .html files
  plugins: [
    new HtmlWebpackPlugin({
      template: 'index.pug',
      inject: true
    })
    new AureliaPlugin( { viewsExtensions: ['.pug' ,'.html']} ),
    // ...

Note that we have moved the metadata object with it's properties title, server, and baseUrl to rules and omitted them here in the HtmlWebpackPlugin.

Converting Files

Replace app.html

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

with app.pug

template
  require(from='app.styl')
  h1 ${message}
  p #{metadata.title}
  p #{metadata.server}

and create app.styl

body {
  color: green;
}

Replace index.ejs with index.pug. Note that we've added a few additional script include elements for illustrative purposes. These include references are to files stored within your project.

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)
    script
      include javascripts/fontawesome-config.js
    script
      include javascripts/google-tag-manager.js
    script(defer src='https://use.fontawesome.com/releases/v5.0.2/js/all.js')
    script
      include javascripts/intercom.js

    // imported CSS are concatenated and added automatically

  body(aurelia-app='main')
    // Webpack Dev Server reload
    if (metadata.server)
      script(src='/webpack-dev-server.js')

In main.ts we need a bit of additional config to associate views with pug. Here we've added the method convertOriginToViewUrl to ViewLocator.

import { Aurelia, ViewLocator } from "aurelia-framework";
import environment from "./environment";
import { PLATFORM } from "aurelia-pal";

export function configure(aurelia: 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")));
}

Global Resources

Aurelia requires that you declare your project's global components. In cases where there are no associated .js files, you will need to declare your component using a .pug extension rather than .html extension.