Search code examples
javascriptpugparcel

Compiling client-site pug templates into modules


I am serving a web app using Node.js, Express, Parcel and Pug and it all runs very well.

Parcel is bundling up my JS up to a point where I am quite satisfied.

However, I also do some client side templating, and that is only going to increase. I currently compile cs pug template using this solution using the pug-cli package (there is also an alternate solution available here using pugtalizer); however either solution compiles pug templates into JS with the template function in the global namespace that I can only access when loading the template function via the HTML <script> tag.

This results in me having to load several JS files, which defies the whole attempt to bundle up all JavaScript into one bundle using Parcel.

How can I import (i.e. using ES6 import()) the template file in my cs javascript so that it gets bundled?

UPDATE

I just analysed the compiled template function. I reformatted it, so as to better analyse what's going on, and added a simple export command to the compiled template file at the end like so:

module.exports = { exampleTemplate }

I then can import this in my client code and use it as usual:

import { exampleTemplate } from '<path>/example'
...
const html = exampleTemplate ({<locals>})
document.getElementByID('target').innerHTML = html

All that's left to do is to somehow tell Pug to append that module.exports statement, and we have a solution...


Solution

  • Turns out Pug API supports this functionality out of the box, and pug-cli does as well.

    All I needed to to in the end is to change my package.json script to:

    package.json

    "scripts": {
        ...
        "dev:watch:pug": "pug -O '{module: true}' -c -w --name-after-file -o src/client/views src/client/views",
        ...
    }