【问题标题】:Dynamic file mapping with relative destination具有相对目标的动态文件映射
【发布时间】:2013-05-16 03:33:21
【问题描述】:

这是一个关于使用 Grunt.js 进行动态文件映射的通用问题,但出于示例目的,我将尝试在项目中构建 coffee 文件动态结构:

在这里,我可以有多个(动态)具有不同深度的目标文件夹。查找coffee 文件仍然很容易,它会随时匹配**/coffee/*.coffee

我想要实现的是,使 dest 属性 relative 与匹配的咖啡文件:

  • 找到**/coffee/*.coffee
  • 编译成../js/*.js

而不是使其相对于项目文件夹(Gruntfile)。

coffee: {
    compile: {
        files: [
            {
              expand: true,
              src: ['**/coffee/*.coffee'],
              dest: '../js/', // This won't work ! But I wish it could :)
              ext: '.js'
            }
        ]
    }
}

您将如何实现这一目标?

【问题讨论】:

    标签: javascript coffeescript gruntjs


    【解决方案1】:

    我认为这不是一个好主意。听起来每个目标都应该是自己的存储库。即使我们忽略这一点,您也会遇到其他问题,例如难以区分目标文件夹和非目标文件夹。例如,您当前的模式可能会匹配 node_modules/ 目录中的 CoffeeScript 文件。

    我还觉得奇怪的是您的目标具有不同的文件夹结构(即 coffee/js/ 不在同一级别)。同样,听起来它们是不同的项目,应该有自己的存储库。

    话虽如此,如果你真的、真的必须那样做,有几种方法可以做到这一点。

    首先,“正常”的做法是手动指定多个目标。我将在这里使用Gruntfile.coffee 语法:

    coffee:
      target1:
        expand: true
        cwd: 'target1/coffee'
        src: '**/*.coffee'
        dest: 'target1/js'
        ext: '.js'
      targetX:
        expand: true
        cwd: 'targetX/some-folder/coffee'
        src: '**/*.coffee'
        dest: 'targetX/some-folder/js'
        ext: '.js'
    

    但是,如果您确定需要动态目标,并且不介意将不需要的文件夹列入黑名单,不妨尝试以下方法:

    coffee: do ->
      targets = {}
      for target in grunt.file.expand '**/coffee', '!node_modules/**'
        targets[target.split('/', 1)[0]] =
          expand: true
          cwd: target
          src: '**/*.coffee'
          dest: target + '/../js'
          ext: '.js'
      targets
    

    这与之前的 sn-p 基本相同,但增加了一些不确定性。您可以通过让targets/ 文件夹包含所有目标并使用targets/**/coffee 作为模式来摆脱黑名单。

    您也可以使用grunt.file.expandMapping:

    coffee:
      compile:
        files: grunt.file.expandMapping ['**/coffee/**/*.coffee', '!node_modules/**'], '',
          expand: true
          ext: '.js'
          rename: (base, src) ->
            src.replace '/coffee/', '/js/'
    

    虽然它可能看起来有点简单(而且丑陋),但它是最慢的选择并且感觉最错误。

    所以那里。这是可能的,但很可能不是您真正想要的。

    【讨论】:

    • 感谢您的明确回答。我完全同意你的观点,这是我们在处理多设备项目时的工作流程非常具体的案例。我们可以使用多个 Gruntfiles 来实现,但我们倾向于按项目拥有一个文件。 Codekit 可以选择替换路径组件的实例。这就是我试图重现的内容。我自己刚刚找到了最后一个解决方案,但最后,我想我会听从您的建议并手动指定目标。我也很想知道社区将如何实现这一目标。非常感谢@simo-kinnunen!
    • 我想我遗漏了一些明显的东西。你能解释为什么最后一种方法更慢吗?它肯定会在它的 globbing 中执行与之前相同数量的目录搜索吗?
    • 没错,第二个示例确实好不到哪里去,因为它在任何级别上查找“咖啡”,但是通过执行更严格的目录布局可以相对容易地改进这一点。虽然我仍然建议 OP 拆分他的 repo 并完全避免这个问题,但我可以也许看到自己使用第二种方法和更便宜的 glob 模式来创建一般的动态目标。但最后一个,根本没有。
    • 第二种方法可以让watch只触发特定的子文件夹,当有多个独立的子文件夹时,这将是一个巨大的节省。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 2022-11-09
    • 2021-01-04
    • 2012-04-24
    • 2019-02-26
    • 1970-01-01
    相关资源
    最近更新 更多