Last active
August 29, 2015 14:14
-
-
Save chrisgonzalez/979bf20908b8743f0524 to your computer and use it in GitHub Desktop.
Buildify Script for CSS and JS tag replacement and minification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This file will replace blocks of script tags or css link tags nested between comments | |
* in html or any text file with the minified equivalents. The structure is as follows: | |
* | |
* For JavaScript: | |
* <!-- scripts [output file name w/ directory] --> | |
* [<script> tags live here] | |
* <!-- /scripts [output file name w/directory (matches above)] --> | |
* | |
* For CSS: | |
* <!-- styles [output file name w/ directory] --> | |
* [style <link> tags live here] | |
* <!-- /styles [output file name w/directory (matches above)] --> | |
* | |
* You can insert as many of these blocks as you'd like in your html/other file, | |
* all will be replaced with a single <link> or <script> per block, referencing | |
* the file name and path you specified in the opening comment. While it's not | |
* necessary to have the opening comment match the closing comment, they do need | |
* to be unique per block, as regex is annoying :) | |
* | |
* All files will be output to a /dist directory, and the html file will be output | |
* as index.html in the /dist directory. Look to line 94 for the index.html file name | |
* and look for /dist if you'd like to change the output directory. | |
* | |
**/ | |
var buildify = require('buildify'), | |
scripts = [], | |
styles = []; | |
// extract all comments: /<!--[\s\S]*?-->/g | |
// match anything between two (word)[\s\S]*(word) | |
buildify('src') | |
.load('index.html') | |
.perform(function(content) { | |
var i, j, outputFileName, | |
comments = content.match(/<!--[\s\S]*?-->/g); | |
// for each matching set of comments w/ filename | |
for (i = 0; i < comments.length; i+=2) { | |
// check that comment is of the type to parse (skip if it isn't!) | |
while (comments[i].indexOf('scripts') < 0 && comments[i].indexOf('styles') < 0) { | |
i++; | |
} | |
// opening and closing comment | |
var opening = comments[i], | |
closing = comments[i+1]; | |
// take entire block of scripts or styles | |
var regex = new RegExp('(' + opening + ')[\\s\\S]*' + '(' + closing + ')', 'gi'); | |
var enclosed = content.match(regex)[0]; | |
// if the match is a scripts block | |
if (enclosed.indexOf('scripts') > -1) { | |
console.log('Found a script block!'); | |
// parse out the file name | |
outputFileName = opening.replace('<!-- scripts', '').replace('-->', '').trim(); | |
// parse out the src attributes | |
var scriptSrc = enclosed.match(/src=\"[\s\S]*?\"/gi); | |
var scriptFiles = []; | |
for (j = 0; j < scriptSrc.length; j++) { | |
// strip out src and quotes | |
var src = scriptSrc[j].replace('src="', '').replace('"', ''); | |
scriptFiles.push(src); | |
} | |
// push a record for the build | |
scripts.push({ | |
filename: outputFileName, | |
files: scriptFiles | |
}); | |
// replace the whole block with a single script | |
content = content.replace(regex, '<script src="' + outputFileName + '"></script>') | |
// else if we've found a styles block | |
} else if (enclosed.indexOf('styles') > -1) { | |
console.log('Found a styles block!'); | |
// extract the desired css filename | |
outputFileName = opening.replace('<!-- styles', '').replace('-->', '').trim(); | |
// find the href attributes | |
var linkHref = enclosed.match(/href=\"[\s\S]*?\"/gi); | |
var styleFiles = []; | |
// parse out the desired file name | |
for (j = 0; j < linkHref.length; j++) { | |
var href = linkHref[j].replace('href="', '').replace('"', ''); | |
styleFiles.push(href); | |
} | |
// push a record of the stylesheet for the build | |
styles.push({ | |
filename: outputFileName, | |
files: styleFiles | |
}); | |
// replace the whole block with a single stylesheet <link> | |
content = content.replace(regex, '<link type="text/css" rel="stylesheet" href="' + outputFileName + '" />'); | |
} | |
} | |
return content; | |
}) | |
// change directory to 'dist' | |
.changeDir('../dist') | |
// save the file | |
.save('index.html'); | |
// for each script record | |
for (var i = 0; i < scripts.length; i++) { | |
// if it starts with '/' ie a root file, strip out the slash for finding it here | |
if (scripts[i].filename.charAt(0) === '/' ) { | |
scripts[i].filename = scripts[i].filename.substring(1); | |
} | |
// if more than one script, concat then uglify then save | |
if (scripts[i].files.length > 1) { | |
buildify('src') | |
.load(scripts[i].files[0]) | |
.concat(scripts[i].files.slice(1)) | |
.uglify() | |
.changeDir('../') | |
.save('dist/' + scripts[i].filename); | |
// else just uglify and save | |
} else { | |
buildify('src') | |
.load(scripts[i].files[0]) | |
.uglify() | |
.changeDir('../') | |
.save('dist/' + scripts[i].filename); | |
} | |
} | |
// for each style record | |
for (var j = 0; j < styles.length; j++) { | |
// if it's got a '/', strip that out so we can find the file | |
if (styles[j].filename.charAt(0) === '/' ) { | |
styles[j].filename = styles[j].filename.substring(1); | |
} | |
// if there's more than one style in the block, concat, minify then save | |
if (styles[j].files.length > 1) { | |
buildify('src') | |
.load(styles[j].files[0]) | |
.concat(styles[j].files.slice(1)) | |
.cssmin() | |
.changeDir('../') | |
.save('dist/' + styles[j].filename); | |
// else just minify and save | |
} else { | |
buildify('src') | |
.load(styles[j].files[0]) | |
.cssmin() | |
.changeDir('../') | |
.save('dist/' + styles[j].filename); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment