Help us understand the problem. What is going on with this article?

npmでインストールしたmoduleのクラスをextendしたら " TypeError: Class constructor classname cannot be invoked without 'new' "

表題のエラーに遭遇したので、その原因と対処法を記録しておきます。

環境

この記事は以下の環境を前提にしています。

package.json
    "@babel/cli": "^7.2.3",
    "@babel/core": "^7.4.0",
    "@babel/preset-env": "^7.4.2",
    "typescript": "^3.3.4000",

環境が異なる場合は、この記事の内容が適用できない場合があります。ご注意ください。

問題発生の手順

  1. npmでES6ネイティブのモジュールをインストールする。
  2. モジュール内のクラスを継承する。
  3. BabelなどでES5にトランスパイルする。
import { ES6Class } from "module";
export class ClassName extends ES6Class {...

上記コードの例の場合、npmからES6ネイティブのmoduleという名前のパッケージをインストールし、
ES6Classというクラスをインポート、ClassNameというクラスに継承しています。

症状

上記の手順を実行し、生成されたjavascriptを実行すると、以下のエラーが発生します。

Uncaught TypeError: Class constructor ClassName cannot be invoked without 'new'
    at new ClassName (ClassName.js:35)
    at onDomContentsLoaded (main.js:19)
    at eval (main.js:32)
    at Module../src/main.js (bundle.js:133)
    at __webpack_require__ (bundle.js:20)
    at bundle.js:84
    at bundle.js:87
classname   @   classname.js:35
onDomContentsLoaded @   main.js:19
(anonymous) @   main.js:32
./src/main.js   @   bundle.js:133
__webpack_require__ @   bundle.js:20
(anonymous) @   bundle.js:84
(anonymous) @   bundle.js:87

ClassNameクラスのコンストラクタの実行に失敗します。

原因

この問題は、ネイティブのES6クラスを継承し、さらにES5に変換することによって発生します。この変換に失敗するために上記の症状が発生します。

対処法

変換の対象をES5ではなくES6に指定することで、この問題は解決します。

Babelの場合

Babelでトランスパイルを使用している場合、@babel/preset-envで変換対象を指定します。
nodeを変換対象に指定することでES6のjsファイルが出力されます。

{
  "presets": [
    [ "@babel/preset-env", {
      "targets": { "node": true }
    }]
  ]
}

TypeScriptの場合

TypeScriptの場合、コンパイラオブションで変換対象の指定ができます。

tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
  }
}

副作用

変換先のjsファイルはES6の構文を使用していますので、IE11では動作しません。
ECMAScript 6 compatibility table
IE11をターゲットとする場合は、extendsを使用しないなど他の回避方法を検討してください。

参考記事

stackoverflow - Javascript ES6 TypeError: Class constructor Client cannot be invoked without 'new'

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away