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

pug-plugin

Package Overview
Dependencies
Maintainers
1
Versions
92
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pug-plugin

The pug plugin for webpack to handle pug files from webpack entries and save them as HTML.

  • 1.1.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
3.8K
increased by417.52%
Maintainers
1
Weekly downloads
 
Created
Source

npm version node node codecov node

pug-plugin

Webpack plugin for the Pug templates.
This plugin extract HTML and CSS from pug html scss css files defined by webpack entry into output directory.

The plugin can be used not only for pug but also for simply extracting HTML or CSS from webpack entry, independent of pug usage.

Install

npm install pug-plugin --save-dev

The motivation

Early

To save extracted HTML, you had to add new HtmlWebpackPlugin ({...}) to webpack.plugins for each file:

const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  entry: {
    'main': './main.js',
    'styles': './styles.scss',
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'templates/page01.pug',
      filename: 'page01.html',
    }),
    // ...
    new HtmlWebpackPlugin({
      template: 'templates/page66.pug',
      filename: 'page66.html',
    }),
  ]
}

Each time will be created new instance of the plugin, initialized and processed. This is not good for huge amount of files.

Now

This plugin can extract and save HTML directly from webpack entry. It is very practical to define all static resources (js, sass, pug, html) together, in one place:

const PugPlugin = require('pug-plugin');
module.exports = {
  entry: {
    'main': './main.js',
    'styles': './styles.scss',
    'index': 'templates/index.html', // now is possible define HTML file in entry
    'page01': 'templates/page01.pug', // now is possible define PUG file in entry
    // ...
    'page77': 'templates/page77.pug',
  },
  plugins: [
    new PugPlugin(), // supports zero config using default webpack output options 
  ]
};

Features

  • supports Webpack 5 and Pug 3
  • supports handle pug files from webpack entry and save extracted HTML into separate file
    module.exports = {
      entry: {
        about: 'src/templates/about.pug', // extract HTML and save into output directory as `about.html`
      },
    }
    
  • supports handle html files from webpack entry and save it without additional plugins like html-webpack-plugin
    module.exports = {
      entry: {
        index: 'src/templates/index.html', // save the HTML into output directory as `index.html`
      },
    }
    
  • supports handle scss css files from webpack entry without additional plugins like mini-css-extract-plugin
    module.exports = {
      entry: {
        styles: 'src/assets/scss/main.scss', // extract CSS and save into output directory as `styles.css`
      },
    }
    
  • supports webpack entry syntax to define source / output files separately for each entry
    module.exports = {
      entry: {
        about: { import: 'src/pages/about/template.pug', filename: 'public/[name].html' },
        examples: { import: 'vendor/examples/index.html', filename: 'public/some/path/[name].html' },
      },
    };
    
  • supports webpack entry API for the plugin option filename, its can be as a template string or a function
    const PugPluginOptions = {
      filename: (pathData, assetInfo) => {
        return pathData.chunk.name === 'main' ? 'assets/css/styles.css' : '[path][name].css';
      }
    }
    
  • supports modules to separately handles of files of different types, that allow to define a separate source / output path and filename for each file type
    const PugPluginOptions = {
      modules: [
        {
          test: /\.(pug)$/,
          sourcePath: path.join(__dirname, 'src/templates/'),
          outputPath: path.join(__dirname, 'public/'),
          filename: '[name].html'
        },
        {
          test: /\.(html)$/,
          sourcePath: path.join(__dirname, 'src/vendor/static/'),
          outputPath: path.join(__dirname, 'public/some/other/path/'),
        },
        {
          test: /\.(sass|scss)$/,
          sourcePath: path.join(__dirname, 'src/assets/sass/'),
          outputPath: path.join(__dirname, 'public/assets/css/'),
          filename: isProduction ? '[name][contenthash:8].css' : '[name].css'
        },
      ],
    };
    
  • supports post process for modules to handle the extracted content before emit
    const PugPluginOptions = {
      modules: [
        {
          test: /\.pug$/,
          postprocess: (content, entry, compilation) => {
            // TODO: your can here handle extracted HTML
            return content;
          },
        },
      ],
    };
    
  • the pug-loader is the part of this plugin, no need additional loaders to render pug files
    const PugPlugin = require('pug-plugin');
    module.exports = {
      module: {
        rules: [
          {
            test: /\.pug$/,
            loader: PugPlugin.loader,
          },
        ],
      },
    };
    

    See the description of the pug-loader options here.

  • extract CSS files from webpack entry without generating unnecessary empty js files,
    not need more for additional fix plugins like webpack-remove-empty-scripts or webpack-fix-style-only-entries
    const PugPlugin = require('pug-plugin');
    module.exports = {
      entry: {
        'styles': 'styles.scss',
      },
      plugins: [
        new PugPlugin({
          modules: [
            PugPlugin.extractCss({ ...extractCssOptions }),
          ],
        }),
      ]
    };
    

Plugin options

The plugin options are default options for self plugin and all plugin modules. In a defined module any option can be overridden.

enabled

Type: boolean Default: true
Enable/disable the plugin.

test

Type: RegExp Default: /\.pug$/
The search for a match of entry files.

sourcePath

Type: string Default: webpack.options.context
The absolute path to sources.

outputPath

Type: string Default: webpack.options.output.path
The output directory for processed entries.

filename

Type: string | Function Default: webpack.output.filename || '[name].html'
The file name of output file.

  • If type is string then following substitutions are available in template strings
    • [name] Only filename without extension or path.
    • [base] Filename with extension.
    • [path] Only path, without filename.
    • [path][name] The path and filename without extension.
    • [ext] Extension with leading ..
    • [id] The ID of the chunk.
    • [contenthash] The hash of the content.
    • [contenthash:nn] The nn is the length of hashes (defaults to 20).
  • If type is Function then following parameters are available in the function:
    • @param {webpack PathData} pathData See the description of this type here
    • @param {webpack AssetInfo} assetInfo
    • @return {string} The name or template string of output file.

postprocess

Type: Function Default: null
The post process for extracted content from compiled entry. The following parameters are available in the function:

  • @param {string | []} content The content of compiled entry. Can be a string (for html entry), an array (for css).
  • @param {AssetEntry} entry The current entry object.
  • @param {webpack.compilation} compilation The webpack compilation object.
  • @return {string | null} Return a string content to save it into output directory.
    If return null then the compiled content of the entry will be ignored, and will be saved original content compiled as JS module.
    May be useful for debug to see a source of compilation any webpack loader.

verbose

Type: boolean Default: false
Show the file information at processing of entry.

modules

Type: PluginOptions[] Default: []
The array of object with type PluginOptions to separately handles of files of different types.
The description of @property of the type PluginOptions see above, by Plugin options.

/**
 * @typedef {Object} PluginOptions
 * @property {boolean} enabled
 * @property {boolean} verbose
 * @property {RegExp} test
 * @property {string} sourcePath
 * @property {string} outputPath
 * @property {string | function(PathData, AssetInfo): string} filename
 * @property {function(string, AssetEntry, Compilation): string | null} postprocess
 */

Usage examples

Output HTML file from Pug template

webpack.config.js

const PugPlugin = require('pug-plugin');
module.exports = {
  output: {
    path: path.join(__dirname, 'public/'), // output path
    publicPath: '/', // must be defined a real publicPath, `auto` not supported!
  },
  entry: {
    'index': 'templates/index.pug', // save HTML into '<__dirname>/public/index.html'
  },
  plugins: [
    new PugPlugin(),
  ],
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: PugPlugin.loader,
        // this loader options are optional, but recommended for faster compilation
        options: {
          method: 'render',
          esModule: true,
        },
      },
    ],
  },
};

Output HTML file from a source directory

Dependency: html-loader This loader is need to handle the .html file type.
Install: npm install html-loader --save-dev

webpack.config.js

const PugPlugin = require('pug-plugin');
module.exports = {
  output: {
    path: path.join(__dirname, 'public/'), // output path
    publicPath: '/', // must be defined a real publicPath, `auto` not supported!
  },
  entry: {
    'example': 'vendor/pages/example.html', // save HTML into '<__dirname>/public/example.html'
  },
  plugins: [
    new PugPlugin({
      modules: [
        // add the module object to match `.html` files in webpack entry
        { test: /\.html$/, filename: '[name].html' }
      ],
    }),
  ],
  module: {
    rules: [
      // add the loader to handle `.html` files
      {
        test: /\.html$/,
        loader: 'html-loader',
      },
    ],
  },
};

Extract CSS file from SASS

Dependencies:

  • css-loader this loader translates CSS into JS strings
  • sass-loader need to handle the .scss file type
  • sass needed for sass-loader to compile Sass CSS

Install: npm install css-loader sass sass-loader --save-dev

webpack.config.js

const PugPlugin = require('pug-plugin');
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
  output: {
    path: path.join(__dirname, 'public/'), // output path
    publicPath: '/', // must be defined a real publicPath, `auto` not supported!
  },
  entry: {
    'css/styles': 'src/assets/main.scss', // save CSS into '<__dirname>/public/css/styles.css'
  },
  plugins: [
    new PugPlugin({
      modules: [
        // add the module to extract CSS into output file
        // see options https://github.com/webdiscus/pug-plugin#options
        PugPlugin.extractCss({
          filename: isProduction ? '[name][contenthash:8].css' : '[name].css',
        })
      ],
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(css|sass|scss)$/,
        use: [
          {
            loader: 'css-loader',
            options: {}, // see options https://github.com/webpack-contrib/css-loader#options
          },
          {
            loader: 'sass-loader',
            options: {}, // see options https://github.com/webpack-contrib/sass-loader#options
          },
        ],
      },
    ],
  },
};

If sass files are defined only in webpack entry and used PugPlugin.extractCss(), then don't use mini-css-extract-plugin because this plugin generates unnecessary empty JavaScript files and as the fix should be used additional webpack-remove-empty-scripts or webpack-fix-style-only-entries.

So, if using PugPlugin.extractCss(), then following plugins are not needed:

  • mini-css-extract-plugin
  • webpack-remove-empty-scripts

The plugin module PugPlugin.extractCss extract and save pure CSS, without eny empty JS files.


Usage of Pug, HTML, SASS, JS together in webpack entry

webpack.config.js

const PugPlugin = require('pug-plugin');
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
  output: {
    path: path.join(__dirname, 'public/'), // output path
    publicPath: '/', // must be defined a real publicPath, `auto` not supported!
  },
  entry: {
    // use source / output paths, defined in module options
    'assets/js/main': './src/assets/main.js', // ==> '<__dirname>/public/assets/js/main.js'
    'css/styles': 'src/assets/main.scss', // ==> '<__dirname>/public/assets/css/styles.css'
    'index': 'index.pug', // ==> '<__dirname>/public/index.html'
    'about': 'about.html', // ==> '<__dirname>/public/static/about.html'
    
    // use absolute paths if source file is not in defined option `sourcePath` 
    'assets/js/demo01': path.join(__dirname, './src/components/demo01/script.js'), // ==> '<__dirname>/public/assets/js/demo01.js'
    'assets/css/demo01': path.join(__dirname, 'src/components/demo01/styles.scss'), // ==> '<__dirname>/public/assets/css/demo01.css'
    'pages/demo01': path.join(__dirname, 'src/components/demo01/template.pug'), // ==> '<__dirname>/public/pages/demo01.html'
    
    // use custom output filename individual for the entry
    'js/demo02': {
      import: path.join(__dirname, './src/components/demo02/main.js'),
      filename: 'assets/[name]-[contenthash:8].js', // ==> '<__dirname>/public/assets/js/demo02-abcd1234.js'
    },
    'css/demo02': {
      import: path.join(__dirname, './src/components/demo02/main.scss'),
      filename: 'assets/[name]-[contenthash:8].css', // ==> '<__dirname>/public/assets/js/demo02-abcd1234.css'
    },
    'demo02': {
      import: path.join(__dirname, './src/components/demo02/main.pug'),
      filename: 'pages/[name].html', // ==> '<__dirname>/public/pages/demo02.html'
    },
  },
  plugins: [
    new PugPlugin({
      enabled: true,
      verbose: false,
      modules: [
        // add the module object to define custom options for `.pug`
        {
          test: /\.pug$/,
          filename: '[name].html',
          sourcePath: 'src/templates/pug/', // define custom path to sources, relative by webpack.config.js 
          outputPath: '', // define custom output path, relative by webpack output.path
        },
        // add the module object to match `.html` files in webpack entry
        { 
          test: /\.html$/, 
          filename: '[name].html',
          sourcePath: 'src/templates/html/',
          outputPath: 'static/',
        },
        // add the module to extract CSS into output file
        PugPlugin.extractCss({
          filename: isProduction ? '[name][contenthash:8].css' : '[name].css',
          sourcePath: 'src/assets/sass/',
          outputPath: 'assets/css/',
        })
      ],
    }),
  ],
  module: {
    rules: [
      // pug
      {
        test: /\.pug$/,
        loader: PugPlugin.loader,
        options: {
          method: 'render',
          esModule: true,
        },
      },
      // html
      {
        test: /\.html$/,
        loader: 'html-loader',
      },
      // styles
      {
        test: /\.(css|sass|scss)$/,
        use: [
          {
            loader: 'css-loader',
          },
          {
            loader: 'sass-loader',
          },
        ],
      },
    ],
  },
};

Also See

Testing

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

License

ISC

Keywords

FAQs

Package last updated on 06 Dec 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