【问题标题】:How to copy a file to every directory with Grunt?如何使用 Grunt 将文件复制到每个目录?
【发布时间】:2019-12-21 08:39:50
【问题描述】:

所以我正在构建一个 WP 插件,习惯上将空 index.html 文件放入每个文件夹中,以防止在主机允许的位置列出目录。我正在使用 grunt 构建部署就绪包,但我唯一缺少的是这些文件。我有很多文件夹,不想手动创建这些文件。我很高兴创建一个,并让 Grunt 将该文件复制到每个路径。但是怎么做呢?

【问题讨论】:

    标签: gruntjs


    【解决方案1】:

    不需要额外的 grunt 插件。使用 Grunt 的内置功能可以实现您的要求。

    考虑将custom Task 添加到您的Gruntfile.js,如下所示的createEmptyHtmlFiles

    Gruntfile.js

    module.exports = function(grunt) {
    
      grunt.initConfig({
        // ...
      });
    
      /**
       * Custom task to create empty `index.html` file in all folders.
       */
      grunt.registerTask('createEmptyHtmlFiles', function() {
    
        var fileName = 'index.html',
            contents = '';
    
        grunt.file.expand({ filter: 'isDirectory' }, 'dist/**/*')
            .forEach(function(dirPath) {
              var htmlFilePath = dirPath + '/' + fileName;
              grunt.file.write(htmlFilePath, contents, { encoding: 'utf8'})
            });
      });
    
      grunt.registerTask('default', ['createEmptyHtmlFiles']);
    
    };
    
    

    说明:

    1. 通常,您的Gruntfile.js 将包含grunt.initConfig({ ... }); 部分,该部分定义了您要执行的各种任务的配置。这部分应该按照您当前的配置保留。

    2. 注册了一个名为 createEmptyHtmlFiles 的自定义任务,它执行以下操作:

      • 将所需的文件名(即index.html)分配给fileName 变量,并将空字符串分配给contents 变量。

      • 接下来我们使用grunt.file.expand,我们将globbing pattern传递给它。在上面的示例中,提供的 glob 是 'dist/**/*'。 globbing 模式与filter: 'isDirectory' 选项相结合,本质上是获取dist 目录中所有文件夹的路径名。

        重要提示:您需要根据您的目录结构更改此 glob 模式。

      • 接下来我们使用 Array 的 forEach 方法迭代每个目录路径名。

      • forEach 循环的每一轮中,我们为htmlFilePath 变量分配一个新路径名,用于创建生成的index.html 文件。

      • 每个index.html 文件都是使用grunt.file.write 创建的。

    演示:

    1. 假设项目目录的结构如下:

      .
      ├── Gruntfile.js
      ├── dist
      │   ├── a
      │   │   ├── b
      │   │   │   └── 1.txt
      │   │   └── c
      │   │       └── 2.txt
      │   ├── d
      │   │   ├── 3.txt
      │   │   └── e
      │   │       └── 4.txt
      │   └── f
      │       └── g
      │           └── 5.txt
      ├── node_modules
      │   └── ...
      └── package.json
      
    2. 鉴于上面的Gruntfile.js,在运行$ grunt后会变成如下:

      .
      ├── Gruntfile.js
      ├── dist
      │   ├── a
      │   │   ├── b
      │   │   │   ├── 1.txt
      │   │   │   └── index.html         <-----
      │   │   ├── c
      │   │   │   ├── 2.txt
      │   │   │   └── index.html         <-----
      │   │   └── index.html             <-----
      │   ├── d
      │   │   ├── 3.txt
      │   │   ├── e
      │   │   │   ├── 4.txt
      │   │   │   └── index.html         <-----
      │   │   └── index.html             <-----
      │   └── f
      │       ├── g
      │       │   ├── 5.txt
      │       │   └── index.html         <-----
      │       └── index.html             <-----
      ├── node_modules
      │   └── ...
      └── package.json
      
      

      注意dist 目录中的每个文件夹现在都包含一个空的index.html 文件。

    3. 您可能需要排除在特定目录中创建index.html。在这种情况下,您可以通过传递给grunt.file.expand 方法的全局模式来否定特定目录。

      例如,假设我们在createEmptyHtmlFiles 任务中配置如下:

      ...
      grunt.file.expand({ filter: 'isDirectory' }, ['dist/**/*', '!dist/a/{b,c}'])
      ...
      

      注意:这一次我们传递一个包含两个 glob 模式的数组。第一个与前面的示例相同,但是第二个以 ! 开头,这将否定匹配。

      使用上述 glob 模式运行 $ grunt 将产生以下目录结构:

      .
      ├── Gruntfile.js
      ├── dist
      │   ├── a
      │   │   ├── b
      │   │   │   └── 1.txt              
      │   │   ├── c
      │   │   │   └── 2.txt              
      │   │   └── index.html             <-----
      │   ├── d
      │   │   ├── 3.txt
      │   │   ├── e
      │   │   │   ├── 4.txt
      │   │   │   └── index.html         <-----
      │   │   └── index.html             <-----
      │   └── f
      │       ├── g
      │       │   ├── 5.txt
      │       │   └── index.html         <-----
      │       └── index.html             <-----
      ├── node_modules
      │   └── ...
      └── package.json
      
      

      注意dist 目录中的每个文件夹(不包括文件夹bc)现在都包含一个空的index.html 文件。


    顺便说一句。当你说“空 index.html 文件”时,我是从字面上理解的。但是,如果您确实需要在每个文件中添加一些 html 标记,则可以将其分配给 contents 变量。例如:

    contents = '<!DOCTYPE html>\n<html>\n<head></head>\n<body></body>\n</html>';
    

    但我说“复制一个文件...”

    在这种情况下,您可以将自定义任务更改为以下内容:

    /**
      * Custom task to copy a source `index.html` file in all folders.
      */
     grunt.registerTask('copyFileToFolders', function() {
    
       var srcFilePath = './path/to/file/to/copy/index.html';
    
       grunt.file.expand({ filter: 'isDirectory' }, 'dist/**/*')
           .forEach(function(dirPath) {
             grunt.file.copy(srcFilePath, dirPath + '/index.html')
           });
     });
    

    注意事项:

    • 这利用grunt.file.copy 将源文件复制到所有文件夹。

    • 分配给srcFilePath 变量的路径名应替换为您要复制到所有文件夹的实际主index.html 文件的真实路径名。

    • 根据第一个示例,必须根据需要更改传递给 grunt.file.expand 的 glob 模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      • 1970-01-01
      • 2011-08-11
      相关资源
      最近更新 更多