【问题标题】:What's the recommended way to copy multiple dotfiles with yeoman?用 yeoman 复制多个点文件的推荐方法是什么?
【发布时间】:2014-07-19 21:04:21
【问题描述】:

我正在为一个相当典型的节点应用程序构建一个 yeoman 生成器:

/
|--package.json
|--.gitignore
|--.travis.yml
|--README.md
|--app/
    |--index.js
    |--models
    |--views
    |--controllers

在我的 yeoman 生成器的模板文件夹中,我必须重命名点文件(和 package.json)以防止它们作为生成器的一部分被处理:

templates/
 |--_package.json
 |--_gitignore
 |--_travis.yml
 |--README.md
 |--app/
     |--index.js
     |--models
     |--views
     |--controllers

我看到很多手动复制点文件的生成器:

this.copy('_package.json', 'package.json')
this.copy('_gitignore', '.gitignore')
this.copy('_gitattributes', '.gitattributes')

我认为在添加新模板文件时手动更改生成器代码很痛苦。我想自动复制 /templates 文件夹中的所有文件,并重命名以 _ 为前缀的文件。

最好的方法是什么?

如果我用虚构的正则表达式来描述我的意图,它会是这样的:

this.copy(/^_(.*)/, '.$1')
ths.copy(/^[^_]/)

编辑 这是我能做到的最好的:

this.expandFiles('**', { cwd: this.sourceRoot() }).map(function() {
    this.copy file, file.replace(/^_/, '.')
}, this);

【问题讨论】:

    标签: yeoman yeoman-generator


    【解决方案1】:

    我在寻找解决方案时通过谷歌找到了这个问题,然后我自己想通了。

    使用新的fs API,您可以使用 glob!

    // Copy all non-dotfiles
    this.fs.copy(
      this.templatePath('static/**/*'),
      this.destinationRoot()
    );
    
    // Copy all dotfiles
    this.fs.copy(
      this.templatePath('static/.*'),
      this.destinationRoot()
    );
    

    【讨论】:

    • 另外,值得注意的是,如果您使用的是来自目的地的 glod in,则需要是一个目录。
    • 这是正确的答案,值得点赞。有关用法示例,请参阅我的最新提交:github.com/srsgores/generator-stylus-boilerplate/commit/…
    • 谢谢!此外,对于相对目的地,this.destinationRoot() 可以替换为 this.destinationPath("path/to/folder")(如 srsgores 的提交示例所示)。
    • 如果你也有嵌套的点文件,那么你可以使用:this.templatePath('static/**/.*')
    • 对不起,为什么这么多代码?下面的答案更好。
    【解决方案2】:

    添加到@callumacrae 的答案:您还可以在copy()globOptions 中定义dot: true。这样/** glob 将包含个点文件。示例:

    this.fs.copy(
      this.templatePath('files/**'),
      this.destinationPath('client'),
      { globOptions: { dot: true } }
    );
    

    可以在node-globREADME 中找到可用的 Glob 选项列表。

    【讨论】:

    • Yeoman 文档真的很糟糕。您在哪里找到“globOptions”信息?我知道选项列表,但是没有关于基本对象名称“globOptions”的提示。
    • @julmot 我认为我最终在File System DocsFile Utilities 部分找到了它。它们链接到mem-fs-editor npm 包,该包为文件系统操作提供底层实现。在那个 README 中有几个提到 globOptions (然后再次导致 node-glob 包:-),它也从 API Docs for actions/file 链接)
    • 我也在努力处理点文件,但 fs.copyTpl 在内部使用 fs.copy。但显然 fs.copyTpl 不接受像 copy 这样的 globOptions 。为了克服这种情况,这里有一个解决方案:this.fs.copyTpl(glob.sync('files/**', {dot: true}), 'client', context)。
    • 勘误 - 必须指定整个模板路径:this.fs.copyTpl(glob.sync(this.templatePath('files/**'), {dot: true}), 'client' , 上下文)
    • @NicolasForney 对于copyTpl{globOptions} 似乎需要位于 5th 参数位置 (eg. here),正如 syntax 所说 #copyTpl(from, to, context[, templateOptions [, copyOptions ]]).
    【解决方案3】:

    这对我有用:globOptions 需要在 第五 参数中:

    this.fs.copyTpl(
      this.templatePath('sometemplate/**/*'),
      this.destinationPath(this.destinationRoot()),
      null,
      null,
      { globOptions: { dot: true } }
    );
    

    【讨论】:

    • 解释否决票?这是当前的工作版本。
    • 这样更好。喜欢这个。
    • 对于copyTpl,您需要使用fifth 参数和globOptions - 我刚刚更新了答案
    • 这应该被接受。对我有用,而被接受的则不行。另外它在 mem-fs 文档中
    • 首选,因为它通过显式选项更改copyTpl 函数的行为,而不是使用多个复制语句来混淆问题。
    【解决方案4】:

    如果您不想使用以点开头的模板,您可以使用dive 模块来实现相同的功能:

    var templatePath = this.templatePath('static-dotfiles');
    var destinationRoot = this.destinationRoot();
    dive(templatePath, {all: true}, function (err, file, stat) {
        if (err) throw err;
        this.fs.copy(
                file,
                (destinationRoot + path.sep + path.relative(templatePath, file))
                        .replace(path.sep + '_', path.sep + '.')
        );
    }.bind(this));
    

    其中static-dotfiles 是您的点文件模板文件夹的名称,其中_ 替换文件名中的.(例如:_gitignore)。

    别忘了在你的生成器顶部添加一个dive 的要求

    var dive = require('dive');
    

    当然,这也适用于copyTpl

    请注意,以_ 开头的所有路径子部分都将替换为.(例如:static-dotfiles/_config/_gitignore 将生成为.config/.gitignore

    【讨论】:

      猜你喜欢
      • 2011-12-15
      • 1970-01-01
      • 2015-07-18
      • 1970-01-01
      • 1970-01-01
      • 2016-09-23
      • 2014-12-11
      • 2013-05-08
      • 1970-01-01
      相关资源
      最近更新 更多