Gulp工具通过css类或xml标记去除代码
我试图创建一个工具来删除在gulp进程中运行的特定xml标记。我们的想法是前端有虚拟内容。然而,在后端集成的下一阶段,它将虚拟内容包装在xml标签中,并根据xml标签名称动态地插入一些带有变量的后端代码。对于这种情况,有PHP,但这个想法是创建一个工具插入任何后端代码Gulp工具通过css类或xml标记去除代码
我所遇到gulp-remove-code
,但问题是它的硬编码的名称和index.js
从内部正则表达式节点模块根据具有特定空间的注释进行匹配。 “
此外,我已经看过gulp-inject-string
标签之前将新的内容。所以最终的想法是标记的XML标签名,注入标签上面的新代码,然后在标签去除一切。
//markup.html
<div class="home">
// some text
<div class="home__text">
<cms_home_text>
My dummy text
</cms_home_text>
</div>
// an image
<div class="home__image">
<cms_home_image>
<img src="someImage.png" alt="some alt" />
</cms_home_image>
</div>
// a link
<div class="home__link">
<cms_home_link1>
<a href="someLink1.html">here</a>
</cms_home_link1>
</div>
// another link
<div class="home__link">
<cms_home_link2>
<a href="someLink2.html">here</a>
</cms_home_link2>
</div>
</div>
成为
//markup.php
<div class="home">
// some text
<div class="home__text">
<?php $cms_home_text ?>
</div>
// an image
<div class="home__image">
<img src="<?php $cms_home_image ?>" alt="<?php $cms_home_image_alt ?>" />
</div>
// a link
<div class="home__link">
<a href=<?php $cms_home_link1 ?>">
<?php $cms_home_link1_text ?>
</a>
</div>
// another link
<div class="home__link">
<a href=<?php $cms_home_link2 ?>">
<?php $cms_home_link2_text ?>
</a>
</div>
</div>
我尝试了一些东西,但得到这个工作,只要你想我的想法。
const gulp = require("gulp");
const fs = require('fs');
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
// hard-coded here but could be a gulp.src stream if you have more than one file to translate
const html = 'markup.html';
gulp.task('default', [addPHP]);
gulp.task('addPHP', function() {
var dirty;
var temp;
var clean;
dirty = fs.readFileSync(html, 'utf8');
var frag = new JSDOM(dirty);
console.dir(frag.window.document.body.children[0].children);
var HLinks = frag.window.document.querySelectorAll("div.home__link");
var HImages = frag.window.document.querySelectorAll("div.home__image");
var HTexts = frag.window.document.querySelectorAll("div.home__text");
// <div class="home__text">
// <cms_home_text>
// My dummy text
// </cms_home_text>
// </div>
// <div class="home__text">
// <?php $cms_home_text ?>
// </div>
HTexts.forEach(function (el, index, list) {
console.log(el.className);
var cmsTagName = el.childNodes[1].nodeName.toLowerCase();
console.log(cmsTagName);
var innerLink = frag.window.document.createTextNode("<?php $" + cmsTagName + "_text ?>");
el.replaceChild(innerLink, el.childNodes[1]);
});
// <cms_home_image>
// <img src="someImage.png" alt="some alt" />
// </cms_home_image>
// <img src="<?php $cms_home_image ?>" alt="<?php $cms_home_image_alt ?>" />
HImages.forEach(function (el, index, list) {
console.log(el.className);
var cmsTagName = el.childNodes[1].nodeName.toLowerCase();
console.log(cmsTagName);
var temp = frag.window.document.createElement("img");
temp.src = "<?php $" + cmsTagName + " ?>";
temp.alt = "<?php $" + cmsTagName + "_alt ?>"
el.replaceChild(temp, el.childNodes[1]);
});
// <cms_home_link1>
// <a href="someLink1.html">here</a>
// </cms_home_link1>
// <a href="<?php $cms_home_link1 ?>">
// <?php $cms_home_link1_text ?>
// </a>
HLinks.forEach(function (el, index, list) {
console.log(el.className);
var cmsTagName = el.childNodes[1].nodeName.toLowerCase();
console.log(cmsTagName);
var tempLink = frag.window.document.createElement("a");
tempLink.href = "<?php $" + cmsTagName + " ?>";
var innerLink = frag.window.document.createTextNode("<?php $" + cmsTagName + "_text ?>");
tempLink.appendChild(innerLink);
el.replaceChild(tempLink, el.childNodes[1]);
});
// because createTextNode changes <> to htmlEntities
var cleaned = frag.window.document.querySelector("div.home").outerHTML.replace(/</gm, "<").replace(/>/gm, ">");
fs.writeFileSync("markup.php", cleaned, 'utf8');
return;
})
我认为这只是一种regExp方法,但可能会像您提到的那样太脆弱。我也考虑过sanitize-html,它可以帮助你实现目标,并且很方便地了解。
还有其他的HTML/DOM解析器,如htmlparser和xmldom,但jsdom似乎是最容易与我合作。
此代码的主要部分脆是行:
var cmsTagName = el.childNodes[1].nodeName.toLowerCase();
出现在每个在foreach呼叫。如果您的dom结构与您的示例不同,以便标签不是el.childNodes 1,您将不得不修改此代码。并注意空textNodes。我似乎想起了一个选择器,它可以跳过空的textNodes,但我现在不记得它。
让我知道这是否适合你。
缓冲区来自一个获取file.contents以传递给函数的gulp流。然后当内容不为空时,我们得到每个文档中匹配的数量,然后循环并采用与reg-ex相匹配的对象。
我们提取完整匹配,ID和类型,然后替换为动态php代码,以便前端可以具有自定义变量,以及针对文本,图像和链接的特定响应。
function applyReplacements(buffer) {
var contents = buffer.toString('utf8');
const regex = /<(cms_.*)(.\b[^>]*)\b[^>]*>((.|\n)*?)<\/\1>/g;
let m,cmsReplace,finalMatch,cmsID,cmsType;
if (contents.length > 0) {
while ((m = regex.exec(contents)) !== null) {
let target = contents.match(regex).length;
for(let i=0;i< target;i++){
//This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
if(groupIndex == 0){
cmsReplace = match;
}
else if(groupIndex == 1) {
cmsID = match;
}
else if(groupIndex == 2) {
cmsType = match.split('"')[1];
// provide the final replacment variables
if(cmsType == "cmsImage") {
finalMatch = '<img src="<?php $'+cmsID+'?>" alt="<?php $'+cmsID+'_alt ?>" width="100%" height="100%" />';
} else if(cmsType == "cmsLink") {
finalMatch = '<a href="<?php $'+cmsID+' ?>"><?php $'+cmsID+'_text ?></a>';
} else {
finalMatch = '<?php $'+cmsID+' ?>';
}
contents = contents.replace(cmsReplace,finalMatch);
}
});
}
}
}
return new Buffer(contents);
}
嗨马克感谢回来,这是真棒。我将在发布2天后发布我提出的解决方案。我采用了正则表达式的方法。将测试你的代码出tmoz,看看哪一个更快。 – Paddy