cloudcmd/lib/server/minify.js
2012-07-07 12:15:52 -04:00

350 lines
No EOL
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Модуль сжатия js-скриптов и css*/
console.log('minify.js loaded...');
/* функция сжимает js-скрипты
* и сохраняет их с именем .min.js
*/
var fs = require('fs');
var path=require('path');
var MinFolder='min/';
/* function clear MinFolder
* if we could not create
* directory and it is
* not exist
*/
var folderExist = function(pError, pStat){
"use strict";
/*file found and it's directory */
if(!pError && pStat.isDirectory())
console.log('folder exist: ' + MinFolder);
else MinFolder='/';
};
/*
* function says thet folder created
* if everything is OK, or
* moves to folderExist function
*/
var makeFolder = function(pError){
"use strict";
/*folder created successfully*/
if(!pError)
console.log('folder created: min');
else fs.stat(MinFolder,folderExist);
};
/* Trying to create folder min
* where woud be minifyed versions
* of files 511(10)=777(8)
* rwxrwxrwx
*/
fs.mkdir(MinFolder,511,makeFolder);
exports.MinFolder = MinFolder;
/* function which minificate js-files
* @pJSFiles_a - varible, wich contain array
* of js file names or string, if name
* single
*/
exports.jsScripts=function jsScripts(pJSFiles_a){
'use strict';
/* подключаем модуль uglify-js
* если его нет - дальнейшая
* работа функции не имеет смысла
*/
try{
var jsp = require("uglify-js").parser;
var pro = require("uglify-js").uglify;
}catch(error){
console.log('can\'n load uglify-js\n' +
'to use js-minification you need to install uglify-js\n' +
'npm install uglify-js\n' +
'https://github.com/mishoo/UglifyJS');
return false;
}
/* Константы */
var CLIENT_JS='client.js';
var CLOUDFUNC_JS='lib/cloudfunc.js';
if(typeof pJSFiles_a === "string")
pJSFiles_a=[pJSFiles_a];
var dataReaded_f=function(pFileName, pData){
console.log('file ' + pFileName + ' readed');
/*********************************/
/* сжимаем код через uglify-js */
var uglify_js=function(pDdata){
var orig_code = pDdata.toString();
var ast = jsp.parse(orig_code); // parse code and get the initial AST
ast = pro.ast_mangle(ast); // get a new AST with mangled names
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
var result_code = pro.gen_code(ast); // compressed code here
return result_code;
};
/*********************************/
var final_code=uglify_js(pData);
var minFileName=pFileName.replace('.js','.min.js');
/* если мы сжимаем client.js -
* меняем строку cloudfunc.js на
* cloudfunc.min.js и выводим сообщение
*
* меняем строку keyBinding.js на
* keyBinding.min.js
* если другой файл - ничего не деалем
*/
/*
* temporary changed dir path,
* becouse directory lib is write
* protected by others by default
* so if node process is started
* from other user (root for example
* in nodester) we can not write
* minified versions
*/
if(pFileName===CLIENT_JS)
console.log('file name of ' +
CLOUDFUNC_JS +
' in ' +
CLIENT_JS +
' changed. size:',
(final_code=final_code
.replace('cloudfunc.js','cloudfunc.min.js')
.replace('keyBinding.js','keyBinding.min.js')
.replace('/lib/', MinFolder)
.replace('/lib/client/', MinFolder)).length);
/* minimized file will be in min file
* if it's possible if not -
* in root
*/
minFileName = MinFolder + path.basename(minFileName);
/* записываем сжатый js-скрипт*/
fs.writeFile(minFileName, final_code, fileWrited(minFileName));
};
/* moving thru all elements of js files array */
for(var i=0;pJSFiles_a[i];i++){
console.log('reading file ' + pJSFiles_a[i]+'...');
fs.readFile(pJSFiles_a[i],fileReaded(pJSFiles_a[i],dataReaded_f));
}
return true;
};
/* функция сжимает css-стили
* и сохраняет их с именем .min.css
* @pImgConvertToBase64_b - булевый признак,
* который отвечает за то, что быконвертировать
* картинки в base64 и поместить в выходной css файл
* @pCSSFiles_a - масив имен css файлов или строка,
* если имя одно
*/
exports.cssStyles=function cssStyles(pCSSFiles_a, pImgConvertToBase64_b){
'use strict';
/* connecting cleanCSS,
* if we can't find it -
* return false
*/
var cleanCSS;
try{
cleanCSS = require('clean-css');
}catch(error){
console.log('can\'n load clean-css \n' +
'to use css-minification you need to install clean-css \n' +
'npm install clean-css\n' +
'https://github.com/GoalSmashers/clean-css');
return false;
}
if(typeof pCSSFiles_a === "string")
pCSSFiles_a=[pCSSFiles_a];
/* Varible contains information
* about readed css file
*/
var lCSSFiles_doneCount=0;
var lAllStyle='';
var dataReaded_f=function(pFileName, pData){
console.log('file ' + pFileName + ' readed');
/*********************************/
/* сжимаем код через clean-css */
var clean_css=function(pData){
/* Сохраняем весь стиль в одну переменную*/
return cleanCSS.process(pData);
};
/*********************************/
var final_code=clean_css(pData);
lAllStyle+=final_code;
var minFileName=pFileName.replace('.css','.min.css');
++lCSSFiles_doneCount;
/* if all files writed we
* save all minimized css
* to one file all.min.css
*/
if(pCSSFiles_a.length === lCSSFiles_doneCount){
/* если включена конвертация картинок в base64
* вызываем её
*/
if(pImgConvertToBase64_b)
base64_images(lAllStyle);
else
fs.writeFile(MinFolder + 'all.min.css', lAllStyle, fileWrited(MinFolder + 'all.min.css'));
}
/* в другом случае - записываем сжатый css файл*/
else{
minFileName = MinFolder + path.basename(minFileName);
fs.writeFile(minFileName, final_code, fileWrited(minFileName));
}
};
/* moving thru all elements of css files array */
for(var i=0;pCSSFiles_a[i];i++){
console.log('reading file ' + pCSSFiles_a[i]+'...');
fs.readFile(pCSSFiles_a[i],fileReaded(pCSSFiles_a[i],dataReaded_f));
}
return true;
};
/* функция сжимает html файлы
* и сохраняет их с именем .min.html
* @pHTMLFiles_a - массим имен html
* файлов, или строка если имя одно
*/
exports.html=function(pHTMLFiles_a){
'use strict';
/* connecting cleanCSS,
* if we can't find it -
* return false
*/
var htmlMinifier;
try{
htmlMinifier = require('html-minifier');
}catch(error){
console.log('can\'n load html-minifier \n' +
'to use html-minification you need to install html-minifier\n' +
'npm install html-minifier\n' +
'https://github.com/kangax/html-minifier');
return false;
}
if(typeof pHTMLFiles_a === "string")
pHTMLFiles_a=[pHTMLFiles_a];
var dataReaded_f=function(pFileName, pData){
console.log('file ' + pFileName + ' readed');
/*********************************/
/* сжимаем код через clean-css */
var html_minify=function(pData){
/* Сохраняем весь стиль в одну переменную*/
var lOptions={
removeComments: true,
removeCommentsFromCDATA: true,
removeCDATASectionsFromCDATA: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeAttributeQuotes: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
/* оставляем, поскольку у нас
* в элемент fm генерируеться
* таблица файлов
*/
removeEmptyElements: false,
removeOptionalTags: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true
};
return htmlMinifier.minify(pData,lOptions);
};
/*********************************/
var final_code=html_minify(pData);
var minFileName=pFileName.replace('.html','.min.html');
/* adding Min folder to file path */
minFileName = MinFolder + minFileName;
/* записываем сжатый html файл*/
fs.writeFile(minFileName, final_code, fileWrited(minFileName));
};
/* moving thru all elements of css files array */
for(var i=0;pHTMLFiles_a[i];i++){
console.log('reading file ' + pHTMLFiles_a[i]+'...');
fs.readFile(pHTMLFiles_a[i],fileReaded(pHTMLFiles_a[i],dataReaded_f));
}
return true;
};
/* функция переводит картинки в base64 и записывает в css-файл*/
function base64_images(pFileContent_s){
'use strict';
var b64img;
try{
b64img = require('css-b64-images');
}catch(error){
console.log('can\'n load clean-css \n' +
'to use images to base64 convertation you need to install css-base64-images \n' +
'npm install -g css-b64-images\n' +
'https://github.com/Filirom1/css-base64-images');
return false;
}
b64img.fromString(pFileContent_s, '.','', function(err, css){
console.log('images converted to base64 and saved in css file');
fs.writeFile(MinFolder + 'all.min.css', css, fileWrited(MinFolder + 'all.min.css'));
});
}
/* Функция создаёт асинхроную версию
* для чтения файла
* @pFileName - имя считываемого файла
*/
function fileReaded(pFileName,pCompressFunc){
"use strict";
return function(pError,pData){
/* функция в которую мы попадаем,
* если данные считались
*
* если ошибка - показываем её
* иначе если переданная функция -
* функция запускаем её
*/
if(!pError)
if (pCompressFunc && typeof pCompressFunc==="function")
pCompressFunc(pFileName,pData.toString());
else console.log(pError);
};
}
/*
* Функция вызываеться после записи файла
* и выводит ошибку или сообщает,
* что файл успешно записан
*/
function fileWrited(pFileName){
"use strict";
return function(error){
console.log(error?error:('file '+pFileName+' writed...'));
};
}