我正在使用load-grunt-config和grunt-prompt,我正在开发一个init任务,它会在两个文件夹之间复制一些php模板。
现在模板文件名是硬编码的,但我宁愿让grunt扫描正确的文件夹并动态提供文件名。
我已尝试使用grunt.file.expand,但我无法让它发挥作用。是否可以扫描文件夹并以grunt-prompt期望的格式返回文件名的数组(或对象,不知道你称之为什么)文件名?
// -------------------------------------
// Grunt prompt
// -------------------------------------
module.exports = {
// ----- Initialization prompt ----- //
init: {
options: {
questions: [{
// Set the authors name
config: 'init.author.name',
type: 'input',
message: 'What is your name?'
}, {
// Set the name of the project
config: 'init.project.name',
type: 'input',
message: 'What is the name of your project?'
}, {
// Select templates to be used
config: 'init.php.templates',
type: 'checkbox',
message: 'Which templates do you want to use?',
choices: [{
name: '404.php',
checked: false
}, {
name: 'archive.php',
checked: false
}, {
name: 'comments.php',
checked: false
}]
}]
}
}
};
顺便说一句,我找到了这个答案:https://stackoverflow.com/a/22270703/1694077,它与问题有关。但它没有详细说明如何专门解决这个问题。另外,我需要比文件名数组更具体的语法:
[{
name: '404.php'
}, {
name: 'archive.php'
}]
答案 0 :(得分:10)
这是一种使用Grunt的文件匹配功能来获取文件列表的方法。以下代码将在名为templates
的子目录中搜索模板。您只需将php
文件放在那里,脚本就会找到它。注意我省略了load-grunt-config
的使用,因为它不是获取文件列表的特定问题的一个因素。
关键是使用grunt.file.expand
来获取文件。
module.exports = function (grunt) {
// List all files in the templates directory.
var templates = grunt.file.expand({filter: "isFile", cwd: "templates"},
["*"]);
// Make actual choices out of them that grunt-prompt can use.
var choices = templates.map(function (t) {
return { name: t, checked: false};
});
grunt.initConfig({
prompt: {
init: {
options: {
questions: [{
// Set the authors name
config: 'init.author.name',
type: 'input',
message: 'What is your name?'
}, {
// Set the name of the project
config: 'init.project.name',
type: 'input',
message: 'What is the name of your project?'
}, {
// Select templates to be used
config: 'init.php.templates',
type: 'checkbox',
message: 'Which templates do you want to use?',
choices: choices
}]
}
}
}
});
grunt.task.loadNpmTasks("grunt-prompt");
grunt.registerTask("default", ["prompt"]);
};
你可以使用比"*"
更复杂的东西作为模式。例如,如果您要在其中包含其他类型的文件,则表示您不希望列出"*.php"
。我还使用isFile
作为filter
选项以避免列出目录。在列出文件之前,我使用cwd
将工作目录更改为templates
,这意味着返回的文件名不包括{{1在他们的名字。也可以这样做:
templates/
并获取名称中包含var templates = grunt.file.expand({filter: "isFile"}, ["templates/*"]);
目录的文件列表。
templates/
默认情况下,load-grunt-config
需要load-grunt-config
个文件(因为它调用package.json
)。这就是我用过的:
load-grunt-tasks
{
"dependencies": {
"load-grunt-config": "^0.8.0",
"grunt-prompt": "^1.1.0",
"grunt": "^0.4.4"
}
}
变为:
Gruntfile.js
然后在module.exports = function (grunt) {
grunt.registerTask("default", ["prompt"]);
require('load-grunt-config')(grunt);
};
中你需要这个:
grunt/prompt.js
答案 1 :(得分:2)
这是一个列出目录中文件的简短代码:
var fs = require("fs")
var files = [];
var list = function (path) {
fs.readdirSync(path).forEach(function (file) {
if(fs.lstatSync(path + '/' +file).isDirectory())
list(path + '/' +file);
else
files.push({name: file});
});
}
list(YOUR_PATH)
console.log(files)
在你的例子中:
var fs = require("fs")
var files = [];
var list = function (path) {
fs.readdirSync(path).forEach(function (file) {
if(fs.lstatSync(path + '/' +file).isDirectory())
list(path + '/' +file);
else
files.push({name: file});
});
}
list(YOUR_PATH)
module.exports = {
// ----- Initialization prompt ----- //
init: {
options: {
questions: [{
// Set the authors name
config: 'init.author.name',
type: 'input',
message: 'What is your name?'
}, {
// Set the name of the project
config: 'init.project.name',
type: 'input',
message: 'What is the name of your project?'
}, {
// Select templates to be used
config: 'init.php.templates',
type: 'checkbox',
message: 'Which templates do you want to use?',
choices: files
}]
}
}
};
答案 2 :(得分:0)
还有另一种方法可以使用与接受的答案中列出的不同的Grunt实用程序方法。值得一提的是因为它暴露了" glob"的选项对象。 Grunt内部使用的npm包。
有关您的Grunt版本使用的glob版本的详细信息,请参阅README.md(查看其package.json文件)。我首先查看了最新的glob,并对Grunt没有 grunt.file.globSync ()方法这一事实感到困惑。我最终意识到Grunt正在使用早期版本的glob,之后{ sync : true }从options对象中删除,并被 globSync ()函数我一直在寻找。
注意: grunt.file.glob ()不会将 src 数组作为 grunt.file.expand (),但是你可以使用大括号来有效地编码数组:
var options = { ... };
var results =
grunt.file.glob(
'{first/path/**/*,second/path/**/*}',
options
);
这是一个示例块,显示我如何在玉器处理中使用它,我似乎记得它由于某种原因本身不处理扩展块。选项:
请求空数组而不是数组
var filesObj = {}; var configObj = { 构建:{ 选项:{ 漂亮:是的, 数据:{ titleStr:'这是来自数据的标题' } }, files:filesObj } };
//从config获取源代码并构建输出目录根目录 var srcPrefix = 新的RegExp(' ^' + grunt.config.get(' sourceAssets')); var buildPrefix = grunt.config.get(' buildAssets');
//每个glob匹配调用一次以填充文件对象。 function addJadeFile(srcPath){ //通过denormlalizing path处理Windows上的glob输出。 srcPath = srcPath.replace(/ \ / g,' /'); //提取公共路径后缀并更改文件扩展名 var relPath = srcPath.replace(srcPrefix,' ..')。replace(/。jade $ /,' .html'); //前置目标路径前缀和属性 //到config对象的文件子对象。 filesObj [buildPath + relPath] = srcPath; }
grunt.file.glob( appConfig.source.client +' / ** / * .jade', {sync:true,stat:false strict:true,dot:false, nonull:false,nodir:true, nosort:true,nounique:true} ).forEach(addJadeFile);
return configObj;
P.S。 grunt.file.glob ()和 grunt.file.expand ()通常优于 fs 包中的遍历方法,因为glob保持遍历缓存。
如果您正在寻找可能是由之前的构建步骤创建的文件,而不是其他文件,那么了解 glob 的遍历缓存也是很好的任务首先遍历其创建位置并填充该缓存。我还没有碰到这个,但要注意这一点,以防你需要找到如何在这种极端情况下清除或忽略缓存。