Search code examples
yeomangulpyeoman-generator

Gulp-useref is throwing error: "path must be a string"


I'm using a gulpfile.js generated by yeoman's gulp-webapp generator and modified slightly by me to fit my needs. For some reason I keep running into an issue when I try to run the build process(default task). The error is thrown during the 'html' task and most of the error references are in `node_modules\gulp-useref\index.js'.

Here is the error output:

stream.js:94
    throw er; //Unhandled stream in pipe.

TypeError: path must be a string
    at Object.fs.openSync (fs.js:427:18)
    at Object.fs.readFileSync (fs.js:284:15)
    at Transform.<anonymous> (C:\dev\project\node_modules\gulp-useref\index.js:54:44)
    at Array.forEach (native)
    at Transform.<anonymous> (C:\dev\project\node_modules\gulp-useref\index.js:50:31)
    at Array.forEach (native)
    at Transform.<anonymous> (C:\dev\project\node_modules\gulp-useref\index.js:41:36)
    at Array.forEach (native)
    at Transform._transform (C:\dev\project\node_modules\gulp-useref\index.js:38:23)
    at Transform._read (C:\dev\project\node_modules\gulp-useref\node_modules\through2\node_modules\readable-stream\lib\_stream_transform.js:184:10)
    at Transform._write (C:\dev\project\node_modules\gulp-useref\node_modules\through2\node_modules\readable-stream\lib\_stream_transform.js:172:12)

Here is the HTML task:

gulp.task('html', ['styles', 'scripts'], function () {
    var jsFilter = $.filter('**/*.js');
    var cssFilter = $.filter('**/*.css');

    return gulp.src(['app/**/*.html','app/**/*.php'])
        .pipe($.useref.assets())
        .pipe(jsFilter)
        .pipe($.uglify())
        .pipe(jsFilter.restore())
        .pipe(cssFilter)
        .pipe($.csso())
        .pipe(cssFilter.restore())
        .pipe($.useref.restore())
        .pipe($.useref())
        .pipe(gulp.dest('dist'))
        .pipe($.size());
});

Solution

  • Short answer: TypeError: path must be a string means that there is an issue with the link/script paths. useref can't find the the file or directory you are pointing it to.

    Long answer:
    There were two issues I ran into.

    1. The link/script paths needs to be relative to the gulpfile or have an alternate directory to search.
    <!-- build:css /styles/main.css -->
    <link href="app/styles/base.css">
    <link href="app/styles/article.css">
    <!-- endbuild -->
    

    OR

    <!-- build:css(app) /styles/main.css -->
    <link href="/styles/base.css">
    <link href="/styles/article.css">
    <!-- endbuild -->
    
    1. The yeoman gulpfile uses multiple alt directories which requires you to put them inside curly braces like this:
    <!-- build:css({.temp,app}) /styles/main.css --> Works
    

    But if you only have one alt directory and you leave it in the curly braces it will throw an error.

    <!-- build:css({app}) /styles/main.css --> TypeError: path must be a string
    

    This is because it is reading the path as C:\path\to\project\{app}\styles\style.css. This seems like odd behavior to me. I would think that it would iterate through the directories listed in the braces regardless of the length.