Search code examples
webpackwebpack-4laravel-mix

Find & replace inside a compiled HTML file using Laravel Mix


I am using the laravel-mix-criticalcss extension to generate an HTML file. Once that file is compiled, I need to run a find and replace in the HTML file source code to rewrite the URLs from relative to absolute. I tried using laravel-mix-string-replace, which uses string-replace-loader, but the replace never happens. I must be missing something with the way the webpack works. What am I missing?

const mix = require('laravel-mix');
const glob = require("glob");

require('laravel-mix-criticalcss');
require('laravel-mix-string-replace');

mix.setPublicPath('assets')
    .disableNotifications()
    .options({
        processCssUrls: false
    });

mix.criticalCss({
    enabled: true,
    paths: {
        base: 'http://lpb-cms.devel',
        templates: 'assets/css/',
        suffix: ''
    },
    urls: [
        {url: '/lpb-branding/get-header/', template: 'header-footer'},
    ],
    options: {
        minify: false,
        height: 19200,
        dest: 'header-footer.html',
        inline: true
    },
}).stringReplace({
    test: /\.html$/,
    loader: 'string-replace-loader',
    options: {
        search: '/themes/',
        replace: 'https://lpb-cms-dev.purecobalt.com/themes/',
    }
});

Solution

  • The laravel-mix-string-replace package doesn't seem to work.

    You can use the mix.after() method like this:

    const fs = require('fs');
    const path = require('path');
    
    mix.setPublicPath('assets')
        .disableNotifications()
        .options({
            processCssUrls: false
        });
    
    mix.criticalCss({
        enabled: true,
        paths: {
            base: 'http://lpb-cms.devel',
            templates: 'assets/css/',
            suffix: ''
        },
        urls: [
            {url: '/lpb-branding/get-header/', template: 'header-footer'},
        ],
        options: {
            minify: false,
            height: 19200,
            dest: 'header-footer.html',
            inline: true
        },
    }).after(stats => {
        // webpack compilation has completed
        fs.readFile(path.resolve(__dirname, 'header-footer.html'), 'utf8' , (readError, data) => {
            if (readError) {
                console.error("\x1b[31mError: \x1b[0m" + readError);
                return;
            }
    
            var result = data.replace('/themes/', 'https://lpb-cms-dev.purecobalt.com/themes/');
    
            fs.writeFile(path.resolve(__dirname, 'header-footer.html'), result, writeError => {
                if (writeError) {
                    console.error("\x1b[31mError: \x1b[0m" + writeError);
                    return;
                }
    
                console.log("Relative theme directory references replaced to full urls!");
            });
        })
    })
    

    If you need to replace more than one thing, you can chain the replacements:

    var result = data.replace('foo', 'bar').replace('this', 'that');