JavaScript 模块

    • ,它与 AMDCommonJS 兼容。UMD modules are also able to be executed without being imported or when no module system is present. This is the default option for the browser and nodejs targets.
    • 异步模块定义(AMD,Asynchronous Module Definition),它尤其为 库所使用。
    • CommonJS,广泛用于 Node.js/npm (require 函数和 module.exports 对象)
    • 无模块(Plain)。不为任何模块系统编译。可以在全局作用域中以其名称访问模块。

    If you’re targeting the browser and want to use a different module system than UMD, you can specify the desired module type in the webpackTask configuration block. For example, to switch to CommonJS, use:

    Webpack provides two different “flavors” of CommonJS, commonjs and commonjs2, which affect the way your declarations are made available. While in most cases, you probably want commonjs2, which adds the module.exports syntax to the generated library, you can also opt for the “pure” commonjs option, which implements the CommonJS specification exactly. To learn more about the difference between commonjs and commonjs2, check .

    If you are creating a library that will be consumed from JavaScript or a Node.js file, and want to use a different module system, the instructions are slightly different.

    To select module kind, set the moduleKind compiler option in the Gradle build script.

    1. compileKotlinJs.kotlinOptions.moduleKind = "commonjs"
    1. tasks.named<KotlinJsCompile>("compileKotlinJs").configure {
    2. kotlinOptions.moduleKind = "commonjs"
    3. }

    Available values are: umd (default), commonjs, amd, plain.

    In the Kotlin Gradle DSL, there is also a shortcut for setting the CommonJS module kind:

    1. kotlin {
    2. js {
    3. }
    4. }

    要告诉 Kotlin 一个 external 类、 包、 函数或者属性是一个 JavaScript 模块,你可以使用 @JsModule 注解。考虑你有以下 CommonJS 模块叫“hello”:

    你应该在 Kotlin 中这样声明:

    1. @JsModule("hello")
    2. external fun sayHello(name: String)

    一些 JavaScript 库导出包(命名空间)而不是函数和类。 从 JavaScript 角度讲,它是一个具有一些成员对象,这些成员是类、函数和属性。 将这些包作为 Kotlin 对象导入通常看起来不自然。 编译器可以使用以下助记符将导入的 JavaScript 包映射到 Kotlin 包:

    1. @file:JsModule("extModule")
    2. package ext.jspackage.name
    3. external fun foo()
    4. external class C

    其中相应的 JavaScript 模块的声明如下:

    1. module.exports = {
    2. foo: { /* 此处一些代码 */ },
    3. C: { /* 此处一些代码 */ }
    4. }

    在前文示例中,JavaScript 模块导出单个包。 但是,一些 JavaScript 库会从模块中导出多个包。 Kotlin 也支持这种场景,尽管你必须为每个导入的包声明一个新的 .kt 文件。

    例如,让我们的示例更复杂一些:

    1. module.exports = {
    2. mylib: {
    3. pkg1: {
    4. foo: function() { /* 此处一些代码 */ },
    5. bar: function() { /* 此处一些代码 */ }
    6. baz: function() { /* 此处一些代码 */ }
    7. }
    8. }
    9. }

    要在 Kotlin 中导入该模块,你必须编写两个 Kotlin 源文件:

    1. @file:JsModule("extModule")
    2. @file:JsQualifier("mylib.pkg1")
    3. package extlib.pkg1
    4. external fun foo()
    5. external fun bar()

    以及

    1. @file:JsModule("extModule")
    2. @file:JsQualifier("mylib.pkg2")
    3. package extlib.pkg2
    4. external fun baz()

    当一个声明标有 @JsModule、当你并不把它编译到一个 JavaScript 模块时,你不能在 Kotlin 代码中使用它。 通常,开发人员将他们的库既作为 JavaScript 模块也作为可下载的 .js 文件分发, 可以将这些文件复制到项目的静态资源,并通过 <script> 标签包含。 如需告诉 Kotlin,可以在非模块环境中使用一个 @JsModule 声明,请添加 @JsNonModule 注解。例如以下 JavaScript 代码:

    1. @JsModule("hello")
    2. @JsNonModule
    3. external fun sayHello(name: String)

    Kotlin 以 Kotlin/JS 标准库作为单个文件分发,该文件本身被编译为 UMD 模块,因此你可以使用上述任何模块系统。While for most use cases of Kotlin/JS, it is recommended to use a Gradle dependency on kotlin-stdlib-js, 也在 NPM 上作为 包提供。