52 votes

Comment renommer des fichiers avec Grunt, en se basant sur le nom du dossier parent du fichier concerné ?

J'ai la structure suivante :

src/
    modules/
        module1/
            js/
                main.js
            scss/
                main.scss
            index.html
        module2/
            js/
                main.js
            scss/
                main.scss
            index.html

Je voudrais exécuter une tâche grunt pour les copier dans la structure suivante :

dev/
    js/
        module1.js
        module2.js
    css/
        module1.css
        module2.css
    module1.html
    module2.html

Existe-t-il un moyen de faire cela avec un plugin grunt existant ? Sinon, comment puis-je le faire ?

91voto

Gloopy Points 16421

Cela peut être fait en utilisant l'option grunt-contrib-copy plugin.

La principale chose à noter est que vous pouvez modifier la destination de manière programmatique en utilisant une fonction de renommage (qui prend en compte la destination et la source de chaque fichier).

Voici un échantillon (un peu fragile) Gruntfile.js qui devrait se copier sur la structure que vous souhaitez :

module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    copy: {
      main: {
        files: [
          {
            expand: true, 
            cwd: 'src/modules/', 
            src: ['**/*.js'], 
            dest: 'dev/js/', 
            rename: function(dest, src) {
              // use the source directory to create the file
              // example with your directory structure
              //   dest = 'dev/js/'
              //   src = 'module1/js/main.js'
              return dest + src.substring(0, src.indexOf('/')) + '.js';
            }
          },
          {
            expand: true, 
            cwd: 'src/modules/', 
            src: ['**/*.scss'], 
            dest: 'dev/css/', 
            rename: function(dest, src) {
              return dest + src.substring(0, src.indexOf('/')) + '.css';
            }
          },
          {
            expand: true, 
            cwd: 'src/modules/', 
            src: ['**/*.html'], 
            dest: 'dev/', 
            rename: function(dest, src) {
              return dest + src.substring(0, src.indexOf('/')) + '.html';
            }
          }
        ]
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-copy');

  // Default task(s).
  grunt.registerTask('default', ['copy']);
};

0 votes

J'ai eu la situation inverse : j'avais besoin de déplacer des fichiers vers différents dossiers à partir d'une source unique. Votre réponse a résolu mon problème, merci !

4 votes

Il est également très important de noter ici que si vous souhaitez ignorer certains fichiers lors du renommage, la valeur de retour correcte (par défaut) est return dest+'/'+src - qui fera en sorte que le fichier soit copié à l'emplacement par défaut.

0 votes

Donc, juste pour faire une simple opération en ligne de commande comme copier des fichiers, vous devez installer un plugin ? Est-ce que tu dois installer un plugin pour pratiquement toutes les opérations ?

6voto

tobek Points 184

Il n'y a pas besoin d'utiliser grunt-contrib-copy plus pour cela, vous pouvez désormais profiter de grunt.file.expandMapping qui a des options pour juste changer l'extension du fichier, ou pour définir une fonction qui retourne le nom du fichier de sortie.

Voici un exemple de files dans un jade tâche consistant à compiler les modèles .jade en fichiers .html :

files: [{
    expand: true, 
    src: "**/*.jade", 
    dest: "<%= distDir %>", 
    cwd: "<%= assetsDir %>/jade", 
    rename: function(dest, matchedSrcPath, options) {
        // return the destination path and filename:
        return (dest + matchedSrcPath).replace('.jade', '.html');
    }
}]

Il aurait été plus facile d'utiliser le ext: '.html' au lieu de l'option rename dans ce cas, mais j'utilise l'option rename ici pour que vous puissiez voir comment cela fonctionne.

Plus d'informations sur le ext y rename (et d'autres) dans l'onglet docs grunt.file . Quelques exemples supplémentaires aquí y aquí .

2voto

Paul0515 Points 444

Vous pouvez simplement utiliser les options : expand : true, aplatir : true

Il n'est pas nécessaire d'avoir des rappels de renommage personnalisés.

1voto

Klaus Zahiragic Points 11

Si vous voulez renommer les fichiers .coffee en .js ou autre, il suffit de l'adapter ;)

sudo npm install grunt-contrib-copy

copy: {
  rename: {
    files: [{
     expand: true,
     dot: true,
     cwd: './app/scripts',
     dest: './app/scripts/',
     src: [
       '**/*.coffee'
     ],
     rename: function(dest, src) {
       console.log(dest + src);
       return dest + src.replace('.coffee','.js');
     }
   }]
  }
},

0voto

codenamejames Points 325

Ce n'est pas exactement une réponse à votre question mais je suis venu ici pour chercher Dossiers de destination relatifs avec grunt alors... Voici comment j'ai résolu le problème

...
base: {
  files:
  [
    {
      expand: true,
      cwd: 'app/design/frontend/',
      src: ['**/Magento_Sales/email-src/*.html'],
      dest: '../../Magento_Sales/email/',
      rename: function(dest, src, expand) {
        src = path.parse(src)
        return path.join(expand.cwd, src.dir, dest, src.base);
      }
    },
  ],
}
...

Ce petit bout path.join(expand.cwd, src.dir, dest, src.base); Je crée juste le chemin dont j'ai besoin.

expand.cwd = app/design/frontend/

src.dir = <DYNAMIC_FOLDERS>/Magento_Sales/email-src/

dest = ../../Magento_Sales/email/

src.base = <FILE>.html

et tous ensemble = app/design/frontend/<COMPANY>/<MAIN-THEME>/Magento_Sales/email/<FILE>.html

et dans ma situation, il va maintenant compiler mes emails html dans des dossiers de destination relatifs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X