Search code examples
javascriptgulpbabeljsbrowserifyglslify

Gulp 3.9 + Browserify 11.2 to Gulp 4.0 + Browserify 17.0


I'm trying to update an old repository that is using Gulp 3.9.1 + browserify 11.2.0 to Gulp 4.0.2 + browserify 17.0.0. But those are not the only packages I'm using in this project.

This is the old package.json and the old code I'm trying to port to the new version:

package.json:

"devDependencies": {
    "babel": "^5.8.29",
    "babel-cli": "^6.22.2",
    "babel-preset-es2015": "^6.22.0",
    "babelify": "^6.4.0",
    "browserify": "^11.2.0",
    "core-js": "^1.2.3",
    "extend": "^3.0.0",
    "fs": "0.0.2",
    "glslify": "^2.3.1",
    "gsap": "^1.18.0",
    "gulp": "^3.9.1",
    "gulp-babel": "^5.2.1",
    "gulp-connect": "^2.2.0",
    "gulp-imagemin": "^3.1.1",
    "gulp-newer": "^1.3.0",
    "gulp-streamify": "^1.0.2",
    "gulp-uglify": "^1.5.3",
    "uglify-js": "^2.5.0",
    "vinyl-source-stream": "^1.1.0"
  }

Code:

const gulp = require('gulp')
const source = require('vinyl-source-stream')
const browserify = require('browserify')
const uglify = require('gulp-uglify')
const streamify = require('gulp-streamify')
const babelify = require("babelify");


gulp.task('build', function(){
  build();
});


function build() {
  browserify('src/index.js', {debug: true})
    .transform(babelify)
    .transform('glslify')
    .bundle()
    .on('error', function (err) {
      console.log('Error : ' + err.message);
    })
    .pipe(source('index.min.js'))
    .pipe(streamify(uglify()))
    .pipe(gulp.dest('public/js'));
}

The new package.json and the code I have until now, that I'm not sure if it is the correct implementation:

package.json:

"devDependencies": {
    "babel": "^6.23.0",
    "babel-cli": "^6.18.0",
    "babel-preset-env": "^1.7.0",
    "browserify": "^17.0.0",
    "core-js": "^1.2.3",
    "extend": "^3.0.0",
    "fs": "0.0.2",
    "glslify": "^7.1.1",
    "gsap": "^3.6.1",
    "gulp": "^4.0.2",
    "gulp-babel": "^8.0.0",
    "gulp-connect": "^2.2.0",
    "gulp-imagemin": "^7.1.0",
    "gulp-map": "^0.0.2",
    "gulp-newer": "^1.3.0",
    "gulp-streamify": "^1.0.2",
    "gulp-uglify": "^1.5.3",
    "uglify-js": "^2.5.0",
    "vinyl": "^0.5.3",
    "vinyl-source-stream": "^1.1.0"
  }

Code:

const gulp = require('gulp');
const browserify = require('browserify');
const babel = require('gulp-babel');
const glslify = require('glslify')
const source = require('vinyl-source-stream');
const streamify = require('gulp-streamify');
const uglify = require('gulp-uglify');
const map = require('gulp-map');
const Vinyl = require('vinyl');

gulp.task(build)

function build() {
  gulp.src(['./src/**/*.js', './src/**/*.jsx'])
    .pipe(browserify()
        .transform(babel({options: 'env'}))
        //.transform(glslify('./src/shaders/simple.vert')) // Not working
        //.transform(glslify('./src/shaders/water.frag')) // Not working
        .bundle().on('error', onError))
    .pipe(source('index.min.js'))
    .pipe(streamify(uglify()))
    .pipe(map(function(file) {
      // Explicitly convert to Vinyl object otherwise `gulp.dest()` will fail
      return new Vinyl(file); // But it stills failing
    }))
    .pipe(gulp.dest('./public/js/'));
}

function onError(err) {
  console.log('Error : ' + err.message);
}

I'm not sure if that is the correct way to migrate that code. I'm getting several issues from the different browserify modules, for example:

  • babel: that it seems to be fixed by changing from babelify to gulp-bable
  • glslify: that it seems to be deprecated, but I don't know which is the replace library

Also, and sorry for being repetitive, as I don't know how the migration should be, I'm getting this error after running the build command (gulp build):

[14:08:34] Using gulpfile ~/Documents/workspace/project/gulpfile.js
[14:08:34] Starting 'build'...
[14:08:34] 'build' errored after 109 ms
[14:08:34] TypeError: dest.write is not a function
    at DestroyableTransform.ondata (/Users/user/Documents/workspace/project/node_modules/readable-stream/lib/_stream_readable.js:619:20)
    at DestroyableTransform.emit (node:events:379:20)
    at DestroyableTransform.EventEmitter.emit (node:domain:532:15)
    at addChunk (/Users/user/Documents/workspace/project/node_modules/readable-stream/lib/_stream_readable.js:291:12)
    at readableAddChunk (/Users/user/Documents/workspace/project/node_modules/readable-stream/lib/_stream_readable.js:278:11)
    at DestroyableTransform.Readable.push (/Users/user/Documents/workspace/project/node_modules/readable-stream/lib/_stream_readable.js:245:10)
    at DestroyableTransform.Transform.push (/Users/user/Documents/workspace/project/node_modules/readable-stream/lib/_stream_transform.js:148:32)
    at Pumpify.onReadable (/Users/user/Documents/workspace/project/node_modules/to-through/index.js:25:14)
    at Pumpify.emit (node:events:379:20)
    at Pumpify.EventEmitter.emit (node:domain:532:15)

Sorry for the long explanation, hope someone can help me.


Solution

  • After a lot of researching, I found this blog which has the answer, or almost it has the links to the answer.

    One of the links took me to the most detailed tutorial about Gulp + Browserify + Babelify it could ever exist. Here the link. These are a serie of tutorial explaining how to implement Gulp from Scratch. If you don't want to see the videos and just want the code go here.

    This is my final gulpfile.js.

    And this is the answer to my question:

    My formerly build function in gulpfile.js (now called js)

    function js(done) {
      jsFiles.map( function( entry ) {
        return browserify({
          entries: [constants.jsSRC + entry] // constants.jsSRC == "./src/js/"
        })
          .transform( babelify, { presets: [ '@babel/preset-env' ] } )
          .transform('glslify')
          .bundle()
          .pipe(source( entry ) )
          .pipe(rename( {
            extname: '.min.js'
          }))
          .pipe(buffer() )
          .pipe(gulpif( options.has( 'production' ), stripDebug() ) )
          .pipe(sourcemaps.init({ loadMaps: true }) )
          .pipe(uglify())
          .pipe(sourcemaps.write( '.' ))
          .pipe(dest(constants.jsURL)) // constants.jsURL == "./dist/js/"
          .pipe(browserSync.stream());
      });
      done();
    }
    

    The task inside the same file gulpfile.js

    task("js", js);
    

    My package.json file.

    ...
    "devDependencies": {
        "@babel/core": "^7.13.14",
        "@babel/preset-env": "^7.13.12",
        "babelify": "^10.0.0",
        "browser-sync": "^2.26.14",
        "browserify": "^17.0.0",
        "browserify-shim": "^3.8.14",
        "core-js": "^1.2.3",
        "glslify": "^7.1.1",
        "gsap": "^3.6.1",
        "gulp": "^4.0.2",
        "gulp-connect": "^2.2.0",
        "gulp-if": "^3.0.0",
        "gulp-notify": "^3.2.0",
        "gulp-options": "^1.1.1",
        "gulp-plumber": "^1.2.1",
        "gulp-rename": "^2.0.0",
        "gulp-sourcemaps": "^3.0.0",
        "gulp-strip-debug": "^4.0.0",
        "gulp-uglify": "^1.5.3",
        "gulp-uglifycss": "^1.1.0",
        "vinyl-buffer": "^1.0.1",
        "vinyl-source-stream": "^2.0.0"
      },
      "babel": {
        "presets": [
          "@babel/preset-env"
        ]
      },
      "browserify": {
        "transform": [
          "browserify-shim"
        ]
      },
    ...
    

    Note that there is a babel section and a browserify section that are also needed.

    And to run that gulp task simply do:

    gulp js

    One last thing, the example of the tutorials (thank you Alessandro Castellani) and my final solution, are mostly the same and also contain the other tasks to process the css files, the fonts, the images, and the html file. All of those files are moved to a "production" folder, in my case called dist.