如何在 NPM 中正确设置仅接口项目(及其依赖项目)?

How to correctly setup an interface-only project (and its dependent projects) in NPM?

我的 TypeScript 项目遇到了两个问题。

假设我想创建一个名为 interface-only 的 TypeScript 项目 myproject-api。我打算在名为 myproject-impl1myroject-impl2 的两个不同项目中实现接口。我根据需要使用 Lerna to manage those projects as modules in a root project named myproject, and all of them were bootstrapped (npm link)。我还使用 gulp 来转译 TypeScript 源代码,目前配置非常简单。

问题 1. 即使 "types": "dist/main.d.ts""types": "src/index.ts"package.json 中,实现模块也无法看到类型定义myproject-api。我也试过把myproject-api/src/index.ts移到myproject-api/index.ts,没用。编译器只是失败并显示消息 Cannot find module 'myproject-api'.

问题 2. 如果 .ts 源文件中没有实际实现,TypeScript 似乎不会生成 .d.ts 文件,除非我用tsc -d --outFile dist/main.js编译项目。换句话说,出于某种原因,如果我使用 tsconfig.json 配置(例如 tsc --project tsconfig.json),则会生成 .js 文件,但不会生成 .d.ts 文件。

P.S.: 我开始这个项目只是为了充实和完善我心中的一些想法。如果有人对这种项目布局有更好的设置,请告诉我。


更多信息...

我在所有 .ts 项目中使用 ES6 导入。

这是我的文件夹布局:

.
├── lerna.json
├── package.json
├── packages
│   ├── myproject-api
│   |   ├── dist
│   │   ├── gulpfile.js
│   │   ├── package.json
│   │   ├── src
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   └── myproject-impl*
│       ├── dist
│       ├── gulpfile.js
│       ├── package.json
│       ├── src
│       │   └── index.ts
│       └── tsconfig.json
└── README.md

packages/myproject-api/src/someClass.ts:

export interface ISomeClass { /* ... */ }

packages/myproject-api/src/index.ts:

export * from "./someClass.ts"
// (repeating this kind of export for all inner modules)

packages/myproject-impl*/src/index.ts:

import { ISomeClass } from "myproject-api"
// ...

Gulp 配置:

var gulp = require("gulp");
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");

gulp.task("default", ["build"]);

gulp.task("build", function () {
    return tsProject.src()
        .pipe(tsProject())
        .js.pipe(gulp.dest("."));
});

这是所有项目的tsconfig.json

{
    "compilerOptions": {
        "target": "es6",
        "module": "amd",
        "strict": true,
        "baseUrl": ".",
        "outFile": "dist/main.js",
        "declaration": true,
        "lib": [
            "es5",
            "es2015.promise",
            "es2015.iterable"
        ]
    },
    "exclude": [
        "node_modules",
        "dist"
    ]
}

系统信息:

[flisboac@sonic ~]$ tsc --version
Version 2.6.2
[flisboac@sonic ~]$ node --version
v9.3.0
[flisboac@sonic ~]$ lerna --version
2.5.1
[flisboac@sonic ~]$ gulp --version
[03:39:24] CLI version 2.0.0
[flisboac@sonic ~]$ npm --version
5.6.0
[flisboac@sonic ~]$ uname -a
Linux sonic 4.14.6-1-ARCH #1 SMP PREEMPT Thu Dec 14 21:26:16 UTC 2017 x86_64 GNU/Linux
[flisboac@sonic ~]$ lsb_release -a
LSB Version:    1.4
Distributor ID: Arch
Description:    Arch Linux
Release:    rolling
Codename:   n/a

正如@OJKwon 所建议的那样,--traceResolution 帮助我弄清楚了。根据 the documentation for module resolution,如果您在 tsconfig.json 中指定 "moduleResolution": "node",则 tsc 仅查看 package.json,默认情况下为 "moduleResolution": "classic"。使用 index.ts 作为默认导入模式也仅用于 node 分辨率。

我还必须重新启动 VSCode 才能正确解析导入。