Security News
Opengrep Emerges as Open Source Alternative Amid Semgrep Licensing Controversy
Opengrep forks Semgrep to preserve open source SAST in response to controversial licensing changes.
pug-plugin
Advanced tools
Pug plugin for webpack compiles Pug files to HTML, extracts CSS and JS from the sources specified in Pug.
Pug Plugin enable to use Pug files in webpack entry and generates HTML file that includes the hashed output JS and CSS filenames whose source files are specified in the Pug template.
💡 Highlights:
html-webpack-plugin
and mini-css-extract-plugin
.Specify the Pug files in the webpack entry:
const PugPlugin = require('pug-plugin');
module.exports = {
entry: {
index: './src/views/home/index.pug', // output dist/index.html
about: './src/views/about/index.pug', // output dist/about.html
},
plugins: [
new PugPlugin(), // enable processing of Pug files specified in webpack entry
],
};
Add source scripts and styles directly to Pug using require()
:
link(href=require('./styles.scss') rel='stylesheet')
script(src=require('./main.js'))
Generated HTML contains hashed CSS and JS output filenames:
<link href="/assets/css/styles.05e4dd86.css" rel="stylesheet">
<script src="/assets/js/main.f4b855d8.js"></script>
Just one Pug plugin replaces the functionality of many plugins and loaders:
Package | Features |
---|---|
html-webpack-plugin | extract HTML and save in a file |
mini-css-extract-plugin | extract CSS and save in a file |
webpack-remove-empty-scripts | remove empty js files generated by the mini-css-extract-plugin |
resolve-url-loader | resolve url in CSS |
svg-url-loader | encode SVG data-URL as utf8 |
posthtml-inline-svg | inline SVG icons in HTML |
pug-loader | the Pug loader is already included in the Pug plugin |
Warning
Don't use the
pug-plugin
together withhtml-webpack-plugin
andmini-css-extract-plugin
.
Thepug-plugin
is designed to replace these plugins to make Pug easier to use and faster to compile.
The fundamental difference between mini-css-extract-plugin
and pug-plugin
:
mini-css-extract-plugin
extracts CSS from styles imported in JavaScript
and require additional html-webpack-plugin
to inject <link>
tag somewhere in any HTML file.pug-plugin
extracts CSS from styles specified directly in Pug and save into separate file under hashed output filename.
The <link>
tag stays in place and href
will contain output hashed filename.
You can specify <link>
tag exactly where you want in HTML.
The Pug plugin extracts CSS much faster because it is optimized to perform the same works in one step.node_module
splitChunks
auto
publicPathpretty
formatting of generated HTMLasset/resource
asset/inline
asset
to automatically choose between resource
and inline
inline SVG
in HTMLinline SVG
as data-URL in CSS
background: url('./icons/iphone.svg') // CSS: url("data:image/svg+xml,<svg>...</svg>")
post process
for modules to handle the extracted contentInstall the pug-plugin
:
npm install pug-plugin --save-dev
Install additional packages for styles:
npm install css-loader sass sass-loader --save-dev
Change your webpack.config.js
according to the following minimal configuration:
const path = require('path');
const PugPlugin = require('pug-plugin');
module.exports = {
output: {
path: path.join(__dirname, 'dist/'),
publicPath: '/',
// output filename of JS files
filename: 'assets/js/[name].[contenthash:8].js'
},
entry: {
// don't define scripts and styles in the webpack entry,
// all scripts and styles must be specified in Pug
// define Pug files in entry:
index: './src/views/index.pug', // output index.html
about: './src/views/about/index.pug' // output about.html
// ...
},
plugins: [
// enable using Pug files as entry point
new PugPlugin({
pretty: true, // formatting HTML, should be used in development mode only
extractCss: {
// output filename of CSS files
filename: 'assets/css/[name].[contenthash:8].css'
},
})
],
module: {
rules: [
{
test: /\.pug$/,
loader: PugPlugin.loader, // pug-plugin already contain the pug-loader
options: {
method: 'render', // fast method to generate static HTML files
}
},
{
test: /\.(css|sass|scss)$/,
use: ['css-loader', 'sass-loader']
},
],
},
};
Note
The automatic public path is supported, but for faster compilation is recommended to use a fixed
publicPath
(e.g.'/'
or''
).
Pug template src/views/index.pug
:
html
head
//- add styles in head
link(href=require('./styles.scss') rel='stylesheet')
body
h1 Hello Pug!
//- add scripts at last position in body
script(src=require('./main.js'))
Generated HTML:
<html>
<head>
<link href="/assets/css/styles.f57966f4.css" rel="stylesheet">
</head>
<body>
<h1>Hello Pug!</h1>
<script src="/assets/js/main.b855d8f4.js"></script>
</body>
</html>
Warning
- Don't define styles and JS files in entry. You can use
require()
for source files of JS and SCSS in Pug.- Don't import styles in JS. Use
require()
for style files in Pug.- Don't use
html-webpack-plugin
to render Pug files in HTML. The Pug plugin processes files from webpack entry.- Don't use
mini-css-extract-plugin
to extract CSS from styles. The Pug plugin extract CSS from styles required in Pug.
enabled
Type: boolean
Default: true
Enable/disable the plugin.
verbose
Type: boolean
Default: false
Show the file information at processing of entry.
pretty
Type: boolean
Default: false
Pretty formatting the resulting HTML. Use this option for debugging only. For production build should be disabled.
This option only works for Pug files defined in the webpack entry.
Warning️
The
pretty
option of thepug-loader
is deprecated, therefore use thepretty
option inpug-plugin
.
const PugPlugin = require('pug-plugin');
module.exports = {
plugins: [
new PugPlugin({
pretty: true, // enable formatting of HTML
}),
],
};
test
Type: RegExp
Default: /\.pug$/
Use the test
to match module options by source filename of a resource.
For example, save all extracted svg
files from fonts/
to the separate output directory:
const PugPlugin = require('pug-plugin');
module.exports = {
plugins: [
new PugPlugin({
modules: [
{
test: /fonts\/.+\.svg$/,
outputPath: path.join(__dirname, 'dist/some/other/path/'),
},
],
}),
],
};
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. This directory can be relative by webpack.options.output.path
or absolute.
filename
Type: string | Function
Default: webpack.output.filename || '[name].html'
The name of output file.
string
then following substitutions (see output.filename for chunk-level) are available in template string:
[id]
The ID of the chunk.[name]
Only filename without extension or path.[contenthash]
The hash of the content.[contenthash:nn]
The nn
is the length of hashes (defaults to 20).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.modules
Type: ModuleOptions[]
Default: []
The array of objects of type ModuleOptions
to separately handles of different file types.
The description of @property
see by Pug plugin options.
/**
* @typedef {Object} ModuleOptions
* @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, ResourceInfo, Compilation): string | null} postprocess
*/
extractCss
Type: ModuleOptions
Default module options:
{
test: /\.(css|scss|sass|less|styl)$/,
enabled: true,
verbose: false,
filename: '[name].css',
sourcePath: null,
outputPath: null,
}
The options for embedded extractCss
module. This module extracts CSS from style sources specified in Pug using require()
, e.g.:
link(href=require('./styles.scss') rel='stylesheet')
Warning
Don't import source styles in JavaScript! Styles must be specified directly in Pug.
The default CSS output filename is [name].css
. You can specify your own filename using webpack filename substitutions:
const PugPlugin = require('pug-plugin');
module.exports = {
plugins: [
new PugPlugin({
extractCss: {
filename: 'assets/css/[name].[contenthash:8].css',
},
}),
],
};
The name
is the filename of required style source.
For example, if source file is styles.scss
, then output filename will be assets/css/styles.1234abcd.css
.\n
If you want to have a different output filename, you can use the filename
options as the function.
Note
Since version
3.0.0
the moduleextractCss
is enabled by default.
Warning
Don't use
mini-css-extract-plugin
orstyle-loader
, they are not required more.
TheextractCss
module extracts CSS much faster than other plugins and resolves all asset URLs in CSS, therefore theresolve-url-loader
is redundant too.
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.@param {ResourceInfo} info
The info of current asset.@param {webpack Compilation} compilation
The webpack compilation object.@return {string | null}
Return string content to save to output directory.null
then the compiled content of the entry will be ignored, and will be saved original content compiled as JS module.
Returning null
can be useful for debugging to see the source of the compilation of the webpack loader./**
* @typedef {Object} ResourceInfo
* @property {boolean} [verbose = false] Whether information should be displayed.
* @property {boolean} isEntry True if is the asset from entry, false if asset is required from pug.
* @property {string} outputFile The absolute path to generated output file (issuer of asset).
* @property {string | (function(PathData, AssetInfo): string)} filename The filename template or function.
* @property {string} sourceFile The absolute path to source file.
* @property {string} assetFile The output asset file relative by `output.publicPath`.
*/
The simple example of resolving the asset resources via require() in Pug and via url() in scss.
The webpack config:
const PugPlugin = require('pug-plugin');
module.exports = {
entry: {
index: './src/pages/home/index.pug', // one entry point for all assets
// ... here can be defined many Pug templates
},
output: {
path: path.join(__dirname, 'dist/'),
publicPath: '/',
// output filename of JS files
filename: 'assets/js/[name].[contenthash:8].js'
},
resolve: {
alias: {
// use alias to avoid relative paths like `./../../images/`
Images: path.join(__dirname, './src/images/'),
Fonts: path.join(__dirname, './src/fonts/')
}
},
plugins: [
new PugPlugin({
extractCss: {
// output filename of CSS files
filename: 'assets/css/[name].[contenthash:8].css'
},
}),
],
module: {
rules: [
{
test: /\.pug$/,
loader: PugPlugin.loader,
options: {
method: 'render',
}
},
{
test: /\.(css|sass|scss)$/,
use: ['css-loader', 'sass-loader']
},
{
test: /\.(png|jpg|jpeg|ico)/,
type: 'asset/resource',
generator: {
// output filename of images
filename: 'assets/img/[name].[hash:8][ext]',
},
},
{
test: /\.(woff|woff2|eot|ttf|otf|svg)$/i,
type: 'asset/resource',
generator: {
// output filename of fonts
filename: 'assets/fonts/[name][ext][query]',
},
},
],
},
};
The Pug template ./src/pages/home/index.pug
:
html
head
link(rel="icon" type="image/png" href=require('~Images/favicon.png'))
link(href=require('./styles.scss') rel='stylesheet')
body
.header Here is the header with background image
h1 Hello Pug!
img(src=require('~Images/pug-logo.jpg') alt="pug logo")
script(src=require('./main.js'))
The source script ./src/pages/home/main.js
console.log('Hello Pug!');
The source styles ./src/pages/home/styles.scss
// Pug plugin can resolve styles in node_modules.
// The package 'material-icons' must be installed in packages.json.
@use 'material-icons';
// Resolve the font in the directory using the webpack alias.
@font-face {
font-family: 'Montserrat';
src: url('~Fonts/Montserrat/Montserrat-Regular.woff2'); // pug-plugin can resolve url
...
}
body {
font-family: 'Montserrat', serif;
}
.header {
background-image: url('~Images/header.png'); // pug-plugin can resolve url
...
}
Note
The Pug plugin can resolve an url (as relative path, with alias, from node_modules) without requiring
source-maps
. Do not need additional loader such asresolve-url-loader
.
The generated CSS dist/assets/css/styles.f57966f4.css
:
/*
* All styles of npm package 'material-icons' are included here.
* The imported fonts from `node_modules` will be coped in output directory.
*/
@font-face {
font-family: "Material Icons";
src:
url(/assets/fonts/material-icons.woff2) format("woff2"),
url(/assets/fonts/material-icons.woff) format("woff");
...
}
.material-icons {
font-family: "Material Icons";
...
}
/*
* Fonts from local directory.
*/
@font-face {
font-family: 'Montserrat';
src: url(/assets/fonts/Montserrat-Regular.woff2);
...
}
body {
font-family: 'Montserrat', serif;
}
.header {
background-image: url(/assets/img/header.4fe56ae8.png);
...
}
Note
All resolved files will be coped to the output directory, so no additional plugin is required, such as
copy-webpack-plugin
.
The generated HTML dist/index.html
contains the hashed output filenames of the required assets:
<html>
<head>
<link rel="stylesheet" href="/assets/css/styles.f57966f4.css">
</head>
<body>
<div class="header">Here is the header with background image</div>
<h1>Hello Pug!</h1>
<img src="/assets/img/pug-logo.85e6bf55.jpg" alt="pug logo">
<script src="/assets/js/main.b855d8f4.js"></script>
</body>
</html>
All this is done by one Pug plugin, without additional plugins and loaders. To save build time, to keep your webpack config clear and clean, just use this plugin.
Pug plugin can resolve styles in node_modules
.
Note
Pug plugin resolves styles much fasted than the resolve-url-loader and don't require to use the source map in
sass-loader
.
@use 'MODULE_NAME/path/to/style';
Important: the file extension, e.g. .scss, .css, must be omitted.
Example how to import styles of material-icons:
// import styles from installed module `material-icons`
@use 'material-icons';
// define short class name
.mat-icon {
@extend .material-icons-outlined;
}
Usage of the icon home
in Pug:
.mat-icon home
Example how to import the style theme tomorrow
of the prismjs module:
// import default prismjs styles from installed module `prismjs`
@use 'prismjs/themes/prism-tomorrow.min';
Note
use the
@use
instead of@import
, because it is deprecated.
splitChunks
Defaults, Webpack will split every entry module. Because the entry point is Pug files, Webpack tries to split those files too, which completely breaks the compilation process in pug-plugin.
To avoid this issue, you must specify which scripts should be split, using optimization.splitChunks.cacheGroups
:
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
scripts: {
test: /\\.(js|ts)$/,
chunks: 'all',
},
},
},
},
// ...
};
Note
In the
test
option must be specified all extensions of scripts which should be split.
See details by splitChunks.cacheGroups.
To enable live reload by changes any file add in the webpack config following options:
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
watchFiles: {
paths: ['src/**/*.*'],
options: {
usePolling: true,
},
},
},
Note
Live reload works only if in Pug used a JS file. If your Pug template has not a JS, then create one empty JS file and add it in Pug:
script(src=require('./dummy.js'))
Don't forget disable this dummy script for production build:
//- script(src=require('./dummy.js'))
npm run test
will run the unit and integration tests.
npm run test:coverage
will run the tests with coverage.
PugPlugin.loader
:highlight
filter highlights code syntax:markdown
filter transform markdown to HTML and highlights code syntax3.0.0 (2022-07-17)
Drop support for Node 12
, minimum supported version is 14.18
sass-loader
13.x requires Node 14.By default, the embedded CSS extractor module is now enabled. For compatibility with external extractor, you can disable extractCss module:
new PugPlugin({
extractCss: {
enabled: false, // disable embedded extractCss module to bypass extracting via external plugin
},
}),
definition of extractCss as plugin module is deprecated:
new PugPlugin({
modules: [
PugPlugin.extractCss({
filename: 'assets/css/[name].[contenthash].css',
})
],
}),
now use the new extractCss
option:
new PugPlugin({
extractCss: {
filename: 'assets/css/[name].[contenthash].css',
},
}),
Note: you can still use the
modules: []
option for custom settings.
publicPath
extractCss
option for embedded CSS extract moduleextractCss
module is enabled with default optionsnew PugPlugin()
is equivalent to:
new PugPlugin({
test: /\.(pug)$/,
enabled: true,
verbose: false,
pretty: false,
sourcePath: null,
outputPath: null,
filename: '[name].html',
extractComments: false,
extractCss: {
test: /\.(css|scss|sass|less|styl)$/,
enabled: true,
verbose: false,
filename: '[name].css',
sourcePath: null,
outputPath: null,
},
modules: [],
}),
publicPath
FAQs
Pug plugin for webpack handles a template as an entry point, extracts CSS and JS from their sources referenced in Pug.
The npm package pug-plugin receives a total of 1,433 weekly downloads. As such, pug-plugin popularity was classified as popular.
We found that pug-plugin demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
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.
Security News
Opengrep forks Semgrep to preserve open source SAST in response to controversial licensing changes.
Security News
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Security News
cURL and Go security teams are publicly rejecting CVSS as flawed for assessing vulnerabilities and are calling for more accurate, context-aware approaches.