首页 > 解决方案 > KotlinJS 生成的 npm 链接包

问题描述

我创建了一个生成 JS 和 TypeScript 输出文件的 Kotlin 多平台应用程序,我正在尝试在 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 中的打字稿标头具有命名空间

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;
        }
    }

我是否正确进行链接?

我是否正确包含此链接包?

还有什么我可能会丢失的吗?

标签: typescriptkotlingradlenpmkotlin-multiplatform

解决方案


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

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

我写的一个快速而肮脏的解决方法是在 Gradle 构建结束时运行一些 Kotlin 脚本来对生成的 TypeScript 进行后处理。

将其包含在您的 Kotlin 块中build.gradle.kts,生成的 TS 标头将在 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("==============================================================")
    }

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

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

或者简单地使用npm link创建一个指向生成输出的simlink,然后允许您指向链接而不是绝对路径,如果您移动东西,绝对路径可能会改变。


推荐阅读