Скопируйте все файлы из каталога в другой с помощью Grunt.js copy

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/" }
Эван Хоббс
источник

Ответы:

150

flatten: trueВариант , так как в этом ответе может работать в некоторых случаях, но мне кажется , что более общее требование (как в моем случае) , чтобы скопировать папку и ее структуру вложенных папок, как есть, к dest. Кажется, что в большинстве случаев, если у вас есть подпапки, на них, вероятно, ссылаются именно так в коде. Ключом к этому является cwdопция, которая сохранит структуру папок относительно указанного рабочего каталога:

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
  }
}
Брайан Моэскау
источник
Спасибо - вы правы, этот ответ - это именно то, что я искал, когда задавал вопрос. Я научился справляться со сплющиванием, вызванным предыдущим ответом, но это раздражало.
Эван Хоббс
14
Я потерял на это больше часа ... Если пользуетесь cwdопциями, обязательно обращайтесь expand:true. Если не установить expand:true, cwd не будет работать должным образом.
ducin
2
Мне нужно было убедиться, что пути к каталогам заканчиваются на '/' и добавить, flatten: falseчтобы это работало.
Сэмюэл Россилль
**/* Это то, что я искал, я использовал ** спасибо, чувак.
Сэм
43

Эта задача будет поддерживать структуру папок, если вы укажете глобус файла. Вам нужен flattenвариант, который уберет структуру.

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

Остальные доступные варианты найдите в репозитории Github . Надеюсь это поможет.

Бен
источник
25

Я хотел бы добавить, что изменение формата глобуса в src изменит работу копии.

Как указано выше 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/а также каталоги, но не копирует содержимое этих каталогов в место назначения.

Кроме того, следующий с 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
+1 Есть ли соглашение о том, что должно означать количество звездочек, например, **всегда ли означает файлы и каталоги, а *просто файлы?
CodyBugstein
1
@Imray Из руководства bash : два соседних *s, используемые как один шаблон, будут соответствовать всем файлам и нулю или более каталогам и подкаталогам . Если за ними следует a /, два соседних *s будут соответствовать только каталогам и подкаталогам .
Хорхе Букаран,
1
**соответствует всему , тогда как **/ только каталогам и подкаталогам (не файлам).
Хорхе Букаран,
2

Пришлось использовать egdy вместо фигурных скобок для сегмента файлов (в Coffeescript) ...

copy: {
  files: [
    cwd: 'path/to/files'
    src: '**/*'
    dest: 'dist/files'
    expand: true
  ]
}
Сашлонг
источник
0

Если вы разрабатываете с помощью angular yeoman, то это лучший способ скопировать с grunt. expand: true требуется при использовании cwd. <% = yeoman.app%> - это просто маршрут приложения ('.').

 {
    expand: true,
     cwd: '<%= yeoman.app %>/data',
     dest: '<%= yeoman.dist %>/data',
     src: ['**']
    }
LearnToday
источник
Хотя этот фрагмент кода может решить вопрос, включение объяснения действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин вашего предложения кода. Также постарайтесь не загромождать свой код пояснительными комментариями, так как это снижает удобочитаемость как кода, так и пояснений!
Прощай, StackExchange