Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Angular 6 typescript与KotlinJs的集成_Javascript_Angular_Typescript_Kotlin_Requirejs - Fatal编程技术网

Javascript Angular 6 typescript与KotlinJs的集成

Javascript Angular 6 typescript与KotlinJs的集成,javascript,angular,typescript,kotlin,requirejs,Javascript,Angular,Typescript,Kotlin,Requirejs,我刚刚在angular 6 typescript文件中导入了Kotlin编译的javascript模块。这并不容易,结果让我困惑。我想知道是否存在更优雅的方式 我最初使用的是Kotlin文件: package com.example.test data class SomeInterface( var id: String? = null, var value: String? = null ) { } 它可以很好地编译为以下JavaScript (function (roo

我刚刚在angular 6 typescript文件中导入了Kotlin编译的javascript模块。这并不容易,结果让我困惑。我想知道是否存在更优雅的方式

我最初使用的是Kotlin文件:

package com.example.test

data class SomeInterface(
    var id: String? = null,
    var value: String? = null
) {
}
它可以很好地编译为以下JavaScript

(function (root, factory) {
  if (typeof define === 'function' && define.amd)
    define(['exports', 'kotlin'], factory);
  else if (typeof exports === 'object')
    factory(module.exports, require('kotlin'));
  else {
    if (typeof kotlin === 'undefined') {
      throw new Error("Error loading module 'TestKotlinCompiled'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'TestKotlinCompiled'.");
    }
    root.TestKotlinCompiled = factory(typeof TestKotlinCompiled === 'undefined' ? {} : TestKotlinCompiled, kotlin);
  }
}(this, function (_, Kotlin) {
  'use strict';
  var Kind_CLASS = Kotlin.Kind.CLASS;
  function SomeInterface(id, value) {
    if (id === void 0)
      id = null;
    if (value === void 0)
      value = null;
    this.id = id;
    this.value = value;
  }
  SomeInterface.$metadata$ = {
    kind: Kind_CLASS,
    simpleName: 'SomeInterface',
    interfaces: []
  };
  SomeInterface.prototype.component1 = function () {
    return this.id;
  };
  SomeInterface.prototype.component2 = function () {
    return this.value;
  };
  SomeInterface.prototype.copy_rkkr90$ = function (id, value) {
    return new SomeInterface(id === void 0 ? this.id : id, value === void 0 ? this.value : value);
  };
  SomeInterface.prototype.toString = function () {
    return 'SomeInterface(id=' + Kotlin.toString(this.id) + (', value=' + Kotlin.toString(this.value)) + ')';
  };
  SomeInterface.prototype.hashCode = function () {
    var result = 0;
    result = result * 31 + Kotlin.hashCode(this.id) | 0;
    result = result * 31 + Kotlin.hashCode(this.value) | 0;
    return result;
  };
  SomeInterface.prototype.equals = function (other) {
    return this === other || (other !== null && (typeof other === 'object' && (Object.getPrototypeOf(this) === Object.getPrototypeOf(other) && (Kotlin.equals(this.id, other.id) && Kotlin.equals(this.value, other.value)))));
  };
  var package$com = _.com || (_.com = {});
  var package$example = package$com.example || (package$com.example =     {});
  var package$test = package$example.test || (package$example.test = {});
  package$test.SomeInterface = SomeInterface;
  Kotlin.defineModule('TestKotlinCompiled', _);
  return _;
}));
在package.json中,我将“^1.2.70”添加到依赖项部分。 在角度分量中,我必须使用这样的代码进行导入

import * as TestKotlinCompiled from "../../generated/TestKotlinCompiled";

// @ts-ignore
const SomeInterface = TestKotlinCompiled.com.example.test.SomeInterface;
// @ts-ignore
type SomeInterface = TestKotlinCompiled.com.example.test.SomeInterface;
这是在包
com.example.test
中使用类
someinterface
的最低强制性代码,生成到模块
testkotluncompiled

这里的问题如下

/@ts ignore
是必需的,因为ts编译器在编译时看不到正在导入的模块的内容

新建SomeInterface()

let x:SomeInterface需要
类型

所有这些看起来都非常粗糙。 我想要更简单的,比如
使用名称空间com.example.test从“../../generated/TestKotlinCompiled”导入{SomeInterface},而不使用
const
type

那么,有没有办法简化我上面的代码呢?

我成功地提高了KotlinJs在Angular中的一点可用性。我把我的实验放在实验室里

首先,我们必须在Gradle中创建一个多平台子模块。在这种情况下,我们生成js文件(以及其他可能的平台)

然后我们添加到package.json

{
  "dependencies": {
    "kotlin": "^1.3.21",
    "proj-common": "file:../build/javascript-compiled"
  }
}
proj common是我们编译的Kotlin模块。那里的路径是kotlin js文件构建的目的地

因此,在typescript中,我们只需使用一个以上的npm模块

从'proj common/proj common'导入{sample};
//类样本
sample=新的sample.sample();
//面向对象平台
平台=样品平台;
编译进行得很顺利,不需要使用
/@ts ignore

更新 在上面的解释中,子依赖项存在问题。它们并没有被导出,但并非所有的子依赖项都在npm存储库中有它们的等价项。下面的代码解决了这个问题

tasks {
    task<Sync>("assembleWeb") {
        val dependencies = configurations.get("jsMainImplementation").map {
            val file = it
            val (tDir, tVer) = "^(.*)-([\\d.]+-\\w+|[\\d.]+)\\.jar$"
                .toRegex()
                .find(file.name)
                ?.groupValues
                ?.drop(1)
                ?: listOf("", "")
            var jsFile: File? = null
            copy {
                from(zipTree(file.absolutePath), {
                    includeEmptyDirs = false
                    include { fileTreeElement ->
                        val path = fileTreeElement.path
                        val res = (path.endsWith(".js") || path.endsWith(".map"))
                                && (path.startsWith("META-INF/resources/") || !path.startsWith("META-INF/"))
                        if (res && path.endsWith(".js") && ! path.endsWith(".meta.js")) jsFile = fileTreeElement.file
                        res
                    }
                })
                into("$npmTarget/$tDir")
            }
            jsFile?.also { packageJson(tDir, it, tVer) }
            tDir to jsFile
        }
            .filter { it.second != null }
            .map { it.first to it.second!! }
            .toMap()

        packageJson(npmDir, File(jsOutputFile), project.version.toString(), dependencies)
        dependsOn("jsMainClasses")
    }

    assemble.get().dependsOn("assembleWeb")
}

fun packageJson(dir: String, jsFile: File, version: String, dependencies: Map<String, File> = emptyMap()) {
    val deps = dependencies.map {
        """"${js2Name(it.value)}": "file:../${it.key}""""
    }.joinToString(",\n            ")
    val text = """
        {
          "name": "${js2Name(jsFile)}",
          "version": "${version}",
          "main": "./${jsFile.name}",
          "dependencies": {
            ${deps}
          }
        }
    """.trimIndent()
    File("$npmTarget/$dir/package.json").apply {
        if (parentFile.exists()) {
            parentFile.delete()
        }
        parentFile.mkdirs()
        writeText(text)
    }
}

fun js2Name(jsFile: File) = jsFile.name.replace("""\.js$""".toRegex(), "")
在typescript文件中:

从'proj common'导入{sample};
//类样本
sample=新的sample.sample();
//面向对象平台
平台=样品平台;
示例项目请参见

更新2 现在,您可以使用kotlin common子项目创建完整的堆栈项目,就像在gradle中附加插件一样简单

plugins {
    id("com.crowdproj.plugins.jar2npm")
}
该插件将在编译期间自动将所有kotlin js jar包注入节点_模块


这个项目现在用这个插件重写了。参见子模块。

我也尝试过解决这个集成问题, 有许多问题需要克服,例如:

  • 生成类型脚本声明文件
  • 将kotlin JS模块解包到节点_模块中
  • 第三方图书馆
这里有一篇描述这些问题的博客文章

我还创建了一个gradle插件,让一切变得更加简单,

您只为使用angular编写了一个包装器。我解决了Angular和Kotlin之间的积分问题。如果您想要更多,欢迎您提出自己的解决方案。到目前为止,我还没有看到。对不起,它不喜欢链接周围的[]
plugins {
    id("com.crowdproj.plugins.jar2npm")
}