使用npm将KotlinJS生成的软件包链接起来

3

我创建了一个Kotlin多平台应用程序,生成JS和TypeScript输出文件,我正在尝试在TypeScript项目中使用这些输出文件。我对TypeScript以及整个npm生态系统都比较新。

enter image description here

酒店目录中的第一个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"
  },

enter image description here

当我点击自动完成时,我可以看到酒店套餐,但它仍然在下面显示红线。当我尝试在其他TypeScript文件中使用它时,它停止编译。
那个hotel.d.ts文件中的TypeScript头部有一个命名空间。
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;
        }
    }

我是否正确地进行了链接?

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

我可能还有什么遗漏吗?


你好!首先,我还没有开始使用MPP fpr JS,只是提到了它...你为什么要使用多个包呢?例如,你实际上正在创建用于在NPM生态系统中使用的包吗?还是这只是JS应该以一种漂亮的方式相互依赖的东西?我问这个问题是因为通常项目根目录下只有一个package.json,但当然,根据你构建/分发应用程序的方式,可能会有单独的根目录。 - Lucho
由于Kotlin MPP尚不支持拆分输出,因此更容易创建一个Kotlin MPP库,将其编译为JS,然后将生成的库引入到使用TypeScript编写的外部项目中。请参见下面的解决方法,完成后它只需要导入import Booking = com.blah.Booking而不是namespace.package.class。 - Jan Vladimir Mostert
1个回答

4
在 Kotlin 1.4 M2 中生成的 TypeScript 标头未被导出,并且已经有人为此记录了一个错误。

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

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

将此代码包含在 build.gradle.kts 的 Kotlin 块中,生成的 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("==============================================================")
    }

在您的TypeScript项目中的package.json中包含它变得直截了当。
  "dependencies": {
    "hotel": "/home/vlad/Code/.../hotel/build/js",
    "lit-html": "^1.2.1",
    "tslib": "^2.0.0"
  },

或者简单地使用npm link创建一个符号链接到生成的输出,然后允许您指向该链接而不是绝对路径,如果您移动了文件位置,则绝对路径可能会发生变化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接