Yeoman发电机可以更新现有文件吗?

问题描述 投票:30回答:4

所以只是为了给你一些上下文,我正在尝试创建一个生成器,它将创建一些文件(当然基于用户输入)以及更新项目中的一些现有文件(例如添加新路径)。

使用this.template创建文件是没有问题的......问题是:有没有办法用Yeoman做这个,而不必使用Node读取文件并做一些奇特的查找和替换?

yeoman yeoman-generator
4个回答
25
投票

好的,所以我找到了问题的答案。

Addy Osmani向我展示了在哪里可以看到this thread on twitter,然后我发现this link正好显示了我需要的东西。

它的要点归结为两个功能:readFileAsStringwrite。用法如下:

var path = "/path/to/file.html",
    file = this.readFileAsString(path);

/* make modifications to the file string here */

this.write(path, file);

编辑:我也写过关于这个on my blog的博客。

编辑1

如Toilal的评论中所述:

write方法不再存在,必须由writeFileFromString替换(参数也相反) - Toilal

编辑2

然后,如ivoba的评论中所述:

this.writeFileFromStringthis.readFileAsString已弃用,github.com / yeoman / html-wiring现在应该使用,事情会发生变化:) - ivoba


22
投票

Yeoman还使用mem-fs-editor提供更优雅的fs操作方式。

您可以使用this.fs.copy,将流程函数作为选项传递给内容进行任何修改:

this.fs.copy(path, newPath, {
    process: function(content) {

        /* Any modification goes here. Note that contents is a Buffer object */

        var regEx = new RegExp('old string', 'g');
        var newContent = content.toString().replace(regEx, 'new string');
        return newContent;
    }
});

这样您还可以利用mem-fs-editor功能。


3
投票

结合@sepans的优秀答案,可以使用一些解析器,而不是使用正则表达式。

来自Yeoman documentation

Tip: Update existing file's content

更新预先存在的文件并不总是一项简单的任务。最可靠的方法是解析文件AST并编辑它。这个解决方案的主要问题是编辑AST可能很冗长,有点难以掌握。

一些流行的AST解析器是:

  • Cheerio用于解析HTML。
  • Esprima用于解析JavaScript - 您可能对AST-Query感兴趣,它提供了一个较低级别的API来编辑Esprima语法树。
  • 对于JSON文件,您可以使用本机JSON object methods

使用RegEx解析代码文件是危险的路径,在此之前,您应该阅读此CS anthropological answers并掌握RegEx解析的缺陷。如果您确实选择使用RegEx而不是AST树编辑现有文件,请小心并提供完整的单元测试。 - 请,请不要破坏用户的代码。

更具体地说,当使用esprima时,你很可能还需要一些生成器,如escodegen来生成js。

var templatePath = this.destinationPath(...);
this.fs.copy(templatePath, templatePath, {
  process: function (content) {
    // here use the parser
    return ...
  }
});

请注意,您可以在fromto参数中使用相同的路径以替换现有文件。

另一方面,这种解析器的缺点是在某些情况下它可能会改变原始文件的方式太多,虽然安全,但这更具侵入性。


0
投票

使用var text = this.fs.read(filePath)从文件中读取,使用this.fs.write(filePath, content)写入位置的文件。

© www.soinside.com 2019 - 2024. All rights reserved.