Standardize settings file naming and relocate documentation files Fix code quality violations from rsx:check Reorganize user_management directory into logical subdirectories Move Quill Bundle to core and align with Tom Select pattern Simplify Site Settings page to focus on core site information Complete Phase 5: Multi-tenant authentication with login flow and site selection Add route query parameter rule and synchronize filename validation logic Fix critical bug in UpdateNpmCommand causing missing JavaScript stubs Implement filename convention rule and resolve VS Code auto-rename conflict Implement js-sanitizer RPC server to eliminate 900+ Node.js process spawns Implement RPC server architecture for JavaScript parsing WIP: Add RPC server infrastructure for JS parsing (partial implementation) Update jqhtml terminology from destroy to stop, fix datagrid DOM preservation Add JQHTML-CLASS-01 rule and fix redundant class names Improve code quality rules and resolve violations Remove legacy fatal error format in favor of unified 'fatal' error type Filter internal keys from window.rsxapp output Update button styling and comprehensive form/modal documentation Add conditional fly-in animation for modals Fix non-deterministic bundle compilation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
@jqhtml/webpack-loader
Webpack loader for JQHTML templates. Import .jqhtml files directly in your JavaScript!
Installation
npm install --save-dev @jqhtml/webpack-loader webpack
npm install @jqhtml/core jquery
Quick Start
1. Configure Webpack
Add the loader to your webpack.config.js:
module.exports = {
module: {
rules: [
{
test: /\.jqhtml$/,
use: '@jqhtml/webpack-loader'
}
]
},
resolve: {
extensions: ['.js', '.jqhtml']
}
};
Or use the configuration helper:
const { addJQHTMLSupport } = require('@jqhtml/webpack-loader');
module.exports = addJQHTMLSupport({
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
}
});
2. Create JQHTML Templates
Create UserCard.jqhtml:
<Define:UserCard>
<div class="user-card">
<h2 :text="name"></h2>
<p :text="email"></p>
<button @click="handleClick">Contact</button>
<% if (this.data.showBio): %>
<div class="bio" :html="bio"></div>
<% endif; %>
</div>
</Define:UserCard>
3. Import and Use
import UserCard from './UserCard.jqhtml';
import $ from 'jquery';
// Create component instance
const user = $('#user-container').component(UserCard, {
name: 'John Doe',
email: 'john@example.com'
});
// Set data
user.data = {
name: 'John Doe',
email: 'john@example.com',
showBio: true,
bio: '<p>Software developer</p>'
};
// Define methods
user.handleClick = function() {
console.log('Contact clicked!');
this.emit('contact', { user: this.data });
};
// Re-render to apply data
user.render();
Features
Multiple Components per File
<Define:Header>
<header>
<h1><%= this.data.title %></h1>
</header>
</Define:Header>
<Define:Footer>
<footer>
<p>© <%= this.data.year %></p>
</footer>
</Define:Footer>
Import all components:
import { Header, Footer } from './Layout.jqhtml';
// Default export is the first component
import DefaultHeader from './Layout.jqhtml';
Data Bindings
Use :prop syntax for reactive bindings:
:text="expression"- Text content:value="expression"- Input values:class="{active: isActive}"- Dynamic classes:style="{color: textColor}"- Dynamic styles:html="htmlContent"- HTML content (use carefully)
Event Handlers
Use @event syntax for event handling:
@click="methodName"- Call component method@change="updateValue"- Form events@submit="handleSubmit"- Form submission
Scoped IDs
Use $id for component-scoped element IDs:
<div $id="content">
<!-- Becomes id="content:abc123" where abc123 is the component's _cid -->
</div>
Access in component:
this.$id('content') // Returns jQuery element
Advanced Configuration
Loader Options
{
test: /\.jqhtml$/,
use: {
loader: '@jqhtml/webpack-loader',
options: {
sourceMap: true // Enable source maps (default: true)
}
}
}
With TypeScript
Add type declarations for .jqhtml imports:
// jqhtml.d.ts
declare module '*.jqhtml' {
import { Component } from '@jqhtml/core';
const component: typeof Component;
export default component;
// For multi-component files
export const Header: typeof Component;
export const Footer: typeof Component;
}
Production Build
The loader automatically handles production optimizations:
module.exports = {
mode: 'production',
module: {
rules: [
{
test: /\.jqhtml$/,
use: '@jqhtml/webpack-loader'
}
]
},
optimization: {
minimize: true
}
};
How It Works
- Parse - The loader uses
@jqhtml/parserto parse templates - Generate - Converts templates to ES module code
- Export - Each component becomes an ES6 class export
- Register - Components are automatically registered globally
The generated code looks like:
import { Component, render_template, register_component } from '@jqhtml/core';
export class UserCard extends Component {
static component_name = 'UserCard';
async on_render() {
const template_fn = function render() { /* ... */ };
await render_template(this, template_fn);
}
}
register_component('UserCard', UserCard);
export default UserCard;
Troubleshooting
Module Resolution
If webpack can't find .jqhtml files:
resolve: {
extensions: ['.js', '.jqhtml'],
modules: ['node_modules', 'src']
}
jQuery Not Found
Ensure jQuery is available:
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
Source Maps
For better debugging, ensure source maps are enabled:
devtool: 'source-map',
module: {
rules: [{
test: /\.jqhtml$/,
use: {
loader: '@jqhtml/webpack-loader',
options: { sourceMap: true }
}
}]
}
Examples
See the /examples directory for complete examples:
- Basic usage with vanilla JS
- TypeScript integration
- Multi-component layouts
- Complex data binding scenarios
License
MIT