2
\$\begingroup\$

I am new to Javascript and Node.js but wanted to create a minifier in order to minify and escape double quotes in the HTML file. Could you let me know what I could improve in the code and how I can make it more efficient.

Here is my code:

'use strict';

var minify = require('html-minifier').minify;
const fs = require('fs');
var dir = './minifiedHTML';

if (!fs.existsSync(dir)){
    fs.mkdirSync(dir);
}


var tagsToReplace = {
  '"': '\"'
};

var htmlFile = fs.readFileSync("testminify.html", "utf8");

var result = minify(htmlFile, {
  collapseWhitespace: true,
  minifyCSS: true,
  processConditionalComments: true
});

result = addslashes(result)

fs.writeFile('minifiedHTML/minified.html', result, (err) => {  
  // throws an error, you could also catch it here
  if (err) throw err;

  // success case, the file was saved
  console.log('HTML file saved!');
});

function addslashes( str ) {
  return (str + '').replace(/[\\"]/g, '\\$&').replace(/\u0000/g, '\\0');
}
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$
var minify = require('html-minifier').minify;
const fs = require('fs');
var dir = './minifiedHTML';

Try consistently using const, let or var when declaring variables. Also, try using const first. That way, you're ensured that you are always dealing with the same thing through that variable throughout the lifetime of the app, and that any attempts to replace it would warn you. Use let if the value needs replacing (i.e. a counter) and var if the variable has to be function-scoped.

fs.writeFile('minifiedHTML/minified.html', result, (err) => {  
  // throws an error, you could also catch it here
  if (err) throw err;

  // success case, the file was saved
  console.log('HTML file saved!');
});

You're using synchronous APIs for everything except when writing to the file. I recommend also using the synchronous version of writing to a file, fs.writeFileSync() to keep it consistent. Your script is simple, and it's not blocking anything else, so making everything synchronous should be fine.

I'm making a big guess. You're trying to embed this HTML in JSON or JavaScript, and you're escaping the quotes so that it won't terminate the script mid-string. If possible, don't embed HTML (or any arbitrary string really). Just have it carry data, and let the receiving page do the rendering instead. Or you could encode the data in base64 so that it doesn't have quotes at all.


My initial guess was not that far from the intended goal. Building JSON with HTML content IS NOT an issue if you're building the JSON correctly. JSON.stringify() will correctly escape content that would otherwise break the resulting JSON (i.e. it will escape quotes). The only time escaping becomes an issue is when you're building the JSON manually.

Do NOT do the following:

const title = 'your title'
const subject = 'your subject'
const html = '<html lang="en"><body class="has-content">Hello, World!</body></html>'
const json = `{ "title": "${title}", "subject": "${subject}", "html": "${html}" }`

console.log('Invalid JSON:', json)

// This will blow up
console.log('Test parse', JSON.parse(json))

Instead, use JSON.stringify():

const title = 'your title'
const subject = 'your subject'
const html = '<html lang="en"><body class="has-content">Hello, World!</body></html>'
const json = JSON.stringify({ title, subject, html })

console.log('Valid JSON:', json)
console.log('Test parse', JSON.parse(json))

\$\endgroup\$
2
  • \$\begingroup\$ @Joesph I don't know if this should be a separate question, but the goal of this is to create an email template which is a JSON file with Subject and text. the html part is in the middle '{ "subject": "subject line", "html": "html", "text": "text." }' \$\endgroup\$ Commented Jun 17, 2019 at 12:58
  • 1
    \$\begingroup\$ @user6248190 Updated answer. \$\endgroup\$
    – Joseph
    Commented Jun 17, 2019 at 13:51

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.