在TypeScript中导入Victor.js吗?

rad*_*man 20 javascript import module typescript

我正在尝试在TypeScript项目(3.0.1)中使用victor.js库,并且在尝试导入和使用它时确实心痛。我已经从npm以及它的类型(victor @ types / victor)安装了它。我尝试了多种导入方式,但似乎无法使其与IDE中的类型解析一起导入。

我已经尝试过这些:

import { Victor} from 'victor';  
import * as v from 'victor'; 
Run Code Online (Sandbox Code Playgroud)

(只有通过打开“ allowSyntheticDefaultImports”标志并引用其默认导出,才能使用ECMAScript导入/导出引用此模块)

import Victor = require('victor');  
Run Code Online (Sandbox Code Playgroud)

(在定位ecmascript模块时有效,但不兼容)

const Victor = require("victor");  
Run Code Online (Sandbox Code Playgroud)

(有效导入,我可以构造对象,但不存在任何类型)

我敢肯定,外面有人遇到过类似的情况。如果有帮助,则victor的index.js顶部具有以下行:

exports = module.exports = Victor;
Run Code Online (Sandbox Code Playgroud)

Lou*_*uis 27

简单来说

您正在尝试victor像使用es6模块一样使用它,但事实并非如此。我看到两个选择:

  1. tsc您将模块转换为格式commonjs,在这种情况下,tsc将在victor和代码之间提供必要的粘合逻辑

  2. 或者,您需要通过提供胶水的模块加载器加载应用程序。

详细说明

当我tsc使用您显示的导入运行最新版本时,出现的错误是:

只有打开“ esModuleInterop”标志并引用其默认导出,才能使用ECMAScript导入/导出引用此模块。

当我打开时esModuleInterop,它就可以正常工作。这是我使用的测试代码:

import Victor from "victor";

const foo = new Victor(1, 2);
console.log(foo.y);
Run Code Online (Sandbox Code Playgroud)

tsconfig.json

{
  "compilerOptions": {
    "esModuleInterop": true
  }
}
Run Code Online (Sandbox Code Playgroud)

产生此问题的原因是,您在执行操作时import Victor from "victor"要求通过export default...语句(这是es6模块提供的语法)导出的值。但是,victor不会导出与对应的任何内容export default...。因此,必须采取一些措施来弥合差距。使用上面显示的内容,在编译时tsc会发出以下内容:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var victor_1 = __importDefault(require("victor"));
var foo = new victor_1["default"](1, 2);
console.log(foo.y);
Run Code Online (Sandbox Code Playgroud)

注意__importDefault助手功能。每当TS代码想要访问模块导出的内容时就使用export default...它,因为它所做的是检查模块是否声明为es6模块。想要导出默认值的es6模块已经正确构建,因此如果该模块是es6模块,则无需执行任何操作。如果该模块不是es6模块,则帮助程序将创建一种伪模块,其默认导出值是原始模块的值。

有一个重要的警告,因为您提到了“目标ecmascript模块”。如果使用,则tsconfig.json

{
  "compilerOptions": {
    "esModuleInterop": true,
    "module": "es6"
  }
}
Run Code Online (Sandbox Code Playgroud)

然后发出的代码是:

import Victor from "victor";
var foo = new Victor(1, 2);
console.log(foo.y);
Run Code Online (Sandbox Code Playgroud)

请注意,不再有任何辅助功能。由模块加载程序决定,模块加载程序将为您的应用程序加载模块以提供与提供的相同逻辑__importDefault。如果我将文件重命名为具有mjs扩展名并运行:

$ node --experimental-modules test.mjs
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

(node:18394) ExperimentalWarning: The ESM module loader is experimental.
2
Run Code Online (Sandbox Code Playgroud)

将Node与实验性模块支持一起使用时,它提供的功能与相同__importDefault


当您只是allowSyntheticDefaultImports不使用而使用时,esModuleInterop您是在告诉编译器以为您的工具链中有可以完成的工作__importDefault。因此,编译器不提供帮助程序。它允许进行编译,但是稍后有责任使用将执行与相同的工作的模块加载器__importDefault

  • 我的荣幸。是的,它是普通的CommonJS。CommonJS不像es6模块那样区分“默认”导出。而且Victor.js的作者并没有编写使Victor.js看起来像es6模块所需的胶水(导出将__esModule设置为true,等等)。 (3认同)

Zpe*_*ube 13

我看到已经有很好的答案,但想添加这个较短的答案。

错误信息: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.ts(2497)

将我自己的 javascript 文件转换为 typescript 时,我在从 es5 移动到 es6(以及 javascript 到 typescript)时遇到了导入问题。

import * as File from "./MyFile"在 OtherFile.ts 中一样导入。

在我最后拥有的 MyFile.ts 文件中export = {funcName}

解决方案是从 MyFile.ts 文件中删除=这样export {funcName}的内容。

(希望这对某人有所帮助,第一次尝试回答错误/问题)