npm package: @guptast/wappler-cache-buster-minify
Description: Automatic cache busting with CSS/JS minification for static assets in Wappler NodeJS projects
Author: Shalabh Gupta
Latest version: 1.0.0

# @guptast/wappler-cache-buster-minify

Automatic cache busting with CSS/JS minification for static assets in Wappler NodeJS projects. This module extends the original `@benpley/wappler-cache-buster` by adding automatic minification of CSS and JavaScript files.

## Features

- ✅ **Automatic Minification**: Minifies CSS and JS files on-the-fly
- ✅ **Smart Caching**: Only re-minifies when source files change
- ✅ **Cache Busting**: Appends modification timestamps to prevent browser caching issues
- ✅ **Manual Installation**: Full control over extension setup and file placement
- ✅ **Zero Configuration**: Works out of the box once installed
- ✅ **Fallback Safe**: Gracefully handles missing files without breaking your site
- ✅ **Production Ready**: Optimized for performance with minimal overhead

## Installation

This package uses a **manual installation approach**, giving you full transparency and control.

### Step 1: Install the Package

From your Wappler project root directory, run:

```bash
npm install @guptast/wappler-cache-buster-minify
```

### Step 2: Create the Loader File

Create the file `extensions/server_connect/routes/cache-minify-loader.js` with the following content:

```javascript
/**
 * Cache Minify Module Loader
 */
module.exports = require('@guptast/wappler-cache-buster-minify').loader;
```

### Step 3: Restart Wappler

Restart your Wappler application to activate the extension.

You should see this message in your console:

```
✓ Minify Helper loaded - Cache busting with minification enabled for CSS/JS assets
```

### Manual Installation (Alternative)

If you prefer not to use npm, you can install manually:

1. Download the package files
2. Place them in your project's `node_modules/@guptast/wappler-cache-buster-minify/` directory
3. Create the loader file as described in Step 2
4. Restart Wappler

### Project Structure

After installation, your project will have:

```
your-project/
├── extensions/
│   └── server_connect/
│       └── routes/
│           └── cache-minify-loader.js  ← You create this
├── node_modules/
│   └── @guptast/
│       └── wappler-cache-buster-minify/  ← npm installs this
└── public/
    ├── css/
    │   ├── style.css          ← Your source file
    │   └── style.min.css      ← Auto-generated
    └── js/
        ├── app.js             ← Your source file
        └── app.min.js         ← Auto-generated
```

## Usage

### In EJS Templates

Use the `minify()` helper function in your templates:

```html
<!DOCTYPE html>
<html>
<head>
    <!-- Minified CSS with cache busting -->
    <link rel="stylesheet" href="<%=minify('/css/style.css')%>">
    <link rel="stylesheet" href="<%=minify('/css/components.css')%>">
</head>
<body>
    <!-- Your content -->
    
    <!-- Minified JavaScript with cache busting -->
    <script src="<%=minify('/js/app.js')%>"></script>
    <script src="<%=minify('/js/utils.js')%>"></script>
</body>
</html>
```

### What It Does

1. **For CSS/JS files**: 
   - Creates a minified version (e.g., `style.css` → `style.min.css`)
   - Only re-minifies when the source file changes
   - Returns path to minified file with cache-busting timestamp
   - Example output: `/css/style.min.css?v=1702324004815`

2. **For other file types** (images, fonts, etc.):
   - Adds cache-busting timestamp without minification
   - Example: `<%=minify('/images/logo.png')%>` → `/images/logo.png?v=1702324004815`

## How It Works

### Minification Process

1. **First Request**: When `minify('/css/style.css')` is called:
   - Checks if `style.min.css` exists
   - If not, or if `style.css` is newer, minifies the file
   - Saves the minified version to `public/css/style.min.css`
   - Returns path with cache-bust parameter

2. **Subsequent Requests**:
   - Checks modification times
   - Only re-minifies if source file has changed
   - Uses cached minified version otherwise

### Cache Busting

The version parameter (`?v=1702324004815`) is based on the file's last modification time:
- Changes only when the file is actually modified
- Browsers automatically fetch new versions when files change
- No manual cache clearing needed

## File Structure

Your project structure after installation:

```
your-project/
├── public/
│   ├── css/
│   │   ├── style.css          ← Your source file
│   │   └── style.min.css      ← Auto-generated
│   └── js/
│       ├── app.js             ← Your source file
│       └── app.min.js         ← Auto-generated
├── extensions/
│   └── server_connect/
│       └── routes/
│           └── cache-minify-loader.js  ← Created in Step 2
├── node_modules/
│   └── @guptast/
│       └── wappler-cache-buster-minify/  ← NPM package
└── views/
    └── index.ejs              ← Use minify() here
```

**Note**: You only need to maintain your source files (`.css` and `.js`). The minified versions are automatically created and updated.

## Wappler Integration

This package integrates with Wappler's Server Connect module system:

1. The loader file in `extensions/server_connect/routes/` registers the module
2. Wappler automatically detects and loads the module on startup
3. The `minify()` helper becomes available in all EJS templates
4. No additional configuration needed

## Best Practices

### 1. Add `.min.css` and `.min.js` to `.gitignore`

Since minified files are auto-generated, you don't need to commit them:

```gitignore
# Generated minified files
*.min.css
*.min.js
```

### 2. Commit Extension Files

**Do commit** the loader file you created:
- `extensions/server_connect/routes/cache-minify-loader.js`

This ensures all team members have the extension configured.

### 3. Development vs Production

The module works efficiently in both environments:

- **Development**: Automatically re-minifies when you save changes
- **Production**: Uses cached minified files for optimal performance

### 4. Error Handling

The module gracefully handles errors:
- Missing files: Returns original path with warning
- Minification errors: Returns original file path (site stays functional)
- All errors are logged to console for debugging

## Performance

- **First Load**: Small one-time cost to minify files
- **Subsequent Loads**: Near-zero overhead (just stat checks)
- **Typical Savings**: 60-80% reduction in CSS/JS file sizes

## Dependencies

- `uglify-js`: JavaScript minification
- `clean-css`: CSS minification

These are automatically installed with the package.

## Comparison with Original Cache Buster

| Feature | @benpley/wappler-cache-buster | @guptast/wappler-cache-buster-minify |
|---------|------------------------------|-------------------------------------|
| Cache Busting | ✅ | ✅ |
| CSS Minification | ❌ | ✅ |
| JS Minification | ❌ | ✅ |
| Smart Re-minification | N/A | ✅ |
| Installation Type | Manual | Manual |
| All File Types | ✅ | ✅ |

## Troubleshooting

### Minified files not being created

1. Check file permissions in your `public` directory
2. Verify the source files exist
3. Check console for error messages

### Changes not reflecting

1. Ensure you saved the source file
2. Check that the source file's modification time has changed
3. Hard refresh your browser (Ctrl+F5)

### Module not loading in Wappler

1. Ensure package is installed: `npm list @guptast/wappler-cache-buster-minify`
2. Verify the loader file exists:
   - `extensions/server_connect/routes/cache-minify-loader.js`
3. Check file contents match the installation instructions
4. Restart your Wappler application
5. Check console for the "✓ Minify Helper loaded" message

### Extension files not found

If Wappler can't find the module:

1. Double-check the directory path: `extensions/server_connect/routes/`
2. Ensure file name is exactly: `cache-minify-loader.js`
3. Verify file permissions allow Wappler to read them
4. Check for typos in the file contents

## Uninstallation

To remove the package:

### Step 1: Remove the NPM package
```bash
npm uninstall @guptast/wappler-cache-buster-minify
```

### Step 2: Remove the loader file
Delete the file:
- `extensions/server_connect/routes/cache-minify-loader.js`

### Step 3: Clean up generated files (optional)
Delete all `*.min.css` and `*.min.js` files in your `public` folder

### Step 4: Restart Wappler
Restart your Wappler application to complete the removal.

## Credits

- **Original Cache Buster**: Ben Pleysier ([@benpley](https://github.com/benpley))
- **Minification Enhancement**: Shalabh Gupta ([@guptast](https://github.com/guptast))

## License

MIT License - Feel free to use in personal and commercial projects.

## Support

wappler-cache-buster-minify/issues
- Wappler Forum: https://community.wappler.io

## Changelog

### Version 1.0.0
- Initial release
- CSS minification using clean-css
- JavaScript minification using uglify-js
- Smart re-minification based on file modification times
- Automatic cache busting with timestamps
- Manual installation for full transparency and control
- Graceful error handling
- Wappler Server Connect integration