从多个任务写入同一文件(Gulp,Node,gulp-json)

时间:2015-09-28 14:40:20

标签: node.js gulp

我刚刚开始使用Gulp(和NodeJs)......显然我遇到了我的第一堵墙。

这是: 我有一个使用主题的大型项目。每个主题都有自己的资产(scss和js文件)。这是我的gulpfile.js:

// < require block here (not included, to keep this short)

var themes = ["theme1", "theme2", "theme3"];

// Since I can have up to 20 different themes, I use the 'themes' array so I can create tasks dynamically, like this:
themes.forEach(function (theme) {
    gulp.task('css:' + theme, function () {
        setVersion([theme], 'css'); // write asset version into a json file
        gulp.src('../themes/frontend/' + theme + '/assets/css/style.scss')
            .pipe(sourcemaps.init())
            .pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
            .pipe(sourcemaps.write('./'))
            .pipe(gulp.dest('../themes/frontend/' + theme + '/assets/css'))
    });
});

// Of course, I need an "all" task to build all CSS in rare ocasions I need to do so:
gulp.task('css:all', ("css:" + themes.join(",css:")).split(","));
// ("css:" + themes.join(",css:")).split(",") => results in the needed ['css:theme1', 'css:theme2'] tasks array

// The same logic as above for JS files
// but added the use of gulp-concat and gulp-uglify
// Having scripts = { "theme1" : ['script1', 'script2'], "theme2": ['script1', 'script2'] }
// ...

// And "per theme" both "css and js"
themes.forEach(function (theme) {
    gulp.task('theme:' + theme, ['css:' + theme, 'js:' + theme]);
});


// Next I need to set versions for each asset
// I'm writing all the versions into a json file

assetsVersion = someRandomGeneratedNumber;
function setVersion(themes, assetType) {
/**
 * themes: array
 * assetType: 'all', 'css' or 'js'
 */
    var fs = require('fs'),
        path = require("path");
    var versionsFilePath = path.normalize(__dirname + '/../protected/config/theme/frontend/');
    var versionsFileName = '_assets-version.json';

    if (!fs.existsSync(versionsFilePath + versionsFileName)) {
        // Create file if it doesn't exist
        fs.writeFile(versionsFilePath + versionsFileName, "{}", function (err) {
            if (err) {
                return console.log(err);
            }
        });
    }

    gulp.src(versionsFilePath + versionsFileName)
        .pipe(jeditor(function (json) {
            themes.forEach(function(theme) {
                if ("undefined" == typeof (json[theme])) {
                    json[theme] = {};
                }

                if ('css' == assetType) {
                    json[theme]['css'] = assetsVersion;
                } else if ('js' == assetType) {
                    json[theme]['js'] = assetsVersion;
                } else {
                    json[theme] = {"css": assetsVersion, "js": assetsVersion};
                }
                if ("undefined" == typeof(json[theme]['css'])) {
                    // if we're missing the 'css' key (i.e. we've just created the json file), add that too
                    json[theme]['css'] = assetsVersion;
                }
                if ("undefined" == typeof(json[theme]['js'])) {
                    // if we're missing the 'js' key (i.e. we've just created the json file), add that too
                    json[theme]['js'] = assetsVersion;
                }
            });
            return json;
        }))
        .pipe(gulp.dest(versionsFilePath));
}

版本化json的资产应如下所示:

{
  "theme1": {
    "css": "20150928163236",
    "js": "20150928163236"
  },
  "theme2": {
    "css": "20150928163236",
    "js": "20150928163236"
  },
  "theme3": {
    "css": "20150928163236",
    "js": "20150928163236"
  }
}

运行'gulp css:theme#' - 效果很好...... 但是运行'gulp css:all' - 会让一个混乱的json 当然,这是因为所有css:theme#(或js:theme#)任务都运行异步,并且通常会有多个任务同时写入我的json文件。

我已经阅读了关于其他任务的任务,但这并不适合我的整个“动态任务”流程(或者我不知道如何适应它)。 我的意思是我不认为这个:

gulp.task('css:theme1', ['versioning'], function() {
  //do stuff after 'versioning' task is done.
});

会帮助我。那么如果它等待编写版本呢?多个任务仍然会同时写入文件。此外,为了实现这一点,我需要传递我也不知道该怎么做的参数......比如:

gulp.task('css:'+theme, ['versioning --theme ' + theme], function() {
      //do stuff after 'versioning' task is done.
    });

就像我可以在控制台中使它工作一样。我知道这不起作用,但如果能以某种方式将参数发送到任务名称中的任务,那么在某些情况下会非常有用。

runSequence(){... done();我真的不知道怎样才能让它在我的流程中发挥作用......

拜托,任何人......帮助新手...... 如何解决这个问题,同时:

  1. 动态创建任务;
  2. 为所有主题设置一个版本控制json文件。

0 个答案:

没有答案