使用Grunt.js复制将目录中的所有文件复制到另一个文件


91

我正在尝试将目录中的所有文件复制到另一个目录中,作为构建过程的一部分。它适合我明确指定的单个文件,但是当我尝试复制整个目录时,它会做一些奇怪的事情,例如复制完整的目录结构(或完全不复制)。这是我的GruntFile.js的相关部分:

copy: {
  myvoice: {
    files: [
      { src:"src/html/index.html", dest:"dist/myvoice/index.html" },
      { src:"src/html/css/style.css", dest:"dist/myvoice/css/style.css" },
      { src:"src/html/js/require.js", dest:"dist/myvoice/js/require.js" },
      { src:"build/myvoice/main.js", dest:"dist/myvoice/js/main.js" },
      { src:"src/html/css/fonts/*", dest:"dist/myvoice/css/fonts/" }
    ]
  }
},

具体来说,这是我无法开始的最后一行:

      { src:"src/html/css/fonts/*", dest:"dist/myvoice/css/fonts/" }

Answers:


149

此答案中flatten: true选项可能在某些情况下有效,但在我看来,更常见的要求(如我的情况)是将文件夹及其子文件夹结构原样复制到。似乎在大多数情况下,如果您有子文件夹,则可能在代码中以这种方式引用了它们。执行此操作的关键是该选项,该选项将保留相对于指定工作目录的文件夹结构:destcwd

copy: {
  files: {
    cwd: 'path/to/files',  // set working folder / root to copy
    src: '**/*',           // copy all files and subfolders
    dest: 'dist/files',    // destination folder
    expand: true           // required when using cwd
  }
}

谢谢-您说得对,这是我提出问题时一直在寻找的答案。我已经学会解决由先前答案引起的扁平化,但这很烦人。
Evan Hobbs 2014年

13
我为此已经迷失了一个多小时...如果您使用cwd选项,请务必转动expand:true。如果您未设置expand:true,则cwd将无法正常工作。
ducin 2014年

2
我必须确保目录路径以“ /”结尾并添加flatten: false才能使此工作正常。
塞缪尔·罗西耶

**/* 那就是我一直在寻找的东西,我正在使用**谢谢男人。
山姆

43

如果您指定文件全局,则此任务将维护文件夹结构。您想要的是flatten将删除结构的选项。

{
    expand: true,
    flatten: true,
    src: ['src/html/css/fonts/**'],
    dest: 'dist/myvoice/css/fonts/',
    filter: 'isFile'
}

Github存储库中找到其余可用选项。希望这可以帮助。


24

我想补充一点,在src中更改glob的格式将修改副本的工作方式。

如上面的bmoeskau所指出的,以下内容将复制其中的所有内容dist/并将其移至path/to/dir(如果目标已经存在,则将其覆盖)。

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '**'
  }
}

但是请注意:

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '*'
  }
}

只会复制文件里面dist/还有目录,但会不会这些目录中的内容复制到目标。

另外,以下with src: '*/*'复制目录中包含内容的目录dist/。即,仅dist/复制其中的文件。

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '*/*'
  }
}

最后,如上面一样,但src: '**/**'会复制内的文件dist/以及文件里面dist/子目录path/to/dir。因此,目的地内将没有文件夹。

copy: {
  files: {
    expand: true,
    dest: 'path/to/dir',
    cwd: 'dist/',
    src: '*/*',
    flatten: true,
    filter: 'isFile'
  }
}

4
很棒的解释!+1
myrocode

3
比github上的文档更好,我喜欢示例
wukong 2014年

+1关于星号的含义是否存在约定,例如,**总是表示文件和目录,而*仅表示文件?
CodyBugstein 2015年

1
@Imray从bash手册来看:*用作单个模式的两个相邻s将匹配所有文件以及零个或多个目录和子目录。如果后跟a /,则两个相邻的*s 匹配目录和子目录
豪尔赫·布卡拉

1
**匹配所有内容,而**/ 匹配目录和子目录(不匹配文件)。
豪尔赫·布卡拉

1

必须在文件段中使用egdy而不是花括号(在Coffeescript中)...

copy: {
  files: [
    cwd: 'path/to/files'
    src: '**/*'
    dest: 'dist/files'
    expand: true
  ]
}

0

如果您正在使用有角度的yeoman进行显影,那么这是使用grunt复制的更好方法。expand:使用cwd时需要true。<%= yeoman.app%>只是应用程序路由('。')。

 {
    expand: true,
     cwd: '<%= yeoman.app %>/data',
     dest: '<%= yeoman.dist %>/data',
     src: ['**']
    }

尽管此代码段可以解决问题,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。也请尽量不要在代码中添加解释性注释,因为这会降低代码和解释的可读性!
再见StackExchange
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.