Vadorequest
Vadorequest

Reputation: 17997

Gulp task that write all filenames in another file

I'm getting started with Gulp and I want to write a task that does the following:

  1. Browse a directory and sub directories to find files using the pattern *.doc.cjsx
  2. Write all the file path found in another file named components.coffee

I'm using gulp-inject. I know that I eventually will need to write to a proper JS file instead of a coffee file (to avoid track a content-generated file on git)

Here is my task: (coffee)

gulp.task 'react-components', ->
    gulp.src('src/apis/front/commons/components.coffee')
        .pipe(plumber())
        .pipe(
            inject(
                gulp.src(
                    [
                        "src/apis/front/commons/button/*.doc.cjsx"
                    ],
                    read: false
                ),
                {
                    ignorePath: 'src/apis/front/commons/'
                    addPrefix: 'require ./' # I need to make the path relative at runtime, I haven't tested this yet because it doesn't generate any output, yet.
                    starttag: '# inject:components'
                }
            )
        )
        .pipe(debug({minimal: false}))
        .pipe(gulp.dest('src/apis/front/commons/'))

Here is the components.coffee file:

module.exports = [
    require "./button/button.doc.js" # This should be auto-generated inside the starting tag and closing tag.

    # inject:components
    # endinject
]

Here is the output when I run the task:

[10:15:24] Using gulpfile ~/service/www/hapi-rho/gulpfile.coffee
[10:15:24] Starting 'react-components'...
[10:15:24] gulp-inject 1 files into components.coffee.
[10:15:24] gulp-debug: 
cwd:   ~/service/www/hapi-rho
base:  ~/service/www/hapi-rho/src/apis/front/commons/
path:  ~/service/www/hapi-rho/src/apis/front/commons/components.coffee

[10:15:24] gulp-debug: 1 item
[10:15:24] Finished 'react-components' after 31 ms

It seems to be working fine because gulp says that it injected 1 file into components.coffee, if I add another *.doc.cjsx file in the folder then it says it injected two files.

But the content of components.coffee isn't changed, so I'm obviously missing something. Either the starttag isn't found, or it's something else.


Solution: Here is my solution, based on Sven's answer. The paths have changed since and I'm generating an object instead of an array now, but the principle is the same.

gulp.task 'react-components', ->
    gulp.src('src/apis/front/components/components.coffee')
    .pipe(plumber())
    .pipe(
        inject(
            gulp.src('src/apis/front/components/**/*.doc.cjsx', read: false),
            ignorePath: 'src/apis/front/components/'
            starttag: '# inject:components'
            endtag: '# endinject'
            transform: (filepath, file, i, length) ->
                filename = filepath.replace(/cjsx$/, 'js')
                suffix = if i + 1 < length then ',' else ''
                '"' + filename + '": require ".' + filename + '"'# + suffix
        )
    )
    .pipe(debug(minimal: false))
    .pipe gulp.dest('src/apis/front/components/')

Upvotes: 1

Views: 729

Answers (1)

Sven Schoenung
Sven Schoenung

Reputation: 30564

First off, you forgot to specify your endtag.

Secondly, you need to provide a transform option. If you don't explicitly provide one the default transform function will be used, which uses the target file type (coffee in your case) and the source file type (cjsx in your case) to choose a sensible transformation for you.

Unfortunately there is no default transformation for the coffee/cjsx pairing available. That means you have to write one yourself.

Here's what that might look like in your case (regular JavaScript, since I'm not well-versed in CoffeeScript):

gulp.task('react-components', function()  {
  return gulp.src('src/apis/front/commons/components.coffee')
    .pipe(plumber())
    .pipe(inject(
       gulp.src("src/apis/front/commons/button/*.doc.cjsx", {read:false}),
       {
         ignorePath: 'src/apis/front/commons/',
         starttag: '# inject:components',
         endtag: '# endinject',
         transform: function (filepath, file, i, length) {
           return 'require ".' + filepath.replace(/cjsx$/, "js") +
                  '"' + (i + 1 < length ? ',' : '');
         }
       }
     ))
    .pipe(debug({minimal: false}))
    .pipe(gulp.dest('src/apis/front/commons/'));
});

Upvotes: 1

Related Questions