因此,为了给您一些背景信息,我正在尝试创建一个生成器,它将创建一些文件(当然基于用户输入)以及更新项目中的一些现有文件(例如添加新路线)。
使用创建文件this.template
没问题......问题是:有没有办法用 Yeoman 做到这一点,而不必使用 Node 读取文件并进行一些奇特的查找和替换?
因此,为了给您一些背景信息,我正在尝试创建一个生成器,它将创建一些文件(当然基于用户输入)以及更新项目中的一些现有文件(例如添加新路线)。
使用创建文件this.template
没问题......问题是:有没有办法用 Yeoman 做到这一点,而不必使用 Node 读取文件并进行一些奇特的查找和替换?
好的,所以我找到了我的问题的答案。
Addy Osmani 向我展示了在 twitter 上查看此线程的位置,然后我后来找到了这个链接,它准确地显示了我需要的内容。
它的要点归结为两个功能:readFileAsString
和write
。用法如下:
var path = "/path/to/file.html",
file = this.readFileAsString(path);
/* make modifications to the file string here */
this.write(path, file);
编辑:我也在我的博客上写过这个。
正如 Toilal 在评论中提到的那样:
该
write
方法不再存在,必须替换为writeFileFromString
(参数也颠倒了)– Toilal
然后,正如 ivoba 在评论中提到的那样:
this.writeFileFromString
&this.readFileAsString
已弃用,现在应该使用 github.com/yeoman/html-wiring,情况会发生变化 :) – ivoba
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
功能。
结合@sepans 的出色答案,可以使用一些解析器,而不是使用正则表达式。
来自 Yeoman文档:
提示:更新现有文件的内容
更新预先存在的文件并不总是一项简单的任务。最可靠的方法是解析文件AST并对其进行编辑。此解决方案的主要问题是编辑 AST 可能很冗长且有点难以掌握。
一些流行的 AST 解析器是:
- Cheerio用于解析 HTML。
- 用于解析 JavaScript 的Esprima - 你可能对AST-Query感兴趣,它提供了一个较低级别的 API 来编辑 Esprima 语法树。
- 对于 JSON 文件,您可以使用本机JSON 对象方法。
用 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 ...
}
});
请注意,您可以在from
,to
参数中使用相同的路径来替换现有文件。
另一方面,这种解析器的缺点是在某些情况下它可能会过多地改变原始文件,虽然安全,但更具侵入性。
您可以使用mem-fs-editor并调用该fs.append(filepath, contents, [options])
方法。
例如
this.fs.append(this.contextRoot + "/index.html", " <p>Appended text</p>");
用于var text = this.fs.read(filePath)
从文件中读取并this.fs.write(filePath, content)
在位置写入文件。