gulp-build-html
Version:
Used to process html files to automatically concat css and js files, and meanwhile update html references.
128 lines (108 loc) • 4.29 kB
JavaScript
var Vinyl = require('vinyl'),
GulpPluginError = require('gulp-util').PluginError,
utils = require("wzh.node-utils"),
fs = require("fs"),
path = require("path"),
Logger = require("xxlogger");
/** 插件名称 */
var PLUGIN_NAME = "gulp-build-html";
var logger = Logger.ofName(PLUGIN_NAME, PLUGIN_NAME + ".log");
logger.setLevel("warn");
/**
* 引入文件时需要同步调整引用的HTML标签及属性
* key:标签key,不区分大小写
* value:属性key,不区分大小写
* @type {{}}
*/
var htmlTagAndAttributeWhenRefactoringReference = {
link: "href",
script: "src",
img: "src",
audio: "src",
video: "src",
source: "src",
"source-placeholder": "src"
};
/**
* @constructor
* @param {String} msg 错误消息
*/
var newGulpPluginError = function(msg){
return new GulpPluginError(PLUGIN_NAME, msg);
};
/**
* 调整给定字符串中的资源引用中的路径,使其成为相对于提供的基准路径的相对路径
* @param {String} fileContent 声明资源引用的文件正文
* @param {String} fileAbsolutePath 声明资源引用的文件的绝对路径
* @param {String} baseAbsolutePath 调整资源引用的路径时,用于决定最终相对路径的基准路径的绝对路径。如:最终引用资源的html所在的目录
* @return {String} 调整后的字符串
*/
var updateReferenceAsRelativeTo = function(fileContent, fileAbsolutePath, baseAbsolutePath){
if(null == fileContent || "" === fileContent.trim())
return fileContent;
if(null == fileAbsolutePath || "" === fileAbsolutePath.trim())
fileAbsolutePath = process.cwd();
if(null == baseAbsolutePath || "" === baseAbsolutePath.trim())
baseAbsolutePath = "/";
var fileDirAbsolutePath = path.dirname(fileAbsolutePath);
logger.info("Updating resource reference in {} as relative to {}", fileAbsolutePath, baseAbsolutePath);
var newFileContent = fileContent;
var regexpArr = [];
for(var tagName in htmlTagAndAttributeWhenRefactoringReference)
regexpArr.push({
regexp: new RegExp("<\\s*" + tagName + "\\s+(.+?)\\s*\\/?\\s*>", "gim"),
attr: htmlTagAndAttributeWhenRefactoringReference[tagName]
});
/* css 中通过 url 声明的资源引用 */
regexpArr = regexpArr.concat({regexp: /\burl\b\s*\(\s*['"]?([^)'"]*)['"]?\s*\)/gim, attr: null});
regexpArr.forEach(function(s){
var linkRegExp = s.regexp;
var tmp, beginIndex, endIndex;
var dstString = "", attrStrIndex = 0, lastEndIndex = 0;
while((tmp = linkRegExp.exec(newFileContent)) != null){
logger.debug("Found reference: '{}' in '{}'", tmp[1], tmp[0]);
var src, srcValue;
if(null != s.attr && "" !== String(s.attr).trim()){
src = utils.html.getAttribute(tmp[1], s.attr);
var srcValue = !src? null: src.value.trim();
if(null == srcValue || "" === srcValue)
continue;
if(utils.url.isAbsolute(srcValue)){
logger.info("Skip {}", srcValue);
continue;
}
attrStrIndex = tmp[0].indexOf(tmp[1]);
beginIndex = tmp.index + attrStrIndex + src.valueIndex;
endIndex = beginIndex + src.value.length;
}else{
src = tmp[1];
srcValue = src.trim();
if(null == srcValue || "" === srcValue)
continue;
if(utils.url.isAbsolute(srcValue)){
logger.info("Skip {}", srcValue);
continue;
}
attrStrIndex = tmp[0].indexOf(tmp[1]);
beginIndex = tmp.index + attrStrIndex;
endIndex = beginIndex + srcValue.length;
}
var referredFileAbsolutePath = path.resolve(fileDirAbsolutePath, srcValue);
var replacement = path.relative(baseAbsolutePath, referredFileAbsolutePath).replace(/\\/gm, "/");
logger.debug("Base file: {}", path.resolve(baseAbsolutePath));
logger.debug("Referred file: {}", referredFileAbsolutePath);
logger.debug("Replacement: {}", replacement);
dstString += newFileContent.substring(lastEndIndex, beginIndex) + replacement;
lastEndIndex = endIndex;
}
dstString += newFileContent.substring(lastEndIndex);
newFileContent = dstString;
});
return newFileContent;
};
module.exports = {
PLUGIN_NAME: PLUGIN_NAME,
newGulpPluginError: newGulpPluginError,
updateReferenceAsRelativeTo: updateReferenceAsRelativeTo,
logger: logger
};