问题描述
背景
- 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 = myObject
或 export default myObject
它只适用于 ES6 repo (repo B).
问题:
-
是否可以使相同的文件适用于两个系统?我尝试了
export = modules.export = myObject
或任何其他组合,但都无效。 -
如何在 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)
注意事项
- 我发现在我的
"esModuleInterop": true
should make it work 中设置了tsconfig.json
,但无论我做什么,(tsconfig.json 中的任何"module"
值,打开 {{1 }}) 它不起作用。我一直收到同样的allowSyntheticDefaultImports
错误。 - 正如我在评论中提到的,可以认为该文件包含一个静态对象。 (例如
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
他们都成功打印出内容!