Skip to content

Instantly share code, notes, and snippets.

@bradparker
Created January 15, 2016 03:00
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 bradparker/72e30598eb42547658ba to your computer and use it in GitHub Desktop.
Save bradparker/72e30598eb42547658ba to your computer and use it in GitHub Desktop.
simple revision-er
'use strict'
const crypto = require('crypto')
const fs = require('fs')
const mkdirp = require('mkdirp')
const path = require('path')
const recursive = require('recursive-readdir')
const assign = Object.assign
const keys = Object.keys
const HTML_EXTENSIONS = ['.html', '.htm']
const UTF8_EXTENSIONS = HTML_EXTENSIONS.concat(
['.js', '.css']
)
const BASE_DIR = path.resolve(__dirname, '../')
const SOURCE_DIR = path.join(BASE_DIR, './.dev')
const DEST_DIR = path.join(BASE_DIR, './dist')
const inArray = (arr, member) => (arr.indexOf(member) !== -1)
const isHtml = (file) => (inArray(HTML_EXTENSIONS, path.extname(file)))
const isUTF8 = (file) => (inArray(UTF8_EXTENSIONS, path.extname(file)))
const createNewContent = (manifest, content) => {
return keys(manifest).reduce((updatedContent, file) => {
const asset = path.relative(SOURCE_DIR, file)
return updatedContent.replace(`/${ asset }`, `/${ manifest[file].name }`)
}, content)
}
const addHashToFile = (file, hash) => {
const ext = path.extname(file)
const name = path.basename(file, ext)
return `${ name }-${ hash }${ ext }`
}
const newFileName = (file, hash) => {
if (!isHtml(file) && !file.match(/main.js/)) {
return path.relative(
SOURCE_DIR,
path.join(path.dirname(file),
addHashToFile(file, hash))
)
} else {
return path.relative(
SOURCE_DIR,
file
)
}
}
const process = (file, callback) => {
const stream = fs.createReadStream(file)
const hasher = crypto.createHash('sha1')
let content = ''
stream.on('data', (chunk) => {
if (isUTF8(file)) { content += chunk }
hasher.update(chunk)
})
stream.on('end', () => {
const name = newFileName(file, hasher.digest('hex'))
callback(null, { name, content })
})
}
const createManifest = (files, callback) => {
let remaining = files.length
let manifest = {}
files.forEach((file) => {
process(file, (err, result) => {
if (err) {
return callback(err)
}
manifest[file] = result
--remaining
if (remaining <= 0) {
callback(null, manifest)
}
})
})
}
recursive(SOURCE_DIR, (err, files) => {
createManifest(files, (err, manifest) => {
const manifestFiles = keys(manifest)
let remaining = manifestFiles.length
manifestFiles.forEach((file) => {
const properties = manifest[file]
const content = createNewContent(manifest, properties.content)
const fullPath = path.join(DEST_DIR, properties.name)
const directory = path.dirname(fullPath)
mkdirp(directory, () => {
fs.writeFile(fullPath, content, (err) => {
console.log('Reved: ', fullPath)
--remaining
if (remaining <= 0) {
console.log('Rev all complete')
}
})
})
})
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment