我正在使用 gulp 处理网站的页面,其中一些页面是 php 文件。问题是,所有页面都通过模板引擎运行后,它们具有 .html
文件扩展名。我向文件添加一个属性,指定它是否应该是 html 之外的文件,然后重命名该文件以匹配。然而,由于某种原因 gulp-rename 一直说我用来存储扩展的变量是未定义
。
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))
});
当我运行上面的代码时,它会出现错误,提供的重命名参数类型不受支持
。
我还尝试过将选项 obj 与 rename()
放在同一行,ext
仅存储文件扩展名,例如: .pipe(rename({extname: ext}))
这会导致文件添加 undefined 作为扩展名(而不是 phpfile.php
,下面的 md
文件将被命名为 phpfileundefined
)
phpfile.md 中的 yaml
---
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"
}
最佳答案
您的问题是,当您执行 rename(ext)
时,ext
的值仍然是 undefined
,因为您的 data(...)
代码尚未运行。
Gulp 插件的工作原理如下:
- 您调用插件函数并向其传递任何必要的参数。在您的情况下
rename(ext)
。 - 插件函数返回 duplex stream
- 您将该双工流传递给
.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))
});
或者,您也可以使用 gulp-foreach
正如我在this answer中建议的那样类似的问题。不过,在您的情况下,这并不是真正必要的,因为您已经直接在 data(...)
中访问 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))
});
关于javascript - 在一个管道中定义的 gulp var 在另一个管道中未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39380427/