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
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
Within webpack.config.js
there are rules and plugin initialization changes.
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.
Within the list of plugins you'll need to:
- configure webpack to load your
index.pug
file rather than the Aurelia CLI defaultindex.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
.
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")));
}
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.