Asset Manifests with Swig Templates
I’m still using the Swig templating engine for my Node/Express apps and recently decided to streamline my asset caching process. I wanted a simple way to insert hashed assets into my templates but everything that Google came up with seemed a little too complicated. So I wrote a quick custom Swig tag to read from an asset manifest (in my case public/assets.json
generated by the Webpack Manifest Plugin):
let assets = require('../../public/assets.json');
module.exports = function (swig) {
swig.setTag('asset', _parse, _compile, false, true);
};
let _parse = function (str, line, parser) {
parser.on('*', function (token) {
let match = token.match.match(/^["'](.*?)["']$/);
let assetPath = match ? match[1] : null;
if (assetPath) {
let asset = assets[assetPath] || assetPath;
this.out.push(asset);
}
});
return true;
};
let _compile = function (compiler, args) {
if (!args || !args[0]) {
throw new Error('The asset tag expects a filename as a string');
}
let assetPath = args[0].startsWith('/') ? args[0] : '/' + args[0];
return `_output +="${assetPath}";`;
};
I keep this file in an app/helpers
directory and in app.js
my views are set up with the lines:
require('./app/helpers/assets')(swig);
app.engine('html', swig.renderFile);
app.set('view engine', 'html');
After that stylesheets or JavaScript can be added to any template using the unhashed name like so:
<script src="{% asset 'main.js' %}"></script>
<link rel="stylesheet" href="{% asset 'main.css' %}" />
Advertisement
Advertisement