从Babel v5升级到v6+时出现“TypeError不是构造函数”的错误提示

4

我已经苦思冥想了一整天,但还是不能解决这个问题,我认为现在该向SO(Stack Overflow的简称)求助了!我正在尝试将一个项目从babel v5升级到更高版本,我从package.json开始如下操作:

"devDependencies": {
    "babel": "^5.8.21",

"test": "mocha --require babel/register",

我尝试升级babel到v6和v7,但两次都没有成功。在这两种情况下,当我尝试运行先前使用v5可以正常工作的测试时,我会遇到TypeError: _application.ApplicationClient不是构造函数

import { ApplicationClient } from '../src/wiotp/sdk/application';
...
let client = new ApplicationClient();

以v6为例,我在package.json中得到以下内容:

  "devDependencies": {
    "babel-cli": "^6.0.0",
    "babel-core": "^6.0.0",
    "babel-preset-env": "^1.7.0",
    "mocha": "6.1.4",

"test": "mocha --require babel-core/register --timeout 5000",

并创建了一个 .babelrc 文件(之前不存在):

{
    "presets": ["env"]
}

我已经阅读了十几篇文章,试图理解这里发生了什么,根据搜索类似问题的Google结果,我已经尝试和撤销了许多建议的 "修复",但我从零开始,发现非常难以获得一个简单的、通俗易懂的解释,首先是实际问题,以及babel在这里应该如何配置来解决它。我猜想,在v5中默认发生的某些事情现在需要在 .babelrc 中进行配置,但是我不知道从这里往哪里走。

对于一个正在努力理解babel的人,更不用说v5、6、7之间的差异了,有什么指导建议吗?

编辑:

src/wiotp/sdk/application/index.js 包含以下内容:

import { default as ApplicationClient } from './ApplicationClient';

export default {
  ApplicationClient
}

在 src/wiotp/sdk/application/ApplicationClient.js 中只导出了一个类(我只是试图在测试代码中创建该类的实例):

export default class ApplicationClient extends BaseClient {
  constructor(config) {

作为猜测,我认为ApplicationClient是使用新版本的Babel定义或编译为箭头函数,而旧版本没有这样做。不幸的是,我对Babel不够熟悉,不知道从哪里开始验证和/或修复这个问题。不过,“不是构造函数”的消息通常来自尝试在箭头函数中使用new - VLAZ
无法知道 ../src/wiotp/sdk/application 导出了什么。 请在问题中包含这一点。 - loganfsmyth
在Node中,Babel很可能会将import转换为require调用。我猜测这部分存在一些问题,可能是因为ES6和Common.js之间的交互方式没有按照预期工作。需要注意的是,自从Babel 7以后,它们已经移动到了@babel组织的作用域包中。 - adz5A
1个回答

1

src/wiotp/sdk/application/index.js has this:

import { default as ApplicationClient } from './ApplicationClient';

export default {
  ApplicationClient
}
这很糟糕,也是造成你问题的原因。该模块默认导出一个对象文本,而不是使用具名导出。这可能是个bug,他们本意可能是要写:
import { default as ApplicationClient } from './ApplicationClient';
export { ApplicationClient }

或者

export { default as ApplicationClient } from './ApplicationClient';

建议报告问题并提供补丁。

如果这不被认为是错误而是故意的,请您需要更改您的代码为

import application from '../src/wiotp/sdk/application';
…
let client = new application.ApplicationClient();
//               ^^^^^^^^^^^^

或者直接从原始模块导入它:
import ApplicationClient from '../src/wiotp/sdk/application/ApplicationClient.js';
//                                                          ^^^^^^^^^^^^^^^^^^^^^let client = new ApplicationClient();

谢谢您提供的解决方案以及对其中情况的解释,这真的帮助我理解了这里发生了什么。 - DavidParker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接