@hyperse/html-webpack-plugin-loader
A powerful HTML template parser and manipulator for webpack applications, providing a fluent API for modifying HTML templates with ease.
A TypeScript-based HTML template parser that provides a fluent API for manipulating HTML documents. This package is designed to work seamlessly with webpack applications, allowing you to easily modify HTML templates during the build process.
Features
- 🔄 Fluent API for HTML manipulation
- 🎯 Precise control over HTML document structure
- 📦 Easy integration with webpack
- 🚀 TypeScript support
- 🔍 Built-in support for common HTML modifications:
- 📝 Title tag management
- 🎨 Favicon handling with customizable attributes
- 📱 Meta tags management
- 💅 Style injection (both external and inline)
- 📜 Script injection (both external and inline)
- 🔄 Head and body modifications with position control
Installation
npm install --save @hyperse/html-webpack-plugin-loader
API Reference
TemplateParser
The main class that provides HTML template manipulation capabilities.
import { TemplateParser } from '@hyperse/html-webpack-plugin-loader';
const parser = new TemplateParser(htmlSource);
const templateOptions: TemplateOptions = {
title: 'My Page Title',
favicon: {
href: '/favicon.ico',
rel: 'icon',
attributes: {
type: 'image/x-icon',
sizes: '32x32',
},
},
headMetaTags: ['<meta name="description" content="My page description">'],
headStyles: [
{
id: 'main-css',
href: '/styles/main.css',
position: 'end',
order: 1,
},
],
headInlineStyles: [
{
id: 'critical-css',
content: 'body { margin: 0; }',
position: 'beginning',
order: 0,
},
],
headScripts: [
{
id: 'main-js',
src: '/main.js',
position: 'end',
type: 'module',
async: true,
defer: false,
crossOrigin: 'anonymous',
integrity: 'sha384-hash',
nonce: 'abc123',
order: 1,
},
],
headInlineScripts: [
{
id: 'inline-script',
content: 'console.log("Hello");',
position: 'end',
order: 2,
},
],
bodyScripts: [
{
id: 'app-js',
src: '/app.js',
position: 'end',
type: 'module',
async: true,
defer: false,
order: 1,
},
],
};
const modifiedHtml = parser
.upsertTitleTag(templateOptions.title)
.upsertFaviconTag(
templateOptions.favicon.href,
templateOptions.favicon.rel,
templateOptions.favicon.attributes
)
.upsertHeadMetaTags(templateOptions.headMetaTags)
.upsertHeadStyles(templateOptions.headStyles)
.upsertHeadInlineStyles(templateOptions.headInlineStyles)
.upsertHeadScripts(templateOptions.headScripts)
.upsertHeadInlineScripts(templateOptions.headInlineScripts)
.upsertBodyScripts(templateOptions.bodyScripts)
.serialize();
Available Methods
upsertTitleTag(title: string): Updates or inserts the page title
upsertFaviconTag(href: string, rel?: string, attributes?: Record<string, string>): Updates or inserts the favicon link with optional rel and custom attributes
upsertHeadMetaTags(tags: string[]): Updates or inserts meta tags in the head
upsertHeadStyles(styles: StyleItem[]): Updates or inserts external style links in the head
upsertHeadInlineStyles(styles: StyleInlineItem[]): Updates or inserts inline style tags in the head
upsertHeadScripts(scripts: ScriptItem[]): Updates or inserts external script tags in the head
upsertHeadInlineScripts(scripts: ScriptInlineItem[]): Updates or inserts inline script tags in the head
upsertBodyScripts(scripts: ScriptItem[]): Updates or inserts script tags in the body
serialize(): Converts the modified document back to HTML string
parseTemplate Function
A utility function that provides a convenient way to parse and modify HTML templates in a single step.
import { parseTemplate } from '@hyperse/html-webpack-plugin-loader';
const modifiedHtml = parseTemplate(htmlSource, templateOptions).serialize();
The parseTemplate function is a shorthand for creating a TemplateParser instance and applying all template modifications at once. It accepts two parameters:
htmlSource: string: The source HTML template to parse and modify
options: TemplateOptions: The template modification options (same as described above)
This function is particularly useful when you want to perform all template modifications in a single operation without manually chaining multiple method calls.
Type Definitions
type Position = 'beginning' | 'end';
interface HtmlItemBase {
id: string;
position: Position;
order?: number;
}
interface StyleItem extends HtmlItemBase {
href: string;
}
interface StyleInlineItem extends HtmlItemBase {
content: string;
}
interface ScriptItem extends HtmlItemBase {
src: string;
type?: string;
async?: boolean;
defer?: boolean;
crossOrigin?: string;
integrity?: string;
nonce?: string;
}
interface ScriptInlineItem extends HtmlItemBase {
content: string;
}
interface FaviconItem {
href: string;
rel: string;
attributes: Record<string, string>;
}
interface TemplateOptions {
title?: string;
favicon?: FaviconItem;
headMetaTags?: string[];
headStyles?: StyleItem[];
headInlineStyles?: StyleInlineItem[];
headScripts?: ScriptItem[];
headInlineScripts?: ScriptInlineItem[];
bodyScripts?: ScriptItem[];
}
Webpack Loader Integration with html-webpack-plugin
This package provides seamless integration with webpack through a custom loader. The loader works in conjunction with html-webpack-plugin to modify HTML templates during the build process.
Basic Setup
First, ensure you have both html-webpack-plugin and this package installed:
npm install --save-dev html-webpack-plugin @hyperse/html-webpack-plugin-loader
Webpack Configuration
Add the loader to your webpack configuration file (e.g., webpack.config.js or webpack.config.ts):
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const loader = require.resolve('@hyperse/html-webpack-plugin-loader/loader');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: `${loader}!/xxx/src/index.html`,
templateParameters: {
title: 'My Webpack App',
favicon: {
href: '/favicon.ico',
rel: 'icon',
attributes: {
type: 'image/x-icon',
},
},
headMetaTags: [
'<meta name="viewport" content="width=device-width, initial-scale=1.0">',
'<meta name="description" content="My webpack application">',
],
headStyles: [
{
id: 'main-css',
href: '/styles/main.css',
position: 'end',
},
],
bodyScripts: [
{
id: 'app-js',
src: '/app.js',
position: 'end',
type: 'module',
},
],
},
}),
],
};
Usage with TypeScript
If you're using TypeScript, you can import the types for better type checking:
import type { TemplateOptions } from '@hyperse/html-webpack-plugin-loader';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path';
const loader = require.resolve('@hyperse/html-webpack-plugin-loader/loader');
const templateParameters: TemplateOptions = {
title: 'My TypeScript Webpack App',
};
const config = {
plugins: [
new HtmlWebpackPlugin({
template: `$loader}!/xxx/src/index.html`,
templateParameters,
}),
],
};
export default config;
Advanced Usage
Dynamic Template Parameters
You can dynamically generate template parameters based on your environment or other conditions:
const getTemplateParameters = (env) => ({
title: env.production ? 'Production App' : 'Development App',
headMetaTags: [
`<meta name="environment" content="${env.production ? 'production' : 'development'}">`,
],
});
const loader = require.resolve('@hyperse/html-webpack-plugin-loader/loader');
module.exports = (env) => ({
plugins: [
new HtmlWebpackPlugin({
template: `${loader}!/xxx/src/index.html`,
templateParameters: getTemplateParameters(env),
}),
],
});
Multiple HTML Templates
You can use different template parameters for different HTML files:
const loader = require.resolve('@hyperse/html-webpack-plugin-loader/loader');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: `${loader}!/xxx/src/index.html`,
filename: 'index.html',
chunks: ['main'],
templateParameters: {
title: 'Main Application',
},
}),
new HtmlWebpackPlugin({
template: `${loader}!/xxx/src/index.html`,
filename: 'admin.html',
chunks: ['admin'],
templateParameters: {
title: 'Admin Dashboard',
},
}),
],
};
Loader Options
The loader accepts only one option:
force (boolean, optional): When set to true, forces template processing even if no template parameters are provided. Default is false.
Best Practices
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting pull requests.
License
This project is licensed under the MIT License - see the LICENSE file for details.