title: JavaScript ES6 import/export and class extends
body: <p>I builded a custom element which is a hamburger button and now I'm working on a side nav. In this side nav I want to use my hamburger button so I try to export my <code>HCHamburger</code> class which correspond to my button and import it in my <code>SideNav</code> class. The idea is to animate my button position when the side nav is opened. I try to extends my <code>SideNav</code> class with <code>HCHamburger</code> but I got the following error : <code>Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.</code></p>
  
  <p>My HCHambuger class looks like this : </p>
  
  <pre><code>'use strict';
  
  export default class HCHamburger extends HTMLElement {
  
      get menuButton() {
          if (!this._menuButton) {
              this._menuButton = this.querySelector('.hamburger-menu');
          }
  
          return this._menuButton;
      }
  
      get bar() {
          if (!this._bar) {
              this._bar = this.querySelector('.bar');
          }
  
          return this._bar;
      }
  
      attachedCallback() {
          this.menuButton.addEventListener('click', _ =&gt; {
              const sideNavContainerEl = document.querySelector('.js-side-nav-container');
              this.bar.classList.toggle("animate");
              if (sideNavContainerEl.getAttribute('nav-opened') == 'false') {
                  this.openMenuButton(sideNavContainerEl);
              } else {
                  this.closeMenuButton(sideNavContainerEl);
              }
          });
      }
  
      sayHello() {
          console.log('TOTO');
      }
  
      openMenuButton(sideNavContainerEl) {
          this.style.transform = `translateX(${sideNavContainerEl.offsetWidth}px)`;
      }
  
      closeMenuButton(sideNavContainerEl) {
          this.style.transform = `translateX(0px)`;
      }
  }
  
  document.registerElement('hc-hamburger', HCHamburger);
  </code></pre>
  
  <p>And my SideNav class like this :</p>
  
  <pre><code>'use strict';
  
  import Detabinator from './detabinator.js';
  import HCHamburger from './hamburger.js';
  
  class SideNav extends HCHamburger {
    constructor () {
      super();
      this.toggleMenuEl = document.querySelector('.js-menu');
      this.showButtonEl = document.querySelector('.js-menu-show');
      this.hideButtonEl = document.querySelector('.js-menu-hide');
      this.sideNavEl = document.querySelector('.js-side-nav');
      this.sideNavContainerEl = document.querySelector('.js-side-nav-container');
      // Control whether the container's children can be focused
      // Set initial state to inert since the drawer is offscreen
      this.detabinator = new Detabinator(this.sideNavContainerEl);
      this.detabinator.inert = true;
  
      this.toggleSideNav = this.toggleSideNav.bind(this);
      this.showSideNav = this.showSideNav.bind(this);
      this.hideSideNav = this.hideSideNav.bind(this);
      this.blockClicks = this.blockClicks.bind(this);
      this.onTouchStart = this.onTouchStart.bind(this);
      this.onTouchMove = this.onTouchMove.bind(this);
      this.onTouchEnd = this.onTouchEnd.bind(this);
      this.onTransitionEnd = this.onTransitionEnd.bind(this);
      this.update = this.update.bind(this);
  
      this.startX = 0;
      this.currentX = 0;
      this.touchingSideNav = false;
  
      this.supportsPassive = undefined;
      this.addEventListeners();
    }
  
    // apply passive event listening if it's supported
    applyPassive () {
      if (this.supportsPassive !== undefined) {
        return this.supportsPassive ? {passive: true} : false;
      }
      // feature detect
      let isSupported = false;
      try {
        document.addEventListener('test', null, {get passive () {
          isSupported = true;
        }});
      } catch (e) { }
      this.supportsPassive = isSupported;
      return this.applyPassive();
    }
  
    addEventListeners () {
      this.toggleMenuEl.addEventListener('click', this.toggleSideNav);
      this.sideNavEl.addEventListener('click', this.hideSideNav);
      this.sideNavContainerEl.addEventListener('click', this.blockClicks);
  
      this.sideNavEl.addEventListener('touchstart', this.onTouchStart, this.applyPassive());
      this.sideNavEl.addEventListener('touchmove', this.onTouchMove, this.applyPassive());
      this.sideNavEl.addEventListener('touchend', this.onTouchEnd);
    }
  
    onTouchStart (evt) {
      if (!this.sideNavEl.classList.contains('side-nav--visible'))
        return;
  
      this.startX = evt.touches[0].pageX;
      this.currentX = this.startX;
  
      this.touchingSideNav = true;
      requestAnimationFrame(this.update);
    }
  
    onTouchMove (evt) {
      if (!this.touchingSideNav)
        return;
  
      this.currentX = evt.touches[0].pageX;
      const translateX = Math.min(0, this.currentX - this.startX);
  
      if (translateX &lt; 0) {
        evt.preventDefault();
      }
    }
  
    onTouchEnd (evt) {
      if (!this.touchingSideNav)
        return;
  
      this.touchingSideNav = false;
  
      const translateX = Math.min(0, this.currentX - this.startX);
      this.sideNavContainerEl.style.transform = '';
  
      if (translateX &lt; 0) {
        this.hideSideNav();
      }
    }
  
    update () {
      if (!this.touchingSideNav)
        return;
  
      requestAnimationFrame(this.update);
  
      const translateX = Math.min(0, this.currentX - this.startX);
      this.sideNavContainerEl.style.transform = `translateX(${translateX}px)`;
    }
  
    blockClicks (evt) {
      evt.stopPropagation();
    }
  
    onTransitionEnd (evt) {
      this.sideNavEl.classList.remove('side-nav--animatable');
      this.sideNavEl.removeEventListener('transitionend', this.onTransitionEnd);
    }
  
    showSideNav () {
      this.sideNavEl.classList.add('side-nav--animatable');
      this.sideNavEl.classList.add('side-nav--visible');
      this.detabinator.inert = false;
      this.sideNavEl.addEventListener('transitionend', this.onTransitionEnd);
    }
  
    hideSideNav () {
      this.sideNavEl.classList.add('side-nav--animatable');
      this.sideNavEl.classList.remove('side-nav--visible');
      this.detabinator.inert = true;
      this.sideNavEl.addEventListener('transitionend', this.onTransitionEnd);
    }
  
    toggleSideNav () {
      if (this.sideNavContainerEl.getAttribute('nav-opened') == 'true') {
        this.hideSideNav();
        this.sideNavContainerEl.setAttribute('nav-opened', 'false');
      } else {
        this.showSideNav();
        this.sideNavContainerEl.setAttribute('nav-opened', 'true');
      }
    }
  }
  
  new SideNav();
  </code></pre>
  
  <p>I'm using webpack to build my JS code and maybe it's the reason of my issue... I tried different method to import/export but nothing worked.</p>
  
  <p>I thought to just export the method that I needed but it didn't work neither.</p>
  
  <p>Thank's</p>