如何使用 Grunt 将文件复制到每个目录?
How to copy a file to every directory with Grunt?
所以我正在构建一个 WP 插件,通常将空 index.html 文件放入每个文件夹中,以防止在主机允许的情况下列出目录。我正在使用 grunt 构建部署就绪包,但我唯一缺少的是这些文件。我有很多文件夹,不想手动创建这些文件。我很乐意创建一个,并让 Grunt 将该文件复制到每个路径。但是怎么办?
不需要额外的 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']);
};
解释:
通常,您的 Gruntfile.js
将包含 grunt.initConfig({ ... });
部分,该部分定义了您要执行的各种任务的配置。这部分应该保持你当前的配置。
已注册名为 createEmptyHtmlFiles
的自定义任务,它执行以下操作:
将所需的文件名,即 index.html
分配给 fileName
变量,并将空字符串分配给 contents
变量。
接下来我们利用grunt.file.expand
to which we pass a globbing pattern。在上面的示例中,提供的 glob 是 'dist/**/*'
。 globbing 模式结合 filter: 'isDirectory'
选项实质上获得了 dist
目录中所有文件夹的路径名。
重要提示:您需要根据您的目录结构更改此 glob 模式。
接下来我们使用 Array 的 forEach
方法迭代每个目录路径名。
在 forEach
循环的每一轮中,我们为 htmlFilePath
变量分配一个新路径名,用于创建结果 index.html
文件的位置。
每个 index.html
文件都是使用 grunt.file.write
创建的。
演示:
假设项目目录结构如下:
.
├── Gruntfile.js
├── dist
│ ├── a
│ │ ├── b
│ │ │ └── 1.txt
│ │ └── c
│ │ └── 2.txt
│ ├── d
│ │ ├── 3.txt
│ │ └── e
│ │ └── 4.txt
│ └── f
│ └── g
│ └── 5.txt
├── node_modules
│ └── ...
└── package.json
鉴于上面的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
文件。
您可能需要排除 index.html
在特定目录中创建。在这种情况下,我们可以通过传递给 grunt.file.expand
方法的 glob 模式来否定特定目录。
例如,假设我们在 createEmptyHtmlFiles
任务中配置如下:
...
grunt.file.expand({ filter: 'isDirectory' }, ['dist/**/*', '!dist/a/{b,c}'])
...
注意: 这次我们传递一个包含两个 glob 模式的数组。第一个与前面的示例相同,但是第二个以 !
开头,这将使匹配无效。
运行 $ grunt
使用上述 glob 模式将导致以下目录结构:
.
├── 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
目录中的每个文件夹,不包括文件夹 b
和 c
,现在包括一个空的 index.html
文件.
btw. 当你说 "empty index.html files" 时,我是按字面意思理解的。但是,如果您确实需要在每个文件中添加一些 html 标记,您可以将其分配给 contents
变量。例如:
contents = '<!DOCTYPE html>\n<html>\n<head></head>\n<body></body>\n</html>';
可是我说"copy a file ..."
在这种情况下,您可以将自定义任务更改为以下内容:
/**
* 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 模式。
所以我正在构建一个 WP 插件,通常将空 index.html 文件放入每个文件夹中,以防止在主机允许的情况下列出目录。我正在使用 grunt 构建部署就绪包,但我唯一缺少的是这些文件。我有很多文件夹,不想手动创建这些文件。我很乐意创建一个,并让 Grunt 将该文件复制到每个路径。但是怎么办?
不需要额外的 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']);
};
解释:
通常,您的
Gruntfile.js
将包含grunt.initConfig({ ... });
部分,该部分定义了您要执行的各种任务的配置。这部分应该保持你当前的配置。已注册名为
createEmptyHtmlFiles
的自定义任务,它执行以下操作:将所需的文件名,即
index.html
分配给fileName
变量,并将空字符串分配给contents
变量。接下来我们利用
grunt.file.expand
to which we pass a globbing pattern。在上面的示例中,提供的 glob 是'dist/**/*'
。 globbing 模式结合filter: 'isDirectory'
选项实质上获得了dist
目录中所有文件夹的路径名。重要提示:您需要根据您的目录结构更改此 glob 模式。
接下来我们使用 Array 的
forEach
方法迭代每个目录路径名。在
forEach
循环的每一轮中,我们为htmlFilePath
变量分配一个新路径名,用于创建结果index.html
文件的位置。每个
index.html
文件都是使用grunt.file.write
创建的。
演示:
假设项目目录结构如下:
. ├── Gruntfile.js ├── dist │ ├── a │ │ ├── b │ │ │ └── 1.txt │ │ └── c │ │ └── 2.txt │ ├── d │ │ ├── 3.txt │ │ └── e │ │ └── 4.txt │ └── f │ └── g │ └── 5.txt ├── node_modules │ └── ... └── package.json
鉴于上面的
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
文件。您可能需要排除
index.html
在特定目录中创建。在这种情况下,我们可以通过传递给grunt.file.expand
方法的 glob 模式来否定特定目录。例如,假设我们在
createEmptyHtmlFiles
任务中配置如下:... grunt.file.expand({ filter: 'isDirectory' }, ['dist/**/*', '!dist/a/{b,c}']) ...
注意: 这次我们传递一个包含两个 glob 模式的数组。第一个与前面的示例相同,但是第二个以
!
开头,这将使匹配无效。运行
$ grunt
使用上述 glob 模式将导致以下目录结构:. ├── 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
目录中的每个文件夹,不包括文件夹b
和c
,现在包括一个空的index.html
文件.
btw. 当你说 "empty index.html files" 时,我是按字面意思理解的。但是,如果您确实需要在每个文件中添加一些 html 标记,您可以将其分配给 contents
变量。例如:
contents = '<!DOCTYPE html>\n<html>\n<head></head>\n<body></body>\n</html>';
可是我说"copy a file ..."
在这种情况下,您可以将自定义任务更改为以下内容:
/**
* 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 模式。