Bundling hyperhtml-element with browserify/babelify not working

104 views Asked by At

Maybe I'm doing something very wrong but I can't seem to get hyperhtml-element to play nice with babel.

If I import HyperHTMLElement from 'hyperhtml-element' then I get raw es6 in my bundle. If I import HyperHTMLElement from 'hyperhtml-element/es5' then I get Uncaught TypeError: Super expression must either be null or a function

I'm using @babel/preset-env

I've been using hyperhtml-element in an Electron app for the last couple month and love it. But now that I'm trying to use it on the web I can't even figure out how to bundle it. I've been trying to make this work for almost a month now.

This is my gulpfile.js

var gulp = require('gulp')

var browserify = require('browserify')
var watchify = require('watchify')
var babelify = require('babelify')

var source = require('vinyl-source-stream')
var buffer = require('vinyl-buffer')
var merge = require('utils-merge')

var rename = require('gulp-rename')
var uglify = require('gulp-uglify')
var sourcemaps = require('gulp-sourcemaps')


/* nicer browserify errors */
var gutil = require('gulp-util')
var chalk = require('chalk')

function map_error(err) {
  if (err.fileName) {
    // regular error
    gutil.log(chalk.red(err.name)
      + ': '
      + chalk.yellow(err.fileName.replace(__dirname + '/src/js/', ''))
      + ': '
      + 'Line '
      + chalk.magenta(err.lineNumber)
      + ' & '
      + 'Column '
      + chalk.magenta(err.columnNumber || err.column)
      + ': '
      + chalk.blue(err.description))
  } else {
    // browserify error..
    gutil.log(chalk.red(err.name)
      + ': '
      + chalk.yellow(err.message))
  }

  this.emit('end');
}

gulp.task('watchify', function () {
  var args = merge(watchify.args, { debug: true })
  var bundler = watchify(browserify('./src/js/index.js', args)).transform(babelify, { /* opts */ })
  bundle_js(bundler)

  bundler.on('update', function () {
    bundle_js(bundler)
  })
})

function bundle_js(bundler) {
  return bundler.bundle()
    .on('error', map_error)
    .pipe(source('index.js'))
    .pipe(buffer())
    .pipe(gulp.dest('build/static/js'))
    .pipe(rename('index.min.js'))
    .pipe(sourcemaps.init({ loadMaps: true }))
      // capture sourcemaps from transforms
      .pipe(uglify())
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('build/static/js/'))
}

// Without watchify
gulp.task('browserify', function () {
  var bundler = browserify('./src/js/index.js', { debug: true }).transform(babelify, {/* options */ })

  return bundle_js(bundler)
})

// Without sourcemaps
gulp.task('browserify-production', function () {
  var bundler = browserify('./src/js/index.js').transform(babelify, {presets: ["@babel/preset-env"]})

  return bundler.bundle()
    .on('error', map_error)
    .pipe(source('index.js'))
    .pipe(buffer())
    .pipe(rename('index.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('build/static/js/'))
})

Any help you can provide will be greatly appreciated

1

There are 1 answers

5
Andrea Giammarchi On BEST ANSWER

If I import HyperHTMLElement from 'hyperhtml-element' then I get raw es6 in my bundle.

Which is exactly what should happen, right ? You are using ES6 syntax, you get it.

But here you are bundling with browserify, which AFAIK doesn't even understand ES6, only CommonJS.

Accordingly, if you want to require HyperHTMLElement for CommonJS you have to be a bit more specific:

// explicit 
const HyperHTMLElement = require('hyperhtml-element/cjs').default;

If your bundler is smart enough to understand .default automatically and you have some conversion behind the scene from ES6 to ES5/CJS, then you might try the following instead, still pointing at the right folder:

// implicit CJS
import HyperHTMLElement from 'hyperhtml-element/cjs';

One of the two will surely works, if the target env is CJS.