在 commonjs 和 ejs 之间共享文件,Typescript 不是 commonjs 文件上的 module.ts(2306)

问题描述

背景

我有一个文件需要在两个存储库之间共享。该文件包含一个对象。

  • Repo A 设置为仅接受 commonjs 文件 (require("/path/to/file")),我无法轻松访问其 babel 配置。
  • Repo B 使用 ES6 import foo from "bar" 导入样式,我可以使用它的 tsconfig.json

我知道如果我使用 modules.export = myObject 它只适用于 commonjs repo (repo A),如果我使用 export = myObjectexport default myObject 它只适用于 ES6 repo (repo B).

问题:

  1. 是否可以使相同的文件适用于两个系统?我尝试了 export = modules.export = myObject 或任何其他组合,但都无效。

  2. 如何在 ES6 存储库中导入 commonjs 版本? 我尝试将其保留为 commonjs modules.export = myObject 文件,但是在存储库 B 中执行 import foo from "path/to/file" 时一直哭着下面的消息。它在我将其更改为 export = myObject 的那一刻就消失了,但随后它不适用于 Repo A。

File '/path/to/file.ts' is not a module.ts(2306)

注意事项

  1. 我发现在我的 "esModuleInterop": true should make it work 中设置了 tsconfig.json,但无论我做什么,(tsconfig.json 中的任何 "module" 值,打开 {{1 }}) 它不起作用。我一直收到同样的 allowSyntheticDefaultImports 错误
  2. 正如我在评论中提到的,可以认为该文件包含一个静态对象。 (例如2306

tsconfig.json

我正在接触的 repo A 中的部分是 config file for Quasar,它是在 vanilla JS 中的。

Repo B 是 Typescript/Node 项目,里面的 tsconfig.json 相关部分是:

{a: 5,b: 8};

解决方法

我找到了一个解决方案,但是commonjs land中的导入语法不是最好的,但我希望它对你有用。

除了指定 commonjs 和 es6 样式导入之外,您没有提供有关如何设置项目的任何信息,因此我要在这里冒险。还值得注意的是,虽然包含文件有效,但在使用 commonjs 样式的导入时,它们被键入而不是保留它们的打字稿类型(我无法使用 commonjs 样式导入(需要)进行键入 - 我没有使用此导入语法有一段时间,所以正确的 tsconfig.json 选项让它工作让我逃避)。


我将共享代码移动到它自己的项目中并使用以下 tsconfig 设置编译它:

共享 tsconfig.json:

{
    "compilerOptions": {
        "module": "commonjs","target": "ES5","lib": [ "ES5" ],}
}

共享.ts:

export default {'a': 1,'b': 2};

Shared.js(输出):

"use strict";
Object.defineProperty(exports,"__esModule",{ value: true });
exports.default = { 'a': 1,'b': 2 };

(注意这个输出是commonjs风格的,因为ES6兼容commonjs文件)


直接使用 require 时需要引用导入文件中的 .default 变量:

commonjs.ts

var val = require("../shared/shared").default;

console.log(val);

但是,如果您配置为可以将 ES6 样式的导入和输出写入 commonjs,则可以改用以下语法(这将为您提供键入信息):

commonjs.ts

import val from "../shared/shared";

console.log(val);

以上两个文件都是使用以下 tsconfig 编译的:

tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs","target": "es5","lib": [ "es5" ],"types": ["node"]
    }
}

ES6 导入非常简单:

es6.ts

import shared from "../shared/shared";

console.log(shared);

tsconfig.json:

{
    "compilerOptions": {
        "module": "ES6","target": "es6","lib": [ "es6" ]
    }
}

我偷偷怀疑这并不能 100% 解决您的问题,但我需要每个项目的 tsconfig 设置作为您为每个项目使用的打字稿编译器的版本,以便做出更准确的答案。

,

我进行了更多实验,并制作了您可能更喜欢的另一种解决方案。

我仍然没有弄清楚如何在 common-js 样式导入上输入,但是如果运行,导入确实可以工作并且不会导致编译器错误。


我将共享代码移动到它自己的项目中,并使其编译到不同的目录。这是因为如果导入打字稿文件,“esModuleInterop”标志不起作用,所以我将带有支持 .d.ts 文件的 javascript 文件编译到另一个目录,以便源 .ts 文件不会引起冲突。

共享 tsconfig.json:

{
    "compilerOptions": {
        "module": "commonjs","declaration": true,"outDir": "../sharedOut"
    }
}

共享.ts:

export = {'a': 1,'b': 2};

在输出文件夹中你应该得到:

Shared.js:

"use strict";
module.exports = { 'a': 1,'b': 2 };

共享.d.ts

declare const _default: {
    a: number;
    b: number;
};
export = _default;

这会使您的 commonjs 导入看起来像这样:

commonjs.ts

var val = require("../sharedOut/shared");

console.log(val);

或(如果您可以使用 ES6 样式的导入但需要输出是 commonjs):

import val from "../sharedOut/shared";

console.log(val);

以上两个文件都是使用以下 tsconfig 编译的:

tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs","types": ["node"],"esModuleInterop": true
    }
}


ES6 导入(再次)非常简单:

es6.ts

import shared from "../shared/shared";

console.log(shared);

tsconfig.json:

{
    "compilerOptions": {
        "module": "ES6","lib": [ "es6" ],"esModuleInterop": true
    }
}


同样,如果这不能解决您的问题,我将需要更多信息才能取得进展。我需要每个项目的 tsconfig 设置作为您用于每个项目的打字稿编译器的版本,以便做出更准确的答案。

,

我刚刚发现只要文件是具有正确 JSON 格式的 .json 文件,就可以在 ES6 (import) 和 CommonJS (require) 中使用它。

根据 this answer(和 this article),对于 ES6,您需要在 "resolveJsonModule": true, 中启用 tsconfig.json,然后您可以拥有两种格式的内容。

因此,如果文件 content.json 具有以下内容(没有注释或其他任何内容):

{
   "age": 34
}

然后我们将...

import * as jsonContent from "../../content.json"

console.log(jsonContent.age); // prints out 34

以及

const jsonContent = require("../../content.json");

console.log(jsonContent.age); // prints out 34

他们都成功打印出内容!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...