UNPKG

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
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 };