Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@webdiscus/pug-loader

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@webdiscus/pug-loader

The pug loader resolves paths and webpack aliases in a pug template and compiles it to HTML or into a template function.

  • 1.6.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
4.4K
decreased by-19.86%
Maintainers
1
Weekly downloads
 
Created
Source

npm node node node codecov node

pug-loader

Webpack loader for the Pug templates.
The pug loader resolves paths and webpack aliases for extends/include/require() in a pug template and compiles it to HTML or to a template function.

NEW: The pug-loader is now the part of the pug-plugin. This plugin extracts HTML from the pug files defined in the webpack entry and save them in the output directory. Now is possible define pug files directly in webpack entry. See usage examples.

Features

  • supports for Webpack 5 and Pug 3
  • supports for features and options of original pugjs/pug-loader
  • many time faster than original pugjs/pug-loader
  • supports for Webpack resolve.alias and resolve.plugins, works with and without the prefixes ~ @
  • supports for the path resolving from tsconfig.json using tsconfig-paths-webpack-plugin
  • supports for the integration with Angular Component
  • supports for the syntax of CommonJS and ES modules in generated templates for loading them via require or import
  • compiling a pug into a template function, e.g. using in javascript:
    const tmpl = require('template.pug');
    const html = tmpl({ key: "value" })
    
  • rendering a pug into HTML at compile time (using loader method 'render' or query parameter ?pug-render), e.g. using in javascript:
    const html = require('template.pug?pug-render');
    
  • resolving the attribute srcset in img tag:
    img(srcset=`${require('./image1.jpeg')} 320w, ${require('./image2.jpeg')} 640w` src=require('./image.jpeg'))
    
    output
    <img srcset="/assets/image1.f78b30f4.jpeg 320w, /assets/image2.f78b30f4.jpeg 640w" src="/assets/image.f78b30f4.jpeg">
    
  • use the require() for CommonJS and JSON files in pug templates, e.g.:
    data.json
    [
      { "id": 1, "name": "abc" },
      { "id": 2, "name": "xyz" }
    ]
    
    say-hello.js
    module.exports = function (name) {
      return `Hello ${name}!`;
    }
    
    pug template
    - var sayHello = require('./say-hello')
    h1 #{ sayHello('pug') }
    
    - var myData = require('./data.json')
    each item in myData
      div #{item.id} #{item.name}
    
  • rendering to pure HTML using method 'html' to handle HTML in additional loaders, e.g. in html-loader
  • passing custom data to templates at compile time using the loader option data, e.g.:
    {
      test: /\.pug$/,
      loader: 'pug-loader',
      options: {
        method: 'render',
        data: { "key": "value" }
      }
    },
    
    or via query parameters:
    const html = require('template.pug?pug-render&{"key":"value"}');
    
  • supports for the watching of changes in all dependencies
  • all features have integration tests processed through a webpack runner

Why use this particular pug loader instead of the original one?

  • the original pugjs/pug-loader is outdated and not maintained more
  • the original pugjs/pug-loader has error by npm install see issue:
    • npm ERR! Found: pug@3.0.2 ... pug-loader@2.4.0" has incorrect peer dependency "pug@^2.0.0"
  • this pug loader can render a pug into HTML without additional loader
  • this pug loader resolve a path in an embedded resource
  • this pug loader support Webpack resolve.alias also without the prefix ~
  • this pug loader is many times faster than the original pugjs/pug-loader
  • this pug loader watch all change in all dependencies

Install
Webpack config
Options
Usage in Pug templates
Usage in JavaScript
Usage method compile in JavaScript
Usage method render in JavaScript
Usage method html in JavaScript
Usage with Angular Component
Passing data into template
Usage embedded resources
More examples of usages

Install

npm install @webdiscus/pug-loader --save-dev

Webpack config

For usage pug templates only in javascript is enough add to a webpack config:

{
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: '@webdiscus/pug-loader',
      }
    ]
  }
}

Or you can define the resolveLoader.alias to use the pug-loader as default pug loader name:

{
  resolveLoader: {
    alias: {
      'pug-loader': '@webdiscus/pug-loader'
    }
  },
  // ...
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: 'pug-loader',
      }
    ]
  }
}

For processing an embedded resource see usage embedded resources.

For rendering pug templates into static HTML is needed the pug-plugin.

The complete example of the webpack config file:

const path = require('path');
const PugPlugin = require('pug-plugin');
// The absolute path to the base directory of application.
const basePath = path.resolve(__dirname);

// Default pug-loader options.
const pugLoaderOptions = {
  method: 'compile',
  esModule: false,
};‚

module.exports  = {
  resolve: {
    // aliases used in the code examples below
    alias: {
      Components: path.join(basePath, 'src/lib/components/ui/'),
      Images: path.join(basePath, 'src/images/'),
      Templates: path.join(basePath, 'src/templates/'),
    }
  }, 
  
  resolveLoader: {
    // alias for pug-loader
    alias: {
      'pug-loader': '@webdiscus/pug-loader'
    }
  },

  output: {
    path: path.join(basePath, 'public/'), // output path
    publicPath: '/',
    filename: '[name].js',
  },
  
  entry: {
    // the script used a pug template
    'script': './src/js/script.js',
    // save HTML into output.path as index.html
    'index': 'src/templates/index.pug',
  },

  plugins: [
    // this plugin extract HTML from pug template defined in webpack entry
    new PugPlugin(),
  ],

  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: 'pug-loader',
        options: pugLoaderOptions
      },
      
      // processing an embedded resource, e.g. img(src=require('./image.jpeg')) 
      {
        test: /\.(png|jpg|jpeg)/,
        type: 'asset/resource'
        generator: {
          filename: 'assets/images/[name]-[hash][ext][query]',
        },
      }
    ]
  }
};

Options of original pug-loader

See original description of options

basedir

Type: string Default: /
The root directory of all absolute inclusion.

doctype

Type: string Default: html
Specifies the type of document. See available doctypes.

self

Type: boolean Default: false
Use the self as namespace for the local variables in template. It will speed up the compilation, but for access to variable, e.g. myVariable, you must write self.myVariable.

globals

Type: Array<string> Default: []
Add a list of global names to make accessible in templates.

filters

Type: object Default: undefined
Hash table of custom filters. Filters let to use other languages in Pug templates.

plugins

Type: Array<Object> Default: []
Plugins allow to manipulate pug tags, template content in compile process. How it works see in source of pug.

compileDebug

Type: boolean Default: false
Includes the function source in the compiled template to improve error reporting.

pretty

Type: boolean Default: false
This option is deprecated by pugjs and always is false. Don't use it.

Additional options of this implementation

method

Type: string
Default: compile
Values:

  • compile the pug template compiles into a template function and in JavaScript can be called with variables to render into HTML at runtime.
    The query parameter is ?pug-compile. Can be used if the method is render.
    Use this method, if the template have variables passed from JavaScript at runtime. see usage
  • render the pug template renders into HTML at compile time and exported as a string. All required resource will be processed by the webpack and separately included as added strings wrapped to a function.
    The query parameter is ?pug-render. Can be used if the method is compile or is not defined in options.
    Use this method, if the template does not have variables passed from JavaScript at runtime. The method generates the most compact and fastest code. see usage
  • html the template renders into a pure HTML string at compile time. The method need an addition loader to handles the HTML.
    Use this method if the rendered HTML needs to be processed by additional loader, e.g. by html-loader see usage

Embedded resources such as img(src=require('./image.jpeg')) handles at compile time by the webpack using asset/resource.

esModule

Type: Boolean
Default: false
Enable/disable ES modules syntax in generated JS modules.
Values:

  • true The pug-loader generates JS modules with the ES modules syntax.
    For example: import html from 'template.pug';.
    For smaller and faster JS code, it is recommended to use this mode.
  • false defaults. The pug-loader generates JS modules with the CommonJS modules syntax.
    For example, const html = require('template.pug').
    The default value is false for compatibility with the JS modules that is generated by the original pug-loader.

Note: The option esModule is irrelevant for the html method, because it returns a pure HTML string.

For generates smaller and faster JS code, it is recommended to use this options:

{
  method: 'render',
  esModule: true
}

data

Type: Object
Default: {}
The custom data will be passed in all pug templates, it can be useful by pass global data.

Usage

The example of simple file structure of an application under the path /srv/vhost/sample.com/:

.
├--public/
├--lib/
|  └--components/
|     ├--ui/
|     |  ├--layout.pug
|     |  ├--mixins.pug
|     |  └--colors.json
|     ...
├--src/
|  ├--images/
|  |  ├--image.jpeg
|  |  ├--image1.jpeg
|  |  ├--image2.jpeg
|  |  └--image3.jpeg
|  ├--js/
|  |  ├--script.js
|  |  └--data.json
|  └--templates/
|     ├--index.pug
|     └--mixins.pug
|     ├--widget.pug
└--webpack.config.js

The source Pug templates from src/templates/ after compilation are saved as HTML files in public/.

Usage in Pug templates

File ./src/templates/index.pug

// 'Components' is the webpack alias for 'src/lib/components/ui/'
extends Components/layout.pug
include Components/mixins.pug

block content
  - const colors = require('Components/colors.json')`
  
  .color-container
    +show-colors(colors)
  

File ./lib/components/ui/layout.pug

html
  head
    block head
  body
    block content

File ./lib/components/ui/mixins.pug

mixin show-colors(colors)
  each color in colors
    div(style=`background-color:${color.hex};`)= color.name

File ./lib/components/ui/colors.json

[
  {
    "name": "red",
    "hex": "#f00"
  },
  {
    "name": "green",
    "hex": "#0f0"
  },
  {
    "name": "blue",
    "hex": "#00f"
  }
]

In the sample above uses Webpack alias Components instand of relative path ../../lib/components/ui/.

Usage in JavaScript

This pug loader resolve all paths and aliases in Pug templates required from JavaScript.

For example, see the file structure of the application above, the pug template can be loaded in JavaScript via require(). The result of require() is a template function, where the argument is an object of variableName:value, which are available in the pug template.

File ./src/js/script.js:

// 'Templates' is the webpack alias for 'src/templates/'
const widgetTemplate = require('Templates/widget.pug');

// variables passed to the pug template
const locals = {
  text: 'Hello World!',
  colors: [
    {
      "name": "red",
      "hex": "#f00"
    },
    {
      "name": "green",
      "hex": "#0f0"
    },
    {
      "name": "blue",
      "hex": "#00f"
    }
  ]
}

// render template function with variables to HTML
const html = widgetTemplate(locals);

console.log(html);

File ./src/templates/widget.pug:

include ~Templates/mixins

h2 Pug demo widget
//- the variables 'text' and `colors` are passed from 'script.js'
+widget(text, colors)

File ./src/templates/mixins.pug:

mixin widget(text, colors)
  .widget
    p= text
    each color in colors
      div(style=`color:${color.hex};`)= color.name

The result of console.log(html):

<h2>Pug demo widget</h2>
<div class='widget'>
  <p>Hello World!</p>
  <div style="color:#f00">red</div>
  <div style="color:#0f0">green</div>
  <div style="color:#00f">blue</div>
</div>

See the simple web app example.

Usage methods compile, render or html in JavaScript

Method compile (default)

In JavaScript the required template will be compiled into template function.
In webpack config add to module.rules:

{
  test: /\.pug$/,
  loader: 'pug-loader',
  options: {
    method: 'compile' // default method `compile` can be omitted
  }
}

In JavaScript, the result of require () is a template function. Call the template function with some variables to render it то HTML:

const tmpl = require('template.pug');
const html = tmpl({ key: 'value' }); // the HTML string

You can apply the method render to single template using the query parameter ?pug-render:

const html = require('template.pug?pug-render&{"key":"value"}'); // the HTML string

Note: if the query parameter pug-render is set, then will be used rendering for this template, independent of the loader option method. Variables passed in template with method render will be used at compile time.

Method render

This method will render the pug into HTML at compile time.
In webpack config add to module.rules:

{
  test: /\.pug$/,
  loader: 'pug-loader',
  options: {
    method: 'render'
  }
}

In JavaScript the result of require() is an HTML string:

const html = require('template.pug'); // the HTML string

Method html

This method will render the pug to pure HTML and should be used with an additional loader to handle HTML.
In webpack config add to module.rules:

{
   test: /\.pug$/,
   use: [
     { 
       loader: 'html-loader',
       options: {
         esModule: false, // allow to use the require() for load a templqte in JavaScript
       },
     },
     {
       loader: 'pug-loader',
       options: {
         method: 'html',
       },
     },
   ],
}

In JavaScript the result of require() is an HTML string:

const html = require('template.pug'); // the HTML string

Usage scenario 1: pug loader configured for compiling (defaults)

Webpack config:

{
  test: /\.pug$/,
  loader: 'pug-loader'
}

JavaScript:

// compile into template function, because loader option 'method' defaults is 'compile'
const tmpl = require('template.pug');
const html = tmpl({...});

// render the pug file into HTML, using the parameter 'pug-render'
const html2 = require('template2.pug?pug-render');

Usage scenario 2: pug loader configured for rendering

Webpack config:

{
  test: /\.pug$/,
  loader: 'pug-loader', 
  options: {
    method: 'render'
  }
}

JavaScript:

// render into HTML, because loader option 'method' is 'render'
const html = require('template.pug');

// compile into template function, using the parameter 'pug-compile'
const tmpl2 = require('template2.pug?pug-compile');
const html2 = tmpl2({...});

Usage with Angular Component

For usage pug-loader with Angular is needed to customize the webpack config.

Install packages:

npm i --saveDev @webdiscus/pug-loader pug-plugin-ng

in pug-loader can be used optional a plugin, e.g. pug-plugin-ng, to allow unquoted syntax of Angular: [(bananabox)]="val"

Create the file webpack.config.js in root directory of angular project:

module.exports = {
  resolveLoader: {
    alias: {
      'pug-loader': '@webdiscus/pug-loader',
    },
  },

  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: 'pug-loader',
        options: {
          method: 'render',
          doctype: 'html',
          plugins: [require('pug-plugin-ng')],
        },
      },

      // processing an embedded resource by webpack
      {
        test: /\.(png|jpg|jpeg)/,
        type: '`asset/resource`',
      },
    ],
  },
};

Bind the file webpack.config.js in the Angular config angular.json:

{
  // ...
  "projects": {
      // ...
      "architect": {
        "build": {
          // replace architect.build.builder with this value:
          "builder": "@angular-builders/custom-webpack:browser",
          // add the options:
          "options": {
            "aot": true,
            "customWebpackConfig": {
              "path": "./webpack.config.js" // the path to webpack.config.js
            },
            // ...
          },
          // ...
        },
        "serve": {
          // replace architect.serve.builder with this value:
          "builder": "@angular-builders/custom-webpack:dev-server",
          "options": {
            "browserTarget": "<app-name>:build"
          },
          // ...
        },
        // ...
      }
    }
  },
}

In a component file, e.g. ./src/app/app.component.ts set the templateUrl with pug file:

import { Component } from '@angular/core';

// the variable `description` will be passed into pug template via resource query
const templateVars = '{"description": "Use pug template with Angular."}';

@Component({
  selector: 'app-root',
  styleUrls: ['./app.component.css'],
  templateUrl: './app.component.pug?' + templateVars,
})
export class AppComponent {
  title = 'ng-app';
}

Create a pug template, e.g. ./src/app/app.component.pug:

h1 Hello Pug!
p Description: #{description}

See the source files of this example.

Alternative usage with additional html-loader

Install the html-loader:

npm i --saveDev html-loader

If your templates use the html-loader, then modify the webpack.config.js file:

module.exports = {
  resolveLoader: {
    alias: {
      'pug-loader': '@webdiscus/pug-loader',
    },
  },

  module: {
    rules: [
      {
        test: /\.pug$/,
        use: [
          {
            loader: 'html-loader',
            options: {
              esModule: false,
            },
          },
          {
            loader: 'pug-loader',
            options: {
              method: 'html', // the method render into HTML string and require additional loader `html-loader`
              doctype: 'html',
              plugins: [require('pug-plugin-ng')], // optional plugin 
            },
          },
        ],
      },

      // processing an embedded resource by webpack
      {
        test: /\.(png|jpg|jpeg)/,
        type: 'asset/resource',
      },
    ],
  },
};

See the source files of this example.

Passing data into template

By default, the pug file is compiled as template function, into which can be passed an object with template variables.

const tmpl = require('template.pug');
const html = tmpl2({
   key: 'value',
   foo: 'bar',
});

But how pass variables in template which is rendered into HTML?

const html = require('template.pug');

Variables can be passed with query parameters, e.g.:

const html = require('template.pug?key=value&foo=bar');

or as a JSON object, e.g.:

const html = require('template.pug?{"key":"value","foo":"bar"}');

Using the method render and JSON object:

const html = require('template.pug?pug-render&{"key":"value","foo":"bar"}');

Usage of query parameters is legal and official documented feature of webpack loader.

To pass variables global, in all templates at compile time use loader option data:

{
  test: /\.pug$/,
  loader: 'pug-loader',
  options: {
    data: {
      key: 'value',
      foo: 'bar'  
    }
  }
}

The variables will be passed in all templates independent of the method.

Usage embedded resources

For processing image resources in templates with webpack use the require() function:

img(src=require('./path/to/image.jpeg'))

To handles embedded resources in pug is needed the webpack module asset/resource:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|jpeg)/,
        type: 'asset/resource'
      },
      // ...
    ]
  },
};

More information about asset-modules see here.

The example of dynamically generating embedded resources in template:

- files = ['image1.jpeg', 'image2.jpeg', 'image3.jpeg']
each file in files
  img(src=require(file))

File resolving examples

The example of webpack alias used in the table below:

resolve: {
  alias: {
    Images: path.join(__dirname, 'src/images/'),
  },
}
Code@webdiscus/pug-loaderpugjs/pug-loader
img(src=require('image.jpeg'))OKfail
img(src=require('./image.jpeg'))OKOK
img(src=require('./images/image.jpeg'))OKOK
img(src=require('../images/image.jpeg'))OKOK
img(src=require('Images/image.jpeg'))OKOK
- var file = 'image.jpeg'
img(src=require('Images/' + file))
OKOK
- var file = 'image.jpeg'
img(src=require(`Images/${file}`))
OKOK
- var file = 'image.jpeg'
img(src=require(file))
OKfail
- var file = 'image.jpeg'
img(src=require(`${file}`))
OKfail
- var file = 'image.jpeg'
img(src=require('./' + file))
OKOK
- var file = './image.jpeg'
img(src=require(file))
OKfail
- var file = './image.jpeg'
img(src=require('' + file))
OKOK
- var file = 'images/image.jpeg'
img(src=require(file))
OKfail
- var file = 'image.jpeg'
img(src=require('./images/' + file))
OKOK
- var file = 'image.jpeg'
img(src=require(`./images/${file}`))
OKOK
- var file = '../images/image.jpeg'
img(src=require(file))
OKfail
- var file = 'image.jpeg'
img(src=require('../images/' + file))
OKOK
- var file = 'image.jpeg'
img(src=require(`../images/${file}`))
OKOK
the pugjs/pug-loader can't resolve when used a mixin and require on same file:
include mixins
img(src=require('./image.jpeg'))
OKfail

Important: in examples used name of loader as pug-loader, because it is defined as alias at resolveLoader:

{
  resolveLoader: {
    alias: {
      'pug-loader': '@webdiscus/pug-loader'
    }
  },
}

Testing

npm run test will run the unit and integration tests.
npm run test:coverage will run the tests with coverage.

Also See

License

ISC

Keywords

FAQs

Package last updated on 20 Jan 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc