DEV Community

Sarah Hassan
Sarah Hassan

Posted on

3 1

Compile and Bundle Javascript es6 with Browserify + Babelify + Gulp

My story began while I was trying to use the tiny slider npm package in my project and I used Gulp as my task runner.

I got an error when I tried to import the tiny slider js file in the script file of my project.

// my gulp file
const { src, dest } = require('gulp');
// minify JS
const uglify = require('gulp-uglify');
// support JS for old browsers
const babel = require('gulp-babel');
// create source map files to JS
const sourcemaps = require('gulp-sourcemaps');
// rename files
const rename = require('gulp-rename');
const replace = require('gulp-replace');

const srcFiles = {
  jsPath: 'src/js/**/*.js'
};

const distFiles = {
  distJSPath: 'dist/js',
};

// my js task
function jsTask() {
  return (
    src([srcFiles.jsPath])
      // To load existing source maps
      // This will cause sourceMaps to use the previous sourcemap to create an ultimate sourcemap
      .pipe(gulpif(!production, sourcemaps.init({ loadMaps: true })))
      .pipe(
        gulpif(
          production,
          babel({
            presets: ['@babel/preset-env'],
          })
        )
      )
      .pipe(concat('all.js'))
      .pipe(gulpif(production, rename({ extname: '.min.js' })))
      .pipe(gulpif(production, uglify()))
      .pipe(gulpif(!production, sourcemaps.write('./')))
      .pipe(dest(distFiles.distJSPath))
  );
}
Enter fullscreen mode Exit fullscreen mode
// my script file
import { tns } from '../../node_modules/tiny-slider/src/tiny-slider';

Enter fullscreen mode Exit fullscreen mode

I got these errors:

Uncaught SyntaxError: Cannot use import statement outside a module

GET http://localhost:3000/node_modules/tiny-slider/src/tiny-slider net::ERR_ABORTED 404 (Not Found)

Let's start to explain what is the problem then we learn to solve it.

I used gulp-babel to compile ES6 to ES5. The problem is that require is not defined in the browser and in the ES5 syntax. So we need to search for another method to bundle all required js modules into one file.

We need this Browserify + Babelify combination to Compile & Bundle.

  • Browserify bundles js modules into one file to be used in the browser.

  • 'gulp-babel' didn't match with Browserify so, we will use Babelify instead to convert ES6 to ES5.

Steps are as the following:

npm i --save-dev browserify

npm i --save-dev  babelify

// has all packages needed for babelify to work
npm i --save-dev @babel/core

// to tap the specific preset to compile our script
npm i --save-dev @babel/preset-env


// grab source after bundling of browserify and check if entry source is still piped.
npm i --save-dev vinyl-source-stream

// to continue with using source map and uglify
npm i --save-dev vinyl-buffer

Enter fullscreen mode Exit fullscreen mode

In package.json, We need to specify the preset.

"devDependencies": {
    "@babel/core": "^7.13.8",
    "@babel/preset-env": "^7.9.6",
    "babel-core": "^6.26.3",
    "babel-preset-env": "^1.7.0",
    "babelify": "^8.0.0",
    "browser-sync": "^2.26.7",
    "browserify": "^17.0.0",
    .......
  },
  "babel": {
    "presets": [
      "@babel/preset-env"
    ]
  }
Enter fullscreen mode Exit fullscreen mode

In gulp file:

We can run js task for each group of files separately ex: a script for front-end and script for back-end.

// define entry for browserify
const jsSrc = 'module.js';
const jsFolder = 'src/js/';

// we can add a script for front-end and script for back-end and so on
const jsFiles = [jsSrc];
Enter fullscreen mode Exit fullscreen mode
const srcFiles = {
  jsPath: 'src/js/**/*.js',
  jsFiles: 'src/js/',
}
Enter fullscreen mode Exit fullscreen mode
const browserify = require('browserify');
const babelify = require('babelify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');

async function jsTask() {
  jsFiles.map(function (entry) {
    return (
      browserify({
        entries: [jsFolder + entry],
      })
        .transform(babelify, { presets: ['@babel/preset-env'] })
        .bundle()
        .pipe(source('all.js'))
        // To load existing source maps
        // This will cause sourceMaps to use the previous sourcemap to create an ultimate sourcemap
        .pipe(gulpif(production, rename({ extname: '.min.js' })))
        .pipe(buffer())
        .pipe(gulpif(!production, sourcemaps.init({ loadMaps: true })))
        // .pipe(concat('all.js'))
        .pipe(gulpif(production, uglify()))
        .pipe(gulpif(!production, sourcemaps.write('./')))
        .pipe(dest(distFiles.distJSPath))
    );
  });
}

Enter fullscreen mode Exit fullscreen mode

Resources that help me to solve the problem:

Hope this article helps, feel free to share it with your friends, any feedback will be appreciated :)

Thanks for reading!

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay