TypeError: $.useref.assets is not a function

2.5k Views Asked by At

I'm trying to build an Angular app using heroku, I keep getting this error whenever it reaches the html build state. It's my first time deploying to heroku but over the past few days I've kept getting different errors while the app runs without any problem on my local machine, and on a server.

TypeError: $.useref.assets is not a function
2017-04-18T14:36:18.895917+00:00 app[web.1]:     at Gulp.<anonymous> (/app/gulpfile.js:55:25)
2017-04-18T14:36:18.895918+00:00 app[web.1]:     at module.exports (/app/node_modules/orchestrator/lib/runTask.js:34:7)
2017-04-18T14:36:18.895919+00:00 app[web.1]:     at Gulp.Orchestrator._runTask (/app/node_modules/orchestrator/index.js:273:3)
2017-04-18T14:36:18.895920+00:00 app[web.1]:     at Gulp.Orchestrator._runStep (/app/node_modules/orchestrator/index.js:214:10)
2017-04-18T14:36:18.895920+00:00 app[web.1]:     at /app/node_modules/orchestrator/index.js:279:18
2017-04-18T14:36:18.895921+00:00 app[web.1]:     at finish (/app/node_modules/orchestrator/lib/runTask.js:21:8)
2017-04-18T14:36:18.895922+00:00 app[web.1]:     at /app/node_modules/orchestrator/lib/runTask.js:52:4
2017-04-18T14:36:18.895922+00:00 app[web.1]:     at f (/app/node_modules/end-of-stream/node_modules/once/once.js:17:25)
2017-04-18T14:36:18.895923+00:00 app[web.1]:     at DestroyableTransform.onend (/app/node_modules/end-of-stream/index.js:31:18)
2017-04-18T14:36:18.895924+00:00 app[web.1]:     at emitNone (events.js:91:20)
2017-04-18T14:36:18.895924+00:00 app[web.1]:     at DestroyableTransform.emit (events.js:185:7)
2017-04-18T14:36:18.895925+00:00 app[web.1]:     at /app/node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_readable.js:965:16
2017-04-18T14:36:18.895925+00:00 app[web.1]:     at _combinedTickCallback (internal/process/next_tick.js:73:7)
2017-04-18T14:36:18.895926+00:00 app[web.1]:     at process._tickCallback (internal/process/next_tick.js:104:9)

This is my gulpfile.js

/* jshint node:true */
'use strict';

var gulp = require('gulp');
var karma = require('karma').server;
var argv = require('yargs').argv;
var $ = require('gulp-load-plugins')();
var gulp = require('gulp'),
    useref = require('gulp-useref');

gulp.task('styles', function() {
  return gulp.src([
      'app/styles/less/app-green.less',
      'app/styles/less/app-blue.less',
      'app/styles/less/app-red.less',
      'app/styles/less/app-orange.less'
    ])
    .pipe($.plumber())
    .pipe($.less())
    .pipe($.autoprefixer({browsers: ['last 1 version']}))
    .pipe(gulp.dest('dist/styles'))
    .pipe(gulp.dest('app/styles'))
    .pipe(gulp.dest('.tmp/styles'));
});



gulp.task('html', function() {
  return gulp.src(options.src + '/index.html')
    .pipe(useref())
    .pipe(gulpif('*.js', uglify()))
    .pipe(gulp.dest(options.dist));
});''



gulp.task('jshint', function() {
  return gulp.src('app/scripts/**/*.js')
    .pipe($.jshint())
    //.pipe($.jshint.reporter('jshint-stylish'))
    //.pipe($.jshint.reporter('fail'));
});

gulp.task('jscs', function() {
  return gulp.src('app/scripts/**/*.js')
    .pipe($.jscs());
});

gulp.task('html', ['styles'], function() {
  var lazypipe = require('lazypipe');
  var cssChannel = lazypipe()
    .pipe($.csso)
    .pipe($.replace, 'bower_components/bootstrap/fonts', 'fonts');

 var assets = useref.assets({searchPath: '{.tmp,app}'});

  return gulp.src('app/**/*.html')
    //.pipe(assets)
    .pipe($.if('*.js', $.ngAnnotate()))
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', cssChannel()))
        .pipe(useref())
    pipe(assets.restore())
    .pipe($.useref())
    .pipe($.if('*.html', $.minifyHtml({conditionals: true, loose: true})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', function() {
  return gulp.src('app/images/**/*')
    // .pipe($.cache($.imagemin({
    //   progressive: true,
    //   interlaced: true
    // })))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('fonts', function() {
  return gulp.src(require('main-bower-files')().concat('app/styles/fonts/**/*')
    .concat('bower_components/bootstrap/fonts/*'))
    .pipe($.filter('**/*.{eot,svg,ttf,woff,woff2}'))
    .pipe($.flatten())
    .pipe(gulp.dest('dist/fonts'))
    .pipe(gulp.dest('app/fonts'))
    .pipe(gulp.dest('.tmp/fonts'));
});

gulp.task('extras', function() {
  return gulp.src([
    'app/*.*',
    '!app/*.html',
    'node_modules/apache-server-configs/dist/.htaccess'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});

gulp.task('clean', require('del').bind(null, ['.tmp', 'dist']));

gulp.task('connect', ['styles'], function() {
  var serveStatic = require('serve-static');
  var serveIndex = require('serve-index');
  var app = require('connect')()
    .use(require('connect-livereload')({port: 35729}))
    .use(serveStatic('.tmp'))
    .use(serveStatic('app'))
    // paths to bower_components should be relative to the current file
    // e.g. in app/index.html you should use ../bower_components
    .use('/bower_components', serveStatic('bower_components'))
    .use(serveIndex('app'));

  require('http').createServer(app)
    .listen(9000)
    .on('listening', function() {
      console.log('Started connect web server on http://localhost:9000');
    });
});

gulp.task('serve', ['wiredep', 'connect', 'fonts', 'watch'], function() {
  if (argv.open) {
    require('opn')('http://localhost:9000');
  }
});

gulp.task('test', function(done) {
  karma.start({
    configFile: __dirname + '/test/karma.conf.js',
    singleRun: true
  }, done);
});

// inject bower components
gulp.task('wiredep', function() {
  var wiredep = require('wiredep').stream;
  var exclude = [
    'bootstrap',
    'jquery',
    'es5-shim',
    'json3',
    'angular-scenario'
  ];

  gulp.src('app/styles/*.less')
    .pipe(wiredep())
    .pipe(gulp.dest('app/styles'));

  gulp.src('app/*.html')
    .pipe(wiredep({exclude: exclude}))
    .pipe(gulp.dest('app'));

  gulp.src('test/*.js')
    .pipe(wiredep({exclude: exclude, devDependencies: true}))
    .pipe(gulp.dest('test'));
});

gulp.task('watch', ['connect'], function() {
  $.livereload.listen();

  // watch for changes
  gulp.watch([
    'app/**/*.html',
    '.tmp/styles/**/*.css',
    'app/scripts/**/*.js',
    'app/images/**/*'
  ]).on('change', $.livereload.changed);

  gulp.watch('app/styles/**/*.less', ['styles']);
  gulp.watch('bower.json', ['wiredep']);
});

gulp.task('builddist', ['jshint', 'html', 'images', 'fonts', 'extras', 'styles'],
  function() {
  return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
});

gulp.task('build', ['clean'], function() {
  gulp.start('builddist');
});

gulp.task('docs', [], function() {
  return gulp.src('app/scripts/**/**')
    .pipe($.ngdocs.process())
    .pipe(gulp.dest('./docs'));
});
2

There are 2 best solutions below

3
Emile Bergeron On

This was written before OP changed his question to include the content of this answer.


The error tells you that $.useref.assets is not a function and it comes from the following line:

var assets = $.useref.assets({searchPath: '{.tmp,app}'});

Since you're already loading the gulp-useref plugin into a local variable

var useref = require('gulp-useref'),

You don't need to use the $ of gulp-load-plugins.

After that, the first thing you see in the readme of gulp-useref:

What's new in 3.0?

Changes under the hood have made the code more efficient and simplified the API. Since the API has changed, please observe the usage examples below.

If you get errors like

TypeError: useref.assets is not a function

or

TypeError: $.useref.assets is not a function

please read the Migration Notes below.

And below is the Migration from v2 API:

For a simple configuration, you can replace this V2 code:

var gulp = require('gulp'),
    useref = require('gulp-useref');

gulp.task('default', function () {
    var assets = useref.assets();

    return gulp.src('app/*.html')
        .pipe(assets)
        .pipe(assets.restore())
        .pipe(useref())
        .pipe(gulp.dest('dist'));
});

with this V3 code:

var gulp = require('gulp'),
    useref = require('gulp-useref');

gulp.task('default', function () {
    return gulp.src('app/*.html')
        .pipe(useref())
        .pipe(gulp.dest('dist')); 
});

You do not need to call useref.assets(...) anymore. Just pipe to useref() like in the V3 example.

0
Hong Yi On

replace you codes

var assets = useref.assets({searchPath: '{.tmp,app}'});
  return gulp.src('app/**/*.html')
    //.pipe(assets)
   .pipe($.if('*.js', $.ngAnnotate()))
   .pipe($.if('*.js', $.uglify()))
   .pipe($.if('*.css', cssChannel()))
   .pipe(useref())
   pipe(assets.restore()) //you missed a dot point here
   .pipe($.useref())
   .pipe($.if('*.html', $.minifyHtml({conditionals: true, loose: true})))
   .pipe(gulp.dest('dist'));
});

with something like:

return gulp
.src('app/**/*.html')
    .pipe($.useref())
    .pipe($.if('*.js', $.ngAnnotate()))
    .pipe($.if('*.js', $.uglify())) //to uglify js files
    .pipe($.if('*.css', $.csso())) //to uglify css files
    .pipe(gulp.dest('dist'));

or

var jsAppFilter = $.filter('**/app.js', { restore: true });

return gulp
    .src(config.index)        
    .pipe($.useref())
    .pipe(jsAppFilter) //only add annotations to your custom js files
    .pipe($.ngAnnotate())
    .pipe(jsAppFilter.restore)
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', $.csso()))
    .pipe(gulp.dest('./build'));