Pergunta

I've got a project with several files called setup.js in various sub folders in my /src folder. I'd like a gulp task to copy all the setup.js files to a /dist folder and preserve the sub folder structure. This part is easy.

The tricky part is I would also like to generate an index.html file beside each of the setup.js files in the \dist folder. The index.html file will be exactly the same for all of them except that it will need to reference the setup.js script using a path relative the the /dist folder. I know I could use some like gulp-template to dynamically render an html file but I don't know how I would pass the path the setup.js into it. And I don't know how to create an index.html for each setup.js.

So the resulting folder structure I'm going for would look something like this

/src
    template.html
    /blah1
        setup.js
    /blah2
        setup.js
/dist
    /blah1
        setup.js
        index.html
    /blah2
        setup.js
        index.html

Any idea on how I would do this?

Alternatively if someone can link me to some detailed docs/examples/tutorials on Gulp that might explain how to go about domething something like this I would greatly appreciate it. I haven't found many good articles that actually explain what's going on behind the scenes in Gulp and it's hard to find examples that go beyond the trivial src | uglify | concat | dest use case.

Thanks!

Foi útil?

Solução

I'm certainly no expert on gulp or node, so feel free to correct me/add to my answer...

I've tried to replicate a similar directory structure to what you describe here...

Uses gulp-tap and gulp-template

gulpfile.js

var gulp = require('gulp');
var template = require('gulp-template');
var tap = require('gulp-tap');

gulp.task('default', function () {
  gulp.src('./src/**/**.js', { base: './src' })
    // tap into the stream to get the current file and compile
    // the template according to that
    .pipe(tap(function (file) {
      gulp.src('./src/template.html')
        // compile the template using the current
        // file.path as the src attr in the template file
        .pipe(template({
          sourcefile: file.path
        }))
        // not sure about this line but I'm sure it could be better
        // splits the path on the / and then uses the second to last
        // item in the split array (which is the current directory, minus src plus dist)
        .pipe(gulp.dest('./dist/' + file.path.split('/')[file.path.split('/').length - 2]))
    }))
    // finally put the javascript files where they belong
    .pipe(gulp.dest('./dist'))
});

template.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="<%- sourcefile %>"></script>
</head>
<body>
</body>
</html>

Beginning Directory Structure

.
|____dist
|____gulpfile.js
|____src
| |____bar
| | |____setup.js
| |____foo
| | |____setup.js
| |____template.html

Final Directory Structure

.
|____dist
| |____bar
| | |____setup.js
| | |____template.html
| |____foo
| | |____setup.js
| | |____template.html
|____gulpfile.js
|____src
| |____bar
| | |____setup.js
| |____foo
| | |____setup.js
| |____template.html

Outras dicas

I didn't see @brbcoding's solution so I ended up coming up with this solution. I think I like his usage of tap more though:

var gulp = require('gulp');
var through = require('through2');
var fs = require('fs');
var path = require("path");
var lodash = require('lodash');


var replaceWithFile = function(filePath, outName) {
    return through.obj(function(file, encoding, callback) {
        var gulpContext = this;

        fs.readFile(filePath, 'utf8', function(err,data) {
            file.contents = new Buffer(data);
            file.path = path.join(path.dirname(file.path), outName);

            gulpContext.push(file);
            callback();
        });
    });
};

var template = function(data, options) {
    return through.obj(function(file, encoding, callback) {
        var resolvedData = {};

        for (key in data) {
            if(typeof data[key] === 'function') {
                resolvedData[key] = data[key](file);
            }
            else {
                resolvedData[key] = data[key];
            }
        }

        file.contents = new Buffer(lodash.template(file.contents.toString(), resolvedData, options));
        this.push(file);
        callback();
    });
};


gulp.task('test', function() {
    gulp.src('src/**/setup.js')
        .pipe(replaceWithFile('src/indexTemplate.html', 'index.html'))
        .pipe(template({
            challengeFolder: function(file) {
                return path.dirname(file.relative);
            }
        }))
        .pipe(gulp.dest('out1'));
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top