在一个管道中定义的gulp var在另一个

时间:2016-09-07 23:27:22

标签: javascript node.js gulp gulp-rename

我正在使用gulp来处理网站的页面,其中一些页面是php文件。问题是,在通过模板引擎运行所有页面之后,它们具有.html文件扩展名。我正在为文件添加一个属性,指定它是否应该是除html之外的文件,然后重命名该文件以匹配。但是,由于某种原因,gulp-rename一直说我用来存储扩展名的变量是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运行上面的错误时。

此外,我已尝试将选项obj与rename()放在同一行,ext仅存储文件扩展名,例如:.pipe(rename({extname: ext})),导致文件未定义添加为扩展名(而不是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"
  }

2 个答案:

答案 0 :(得分:2)

您的问题是,当您执行rename(ext)ext的值仍为undefined,因为您的data(...)代码尚未运行。

Gulp插件的工作原理如下:

  1. 您调用插件函数并将其传递给任何必要的参数。在您的情况下rename(ext)
  2. 插件函数返回duplex stream
  3. 您将该双工流传递给.pipe()
  4. 只有在执行所有 .pipe()次调用后,您才会开始运行。
  5. 所以rename(ext)是一个函数调用,用于构造流本身。只有在构建了流之后,流才能开始运行

    但是,只有在流运行时才设置ext的值。在构建流时,您需要<{1}} 之前的值。

    在您的情况下,最简单的解决方案是在ext函数中手动重命名,而不是依赖data(...)。你可以使用node.js内置的path模块(这是gulp-rename使用的内容):

    gulp-rename

    另外,您也可以使用gulp-foreach我在this answer中提出的类似问题。但是,由于您已经在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对象,因此在您的情况下并不是必需的。

    编辑:为了完整起见,这是使用data(...)的版本:

    gulp-foreach

答案 1 :(得分:1)

@Sven的回答看起来像是要走的路,因为你希望能够推广其他网站的东西,因为你不能放弃graph = facebook.GraphAPI(access_token=access_token, version='2.5') profile = graph.get_object('me') posts = graph.get_connections(profile['id'], 'feed', limit=500) 管道。

只需完成您的代码:甚至

gulp-front-matter

不起作用:var ext = {extname: '.html'}; … .pipe(rename(ext)) … 会说“我不知道如何处理我传递的数据类型。”你需要做

gulp-rename

(或var ext = '.html'; … .pipe(rename({extname: ext}) … ext = 'html',例如,如果“html”字符串是从其他地方提取的,而且没有“。”

正如我们在聊天中讨论的那样,我希望找到你的php和html可以通过文件名或路径轻松区分。由于您的所有php文件都在{extname: '.' + ext},因此您可以使用gulp-filter。可能最终它不是这种情况的最佳解决方案,但它是一个有用的工具,了解所以这就是它的样子:

/blog