npm link 个由 KotlinJS 生成的包

npm link packages generated by KotlinJS

我创建了一个生成 JS 和 TypeScript 输出文件的 Kotlin Multiplatform 应用程序,我正在尝试在 TypeScript 项目中使用这些输出文件 我对 TypeScript 以及整个 npm 生态系统都很陌生

旅馆目录中的第一个 package.json 如下所示:

{
  "main": "kotlin/hotel.js",
  "devDependencies": {
    "webpack": "4.42.1",
    "webpack-cli": "3.3.11",
    "source-map-loader": "0.2.4",
    "webpack-dev-server": "3.10.3",
    "css-loader": "3.4.2",
    "style-loader": "1.1.3"
  },
  "dependencies": {
    "kotlin": "file:/home/vlad/Code/hotel-state/build/js/packages_imported/kotlin/1.4.0-M2",
    "kotlin-source-map-loader": "file:/home/vlad/Code/hotel-state/build/js/packages_imported/kotlin-source-map-loader/1.4.0-M2"
  },
  "peerDependencies": {},
  "optionalDependencies": {},
  "bundledDependencies": [],
  "name": "hotel",
  "version": "1.0.0"
}

js 目录中的第二个 package.json 如下所示:

{
  "private": true,
  "workspaces": [
    "packages/hotel",
    "packages/hotel-test"
  ],
  "devDependencies": {},
  "dependencies": {},
  "peerDependencies": {},
  "optionalDependencies": {},
  "bundledDependencies": [],
  "name": "hotel",
  "version": "1.0.0"
}

从酒店目录,我已经完成了

sudo npm link hotel 

在我的第二个项目中,我现在将其添加到 package.json,然后是 npm install

  "dependencies": {
    "hotel": "file:/usr/lib/node_modules/hotel",
    "lit-html": "^1.2.1"
  },

当我点击自动完成时,我可以看到酒店套餐,但它下面一直显示一条红线。当我尝试在其他 TypeScript 文件中使用它时,它停止编译

hotel.d.ts 中的打字稿 headers 有一个命名空间

declare namespace hotel {
    type Nullable<T> = T | null | undefined
    namespace com.harakati.hotel {
        /* ErrorDeclaration: Class com.harakati.hotel.TH with kind: OBJECT */
    }

    namespace com.harakati.hotel {
        class Room {
            constructor(roomNumber: Nullable<number>)
            static Room_init_$Create$(roomNumber: Nullable<number>, $mask0: number, $marker: Nullable<any /*Class kotlin.js.DefaultConstructorMarker with kind: OBJECT*/>): com.harakati.hotel.Room
            roomNumber: number;
        }
    }

我链接正确吗?

我是否正确包含了这个链接包?

还有什么我可能遗漏的吗?

原来在 Kotlin 1.4 M2 中生成的 TypeScript headers 没有被导出,并且有人已经为它记录了一个错误

https://youtrack.jetbrains.com/issue/KT-37883

我写的一个快速而肮脏的解决方法是 运行 在 Gradle 构建结束时 post-process 生成的 TypeScript 的一些 Kotlin 脚本。

将其包含在 build.gradle.kts 的 Kotlin 块中,生成的 TS headers 将毫无问题地导入 TS 项目。

    gradle.buildFinished {
        println("==============================================================")
        val path = "$buildDir/js/packages/${project.name}/kotlin/${project.name}.d.ts"
        println("Making some adjustments to \n$path")
        val newLines = mutableListOf<String>()
        println("==============================================================")
        if (File(path).exists()) {
            File(path).readLines().forEach { line ->
                if (line.startsWith("declare namespace") || line.startsWith("}")) {
                    "// $line".let {
                        newLines.add(it)
                        println(it)
                    }
                } else if (line.trim().startsWith("namespace")) {
                    line.replace("namespace", "export namespace").let {
                        newLines.add(it)
                        println(it)
                    }
                } else {
                    line.let {
                        newLines.add(it)
                        println(it)
                    }
                }
            }
            File(path).writeText(newLines.joinToString("\n"))
        } else {
            println("$path does not exist")
        }
        println("==============================================================")
    }

在您的 TypeScript 项目中的 package.json 中,包含它变得很简单

  "dependencies": {
    "hotel": "/home/vlad/Code/.../hotel/build/js",
    "lit-html": "^1.2.1",
    "tslib": "^2.0.0"
  },

或者简单地使用 npm link 为生成的输出创建一个 simlink 然后允许你指向 link 而不是绝对路径,如果你把东西搬来搬去。