我正在使用gulp来处理一个站点的页面,其中一些页面是php文件。问题是,在所有页面通过模板引擎运行之后,它们都有一个.html文件扩展名。我正在向文件中添加一个属性,该属性指定是否应该是html之外的文件,然后将文件重命名为匹配文件。但是,出于某种原因,gulp一直说我用来存储扩展的变量是undefined。
Gulpfile.js中相应的任务:
var gulp = require('gulp'),
gutil = require('gulp-util'),
lodash = require('lodash'),
data = require('gulp-data'),
filesize = require('gulp-filesize'),
frontMatter = require('gulp-front-matter'),
rename = require('gulp-rename'),
util = require('util');
gulp.task('metalsmith', function(){
var ext; //Variable to store file extension
return gulp.src(CONTENT_DIR)
.pipe(frontMatter()).on("data", function(file){
lodash.assign(file, file.frontMatter);
delete file.frontMatter;
})
.pipe(data(function(file){ //ext is defined here
if(typeof file.filetype === 'undefined'){
ext = {extname: '.html'};
}else{
ext = {extname: file.filetype};
}
}))
.pipe(tap(function(file){
console.log(ext); //when I print to the console, ext is defined and correct
}))
.pipe(rename(ext)) //ext is undefined
.pipe(gulp.dest(BUILD_DIR))
});当我使用Unsupported renaming parameter type supplied运行上面的it错误时。
此外,我尝试在与rename()相同的行中使用obj选项,ext只存储文件扩展名例如:.pipe(rename({extname: ext})),这会导致文件以未定义的扩展名添加(而不是phpfile.php,下面的md文件将被命名为phpfileundefined)。
yaml在phpfile.md
---
layout: php.hbt
filetype: ".php"
title: "php"
---package.json
"devDependencies": {
"gulp": "^3.9.1",
"gulp-data": "^1.2.1",
"gulp-filter": "^4.0.0",
"gulp-front-matter": "^1.3.0",
"gulp-rename": "^1.2.2",
"gulp-util": "^3.0.7",
"lodash": "^4.11.1"
}发布于 2016-09-08 06:25:52
您的问题是,在执行rename(ext)时,ext的值仍然是undefined,因为data(...)代码尚未运行。
Gulp插件的工作方式如下:
rename(ext)。.pipe()。.pipe()调用之后,流才会开始运行。因此,rename(ext)是一个函数调用,用于构造流本身的。只有在构建了流之后,流才能启动运行的。
但是,您只在流运行时设置ext的值。在构建流时,您需要ext 在之前的值。
在您的情况下,最简单的解决方案是在data(...)函数中手动重命名,而不是依赖于gulp-rename。您可以使用node.js内置的path模块(这是gulp-rename在引擎盖下使用的):
var path = require('path');
gulp.task('metalsmith', function(){
return gulp.src(CONTENT_DIR)
.pipe(frontMatter()).on("data", function(file){
lodash.assign(file, file.frontMatter);
delete file.frontMatter;
})
.pipe(data(function(file){
var ext;
if(typeof file.filetype === 'undefined'){
ext = '.html';
}else{
ext = file.filetype;
}
var parsedPath = path.parse(file.path);
file.path = path.join(parsedPath.dir, parsedPath.name + ext);
}))
.pipe(gulp.dest(BUILD_DIR))
});或者,您也可以像我在这个答案中建议的那样使用这个答案来回答类似的问题。但是,这在您的情况下并不是真正必要的,因为您已经在直接访问file对象了。
编辑:为了完整起见,这里有一个使用gulp-foreach的版本
var foreach = require('gulp-foreach');
gulp.task('metalsmith', function(){
return gulp.src(CONTENT_DIR)
.pipe(frontMatter()).on("data", function(file){
lodash.assign(file, file.frontMatter);
delete file.frontMatter;
})
.pipe(foreach(function(stream, file){
var ext;
if(typeof file.filetype === 'undefined'){
ext = {extname: '.html'};
}else{
ext = {extname: file.filetype};
}
return stream.pipe(rename(ext));
}))
.pipe(gulp.dest(BUILD_DIR))
});发布于 2016-09-08 07:18:03
@Sven的答案看上去就像要走的路,因为你希望其他站点都能提供一些通用的东西,而且您不能放弃gulp-front-matter管道。
只是为了完成你的代码:甚至
var ext = {extname: '.html'};
…
.pipe(rename(ext))
…不起作用:gulp-rename会说:“我不知道如何处理被传递的那种数据。”你需要做的是
var ext = '.html';
…
.pipe(rename({extname: ext})
…(或者ext = 'html'和{extname: '.' + ext},例如,如果"html“字符串是从其他地方提取而没有”“)
正如我们在chat中讨论的那样,我希望能发现您的php和html可以很容易地通过文件名或路径来区分。因为您所有的php文件都在/blog中,所以可以使用gulp-filter。也许最终它并不是这个场景的最佳解决方案,但是它是一个有用的工具,所以下面是它的样子:
var gulp = require('gulp'),
gutil = require('gulp-util'),
lodash = require('lodash'),
data = require('gulp-data'),
filesize = require('gulp-filesize'),
filter = require('gulp-filter'), // ADDED
frontMatter = require('gulp-front-matter'),
rename = require('gulp-rename'),
util = require('util');
gulp.task('metalsmith', function() {
const filterPHP = filter('blog/**/*', { restore: true });
const filterHTML = filter('!blog/**/*', { restore: true });
return gulp.src(CONTENT_DIR)
//---- if the only purpose of this particular gulp-front-matter pipe was to support the extension assignment, you could drop it
.pipe(frontMatter()).on("data", function(file) { //
lodash.assign(file, file.frontMatter); //
delete file.frontMatter; //
}) //
//---------
.pipe(filterPHP) // narrow down to just the files matched by filterPHP
.pipe(rename({ extname: '.php' }))
.pipe(filterPHP.restore) // widen back up to the full gulp.src
.pipe(filterHTML) // narrow down to just the files matched by filterHTML
.pipe(rename({ extname: '.html' }))
.pipe(filterHTML.restore) // widen back up
.pipe(gulp.dest(BUILD_DIR))
});https://stackoverflow.com/questions/39380427
复制相似问题