【问题标题】:Gulp tool to remove code by either css class or xml tag通过 css 类或 xml 标签删除代码的 Gulp 工具
【发布时间】:2017-09-27 03:12:01
【问题描述】:

我正在尝试创建一个工具来删除在 gulp 进程中运行的特定 xml 标记。这个想法是,对于前端我们有虚拟内容。然而,在后端集成的下一阶段,它采用包装在 xml 标记中的虚拟内容,并根据 xml 标记名称动态插入一些带有变量的后端代码。对于这种情况,有 php,但想法是创建一个工具来插入任何后端代码

我遇到过gulp-remove-code,但问题是它的所有硬编码名称和来自节点模块的index.js 内的正则表达式基于具有特定空格的 cmets 匹配。 "

此外,我查看了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>

【问题讨论】:

    标签: html xml gulp continuous-integration devops


    【解决方案1】:

    我尝试了一些东西,但我认为它可以正常工作。

    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(/&lt;/gm, "<").replace(/&gt;/gm, ">");
    
    
      fs.writeFileSync("markup.php", cleaned, 'utf8');
      return;
    })
    

    我只考虑了一种正则表达式方法,但正如您提到的那样,这可能太脆弱了。我还考虑了sanitize-html,它可以让您朝着目标前进很长一段路,并且很容易了解。

    还有其他 html/dom 解析器,例如 htmlparser 和 xmldom,但 jsdom 对我来说似乎最容易使用。

    这段代码主要的脆弱部分是这一行:

    var cmsTagName = el.childNodes[1].nodeName.toLowerCase();
    

    出现在每个 forEach 调用中。如果您的 dom 结构与您的示例不同,因此标签不是 el.childNodes1 您将不得不修改此代码。并注意空的文本节点。我似乎记得一个会跳过空文本节点的选择器,但我现在想不起来了。

    让我知道这是否适合你。

    【讨论】:

    • 嘿,马克感谢您回来,这太棒了。我还将发布我在破解 2 天后提出的解决方案。我采用了正则表达式方法。将在 tmoz 中测试您的代码,看看哪个更快。
    【解决方案2】:

    缓冲区来自获取 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);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 2019-02-19
      相关资源
      最近更新 更多