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 for webpack resolves paths and webpack aliases in the pug template and compiles it to HTML.

  • 1.1.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
4.7K
decreased by-28.73%
Maintainers
1
Weekly downloads
 
Created
Source

npm version

pug-loader

Webpack loader for the Pug templates.
The pug-loader resolve paths and webpack aliases for extends/include/require() in pug template and compiles it into static HTML or into javascript template function.

Features

  • supports Webpack 5 and Pug 3
  • supports all features and options of original pugjs/pug-loader
  • up to 4x faster than original pugjs/pug-loader at webpack starting
  • up to 8x faster than original pugjs/pug-loader at webpack watching during compile changes in dependencies
  • supports Webpack resolve.alias, work fine with and without the prefixes ~ or @, e.g. this works:
    • extends UIComponents/layout.pug
    • extends ~UIComponents/layout.pug
    • extends @UIComponents/layout.pug
    • include UIComponents/mixins.pug
    • include ~UIComponents/mixins.pug
    • include @UIComponents/mixins.pug
    • include:markdown-it UIComponents/components.md
    • - const colors = require('UIComponents/colors.json')
    • img(src=require('UIComponents/image.jpeg'))
    • const tmpl = require('UIComponents/index.pug');
  • compiling in JS a pug file into template function, e.g.:
    const tmpl = require('template.pug');
    const html = tmpl({ var1: "value1" })
    
  • rendering in JS a pug file directly into HTML (using loader option {method:'render'} or query parameter ?pug-render), e.g.:
    const html = require('template.pug?pug-render&{var1:"value1"}');
    
  • support for passing custom data to templates at compile time using loader option or resource query parameters
  • supports 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 in JS can render a template directly in HTML, w/o usage an additional loader
  • 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

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 rendering pug templates into static HTML is needed the HtmlWebpackPlugin.

The complete example of the webpack config file:

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

// The minimal required options for pug-loader.
const pugLoaderOptions = {};

module.exports  = {
  resolve: {
    // aliases used in the code examples below
    alias: {
      UIComponents: 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'
    }
  },
  
  entry: {
    // the script used a pug template
    'script': './src/js/script.js',
  },

  output: {
    path: path.join(basePath, 'public/assets/'),
    filename: '[name].js',
  },

  plugins: [
    // this plugin extract the content of a pug template 
    // and save compiled via pug-loader content into html file
    new HtmlWebpackPlugin({
      filename: path.join(basePath, '/src/templates/index.pug'),
      template: './public/index.html',
      inject: false
    }),
  ],

  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: 'pug-loader',
        options: pugLoaderOptions
      },
      // it is need for usage embedded resources in pug, like img(src=require('./image.jpeg')) 
      {
        test: /\.(png|jpg|jpeg)/,
        type: 'asset/resource'
      }
    ]
  }
};

Options of original pug-loader

See original description of options

doctype

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

pretty

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

filters

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

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.

compileDebug

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

globals

Type: Array<string>
Default: []
Add a list of global names to make accessible in 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.

Additional options of this implementation

method

Type: string
Default: compile
Values:

  • compile all templates required in JS files will be compiled into a template function, that can be called to generate a HTML
  • render all templates required in JS files will be rendered directly into HTML, it is usefully, e.g., for Angular @Component

data

Type: Object
Default: {}
The custom data will be passed in all pug templates, it can be useful by pass global data, e.g. i18n 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

extends UIComponents/layout.pug
include UIComponents/mixins.pug

block content
  - const colors = require('UIComponents/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 UIComponents instand of relative path ../../lib/components/ui/.

Usage embedded resources

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

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

For usage embedded resources is need add an asset-module to module.rules in webpack config:

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

More information about asset-modules see here.

Known issues / features by usage embedded resources

Due to the peculiarities of the pug compiler, the interpolation of the argument to the require() function depends on its string and variable parts.
Use a relative path only in the string before the variable. The variable must contain only the filename without specifying a path.

Examples of incorrect usage:

- filename = './image.jpeg'
img(src=require(filename))
- filename = '../relative/path/to/resource/image.jpeg'
img(src=require(filename))

Examples of correct usage:

- filename = 'image.jpeg'
img(src=require(filename))
- filename = 'image.jpeg'
img(src=require('../relative/path/to/resource/' + filename))

The example of dynamically generating embedded resources in template:

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

The example of webpack alias used in the table below:

resolve: {
  alias: {
    SourceImages: path.join(__dirname, 'src/images/'),
  },
}

Examples for using embedded resources:

Code@webdiscus/pug-loaderpugjs/pug-loaderNote
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('SourceImages/image.jpeg'))OKOKUsage of the webpack alias to images directory.
- file = 'image.jpeg'
img(src=require('SourceImages/' + file))
OKOK
- file = 'image.jpeg'
img(src=require(`SourceImages/${file}`))
OKOK
- file = 'image.jpeg'
img(src=require(file))
OKfail
- file = 'image.jpeg'
img(src=require(`${file}`))
OKfail
- file = 'image.jpeg'
img(src=require('./' + file))
OKOK
- file = './image.jpeg'
img(src=require(file))
failfailDon't use ./ in variable of filename.
- file = './image.jpeg'
img(src=require('' + file))
failOKDon't use ./ in variable of filename.
- file = 'images/image.jpeg'
img(src=require(file))
OKfail
- file = 'image.jpeg'
img(src=require('./images/' + file))
OKOK
- file = 'image.jpeg'
img(src=require(`./images/${file}`))
OKOK
- file = '../images/image.jpeg'
img(src=require(file))
failfailDon't use a path in a variable.
- file = 'image.jpeg'
img(src=require('../images/' + file))
OKOKDefine a path separately as string and add to she the variable contained only a filename.
- file = 'image.jpeg'
img(src=require(`../images/${file}`))
OKOK
Include the template from sub directory:
include mixins
img(src=require('./image.jpeg'))
OKfailwhen use a mixin and require on same file, then pugjs/pug-loader can't resolve the file in require().

Usage in frontend 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 webpack alias
// 'widgetTemplate' is template function
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:

//- 'Templates' is webpack alias
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>

Usage methods compile or render in JavaScript

Defaults, in JavaScript a required template will be compiled into template function.
For rendering a pug file directly into HTML you have 2 ways:

  1. for global rendering in all JS files set loader option method: 'render':
{
  test: /\.pug$/,
  loader: 'pug-loader',
  options: {
    method: 'render'
  }
}

Then in JavaScript can be used the result of require() as rendered HTML:

const html = require('template.pug');
  1. for local rendering of the pug file add the query parameter ?pug-render:
const html = require('template.pug?pug-render');

Note: if the query parameter pug-render is set, then will be used rendering, independent of the loader option method.

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 directly 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({...});

Passing a 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 directly 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.

More examples of usages see in test cases.

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'
    }
  },
}

Keywords

FAQs

Package last updated on 10 Nov 2021

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