最近每天都在做網頁效能優化,過去 javascript 可能因為很多 plugin 增加了很多 request 次數,或許可以使用 parallel 方式來加速,但始終沒解決浪費頻寬問題,使用 uglify 可以方變得解決需要壓多個 javascript ,但如果網站有一堆頁面都要這樣做一次,每次出 build 都要做一次是非常累人的事,因此寫了一個 script 來處理這個累人的問題。之後再找時間來處理些 error handle 以及,包成一個完整的 module
使用方法很簡單,下載檔案後要先設定好幾個重要的路徑
// javascript 資料夾路徑(相對路徑,相對於 uglify.js這檔案)設定完後只要下簡單的一行,就會進行兩件事 1. 把 html files 符合 "jsTagRegex" 這規則的 javascript 拿掉,取代為 <script src="XXXXX.min.js"></scrips> 2. 把 html 頁面中會需要用到的 javascript 壓成一支
JSRootUrl = __dirname + '/js/',
// html 資料夾路徑(相對路徑,相對於 uglify.js這檔案)
viewRoot = __dirname+ '/../application/views',
// 要略過的檔案名稱( html 資料夾)
skipFiles = ['.DS_Store', 'mail'],
// 壓縮完的檔案名稱後需要加上哪些文字,例如 main.min.js
suffix = '.min',
// 要壓縮哪些 scripts 設定( html 資料夾的 tag 名稱)
jsTagRegex = /\\<\/script\>/ig,
node uglify
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
var fs = require('fs'), | |
sys = require('sys'), | |
exec = require('child_process').exec, | |
staticFolder = 'static', | |
jsFolder = 'js', | |
jsRoot = __dirname + '/' + jsFolder + '/', | |
htmlRoot = __dirname+ '/../application/views', | |
suffix = '.min', | |
skipFiles = ['.DS_Store', 'mail'], | |
sctiptsTag = '<script src="%s"></script>', | |
jsTagRegex = new RegExp( '\<script.*src\=\"\/' + staticFolder + '.*\".*\>\<\/script\>', 'ig'), | |
srcRegex = /src\=\".*\"/ig, | |
Core; | |
Core = module.exports = { | |
getFileList: function(path, cb) { | |
fs.readdir(path, function(err, files){ | |
return (err) ? cb(null) : cb(files); | |
}); | |
}, | |
getFile: function(path, cb) { | |
fs.readFile( path, function(err, data){ | |
return (err) ? cb(null) : cb(data.toString()); | |
}); | |
}, | |
getScriptsPath: function(fileData, cb) { | |
var scripts = fileData.match(jsTagRegex); | |
if(scripts && scripts.length){ | |
var fps = []; | |
for(var i in scripts){ | |
var script = scripts[i].match(srcRegex)[0], | |
fp = script.substr( 4, script.length); | |
fps.push(fp); | |
} | |
cb(fps); | |
}else{ | |
return cb(null); | |
} | |
}, | |
getViewScriptsJSPath: function( filePath, cb) { | |
var _this = this; | |
_this.getFile(filePath, function(fileData){ | |
_this.getScriptsPath(fileData, function(jsPaths){ | |
return cb(jsPaths); | |
}); | |
}); | |
}, | |
replaceFileNameExtension: function(fileName) { | |
return fileName.replace(/\.[^.]+$/i, '') + suffix + '.js'; | |
}, | |
getHtmlScriptTag: function(fName) { | |
fName = this.replaceFileNameExtension(fName); | |
return sctiptsTag.replace(/%s/i, '/' + staticFolder + '/' + jsFolder + '/' + fName); | |
}, | |
saveViewFileAndReplaceScripts: function( filePath, cb) { | |
var fna = filePath.split(/\//ig), | |
fName = fna[fna.length-1], | |
_this = this; | |
_this.getFile(filePath, function(fileData){ | |
fileData = fileData.replace(jsTagRegex, ''); | |
var fileDataArray = fileData.split(/\<\/body\>/i), | |
jsName = _this.getHtmlScriptTag(fName), | |
dataString = fileDataArray[0] + jsName + '</body>' + fileDataArray[1], | |
// save file | |
bufferString = new Buffer(dataString, 'utf8'); | |
fs.writeFile(htmlRoot + '/' + fName, bufferString, function(err){ | |
if(err){ | |
return console.log('save file error = ', err); | |
}else{ | |
return console.log('save file success = ', htmlRoot + fName); | |
} | |
}); | |
return; | |
}); | |
}, | |
commandline: function(cmd, cb) { | |
var _this = this; | |
exec( cmd, function (error, stdout, stderr) { | |
sys.print('stdout: ' + stdout); | |
sys.print('stderr: ' + stderr); | |
if (error !== null) { | |
console.log('exec error: ' + error); | |
} | |
return _this; | |
}); | |
}, | |
uglify: function(fileName, cb) { | |
var _this = this, | |
fPath = htmlRoot + '/' + fileName, | |
_fName = fileName, | |
_regex = new RegExp( '\/' + staticFolder + '\/' + jsFolder, 'i'); | |
this.getViewScriptsJSPath( fPath, function(jsPaths){ | |
if(!jsPaths){ | |
return; | |
} | |
for(var i in jsPaths){ | |
jsPaths[i] = jsPaths[i].replace( _regex, jsRoot); | |
} | |
var jsString = jsPaths.join(' '), | |
uglifyStr = 'uglifyjs ', | |
_fName = fileName.replace(/\.[^.]+$/i, ''); | |
uglifyStr += jsString + ' -o ' + jsRoot + _fName + suffix + '.js -c'; | |
return _this.commandline(uglifyStr); | |
}); | |
}, | |
}; | |
Core.getFileList(htmlRoot, function(viewFiles){ | |
for(var i in viewFiles){ | |
var fName = viewFiles[i], | |
fPath = htmlRoot + '/' + fName; | |
if(skipFiles.indexOf(fName) >= 0){ | |
continue; | |
} | |
Core.saveViewFileAndReplaceScripts(fPath); | |
Core.uglify(fName); | |
} | |
}); |
相關連結
uglify
沒有留言:
張貼留言