【发布时间】:2021-10-28 06:48:47
【问题描述】:
我正在制作自己的库,我想同时使用 javascript 和 typescript。
tsconfig.json
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"declaration": true,
"outDir": "./lib",
"esModuleInterop": true
},
"include": [
"src"
],
"exclude": [
"node_modules",
"**/__tests__/*"
]
}
package.json
{
"main": "lib/classA.js",
"types": "lib/classA.d.ts",
"files": [
"lib/**/*"
],
"scripts": {
"build": "tsc"
}
}
/*
.
.
.
*/
classAInterfaces.ts
export interface IClassA<T> {
size(): number;
/*
.
.
.
*/
}
classA.ts
import { IClassA } from './classAInterfaces';
export default class ClassA<T> implements IClassA<T> {
constructor() {
// ...
}
size() {
// ...
}
/*
.
.
.
*/
}
它被编译为:
classA.d.ts
import { IClassA } from './ClassAInterfaces';
export default class ClassA<T> implements IClassA<T> {
constructor();
size(): number;
}
classA.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class ClassA {
constructor(options) {
// ...
}
size() {
// ...
}
}
exports.default = ClassA;
classAInterfaces.d.ts
export interface IClassA<T> {
size(): number;
/*
.
.
.
*/
}
classAInterfaces.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
现在,当我想在我的项目中使用它时,我在 typescript 项目中使用它没有任何问题(我在 nestjs 中构建这个 ts 项目)
tsconfig.build.json
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
}
}
package.json
{
"scripts": {
"build": "nest build",
"start": "nest start",
}
/*
.
.
.
*/
}
main.ts
import ClassA from 'class-a';
async function main() {
console.log('--------------------------------', ClassA);
const q = new ClassA<number>();
console.log('---------', q.size());
}
main();
它按预期工作,打印:
-------------------------------- [class ClassA]
--------- 0
但是,当我尝试在 javascript 项目中使用它时
package.json
{
"type": "module",
"main": "index.js",
"scripts": {
"start": "node ./index.js"
}
/*
.
.
.
*/
}
index.js
import ClassA from 'class-a'
console.log('--------------------------------', ClassA);
const q = new ClassA();
console.log('---------', q.size());
我得到以下输出:
-------------------------------- { default: [class ClassA] }
file:///C:/Users/win/Desktop/projects/tesst%20library/index.js:5
const q = new ClassA();
^
TypeError: ClassA is not a constructor
我可以使用它
const q = new ClassA.default();
但我不喜欢它,我想像在打字稿中一样使用它。
我想出的唯一解决方案是更改 classA.ts 导出:
import { IClassA } from './classAInterfaces';
class ClassA<T> implements IClassA<T> {
constructor() {
// ...
}
size() {
// ..
}
}
export = ClassA;
然后将 classA.js 更改为
"use strict";
class ClassA {
constructor(options) {
// ...
}
size() {
// ...
}
}
module.exports = ClassA;
和 classA.d.ts 到:
import { IClassA } from './ClassAInterfaces';
declare class ClassA<T> implements IClassA<T> {
constructor();
size(): number;
}
export = ClassA;
将 classA.js 的导出更改为 CommonJS,如导出。该解决方案的问题是我的打字稿项目不再识别我的库(main.ts 打印“-------------- ------ 第一行未定义)
【问题讨论】:
-
你已经将你的 typescript 转换成一个 commonjs 模块。如果你想在 JS
type: module项目中使用它,你仍然需要 import it like a commonjs module。如果要导入 es 模块,请更改 typescript 编译器设置以输出 es 模块并更改class-a包的 package.json 以反映这一点。 Nodejs 不关心__esModule- 只有编译器(babel、tsc)构建的脚本才关心。
标签: javascript node.js typescript commonjs ecma