Skip to content

Instantly share code, notes, and snippets.

@Nitive
Last active June 26, 2017 15:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nitive/506b68e6db87fdd39eff9d25bf99da06 to your computer and use it in GitHub Desktop.
Save Nitive/506b68e6db87fdd39eff9d25bf99da06 to your computer and use it in GitHub Desktop.
Util to normalise html to compare server and client rendering for react apps
const fs = require('fs')
const posthtml = require('posthtml')
function merge(...objs) {
return Object.assign({}, ...objs)
}
function removeAttr(attr, tree) {
tree.match({ attrs: { [attr]: true } }, node => {
return merge(node, { attrs: merge(node.attrs, { [attr]: undefined }) })
})
}
function removeReactTextId(node) {
if (typeof node === 'string' && node.includes('react-text: ')) {
return '<!-- react-text (id removed) -->'
}
return node
}
function addLineBreaks(node) {
if (Array.isArray(node.content)) {
return merge(node, { content: ['\n', ...node.content, '\n'] })
}
return node
}
function removeWhitespacesInStyle(node) {
if (node.attrs && node.attrs.style) {
return merge(node, { attrs: merge(node.attrs, { style: node.attrs.style.replace(/ /g, '')}) })
}
return node
}
function sortAttrs(node) {
if (node.attrs) {
const attrs = Object.keys(node.attrs).sort().reduce((acc, key) => {
return merge(acc, { [key]: node.attrs[key] })
}, {})
return merge(node, { attrs })
}
return node
}
function normalizeNbsp(node) {
if (typeof node === 'string' && node.includes('&nbsp;')) {
const NBSP = ' '
return node.replace(/&nbsp;/g, NBSP)
}
return node
}
function plugin(config) {
return function(tree) {
removeAttr('data-reactid', tree)
removeAttr('data-reactroot', tree)
removeAttr('data-react-checksum', tree)
tree.walk(removeReactTextId)
tree.walk(addLineBreaks)
tree.walk(normalizeNbsp)
tree.walk(removeWhitespacesInStyle)
tree.walk(sortAttrs)
}
}
function run(file) {
const html = fs.readFileSync(`./${file}.html`, 'utf8')
posthtml([plugin({})])
.process(html)
.then(result => {
fs.writeFileSync(`./${file}.post.html`, result.html)
})
.catch(console.error)
}
const files = ['client', 'server']
files.forEach(run)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment