专栏首页BennyhuoKotlin 能用来开发 React Native 吗?

Kotlin 能用来开发 React Native 吗?

0. 引子

前段时间出去休了半个月假,公众号文章史无前例的断了一周,不过不要紧,我这不是又回来了嘛。

摄于:清境农场

闲话少说,既然 Kotlin 可以编译为 Js,那么我们很容易就可以用它去做前端或者 Nodejs 开发。目前官方也已经给出了 React 的 Demo,惊得我只好给大婶儿们双击 666 啊。

1. 死于黎明前的黑暗

既然 React 都有 Demo 了,那么问题来了,居然到现在了,都还没有一个能跑起来的 React Native 的 Demo,不合理啊,甚至连官方的人都说:

扎心了老铁!你贴的可是去年 4 月份的对话,专业点儿行不?

好啊,那我给你们看看 Slack:

这段话翻译成中文那就是:哥啊,kotlin 搞 react-native 到底靠不靠谱啊,react-native 打包的时候看到 kotlin.js 直接就挂机了啊。

每次看到这个界面我都想说嗷个大头鬼啊。。

我随后翻了翻 React-Native 的 issue,发现:

我当时还觉得这哥们肯定打开方式不对啊,后来仔细瞅了瞅下面的问题描述,我觉得它可以跟前面 Slack 上的兄弟握个爪了,亲切地。

你没看错,这哥们的代码就只有引入 Kotlin 这么一行,然后 React-Native 的 打包工具就得累死累活的搞,10分钟后直接超时。。

你以为闹着玩呢?仔细一看 Kotlin.js 行数居然真的这么多!

我靠,以后我看谁还敢在他的网页里面引入这东西。。

说白了就是 KotlinJs 的标准库太大了,成了 React Native 的 bundle 工具无法逾越的一道鸿沟。。

2. 还记得当年 64K 旁边的 Proguard 么?

其实我也踩到了这个坑啊,在出去休假前曾花了两个晚上琢磨怎么编译这东西,无解。后来在外面浪的时候,坐在沙滩上看着海浪轻轻的拍,好美啊。。啊,然后它就拍在了我的大胖脸上,当时脑子里面就闪过 slap、smack。。。额,对,我怎么没去 slack 上面问问呢。

然后几分钟后就有大神回复:

他这一句犹如醍醐灌顶,我瞬间想到,完了,衣服都湿了没得换可咋办。。

开玩笑啦。这里顺便提一句,这个 Slack 真心不错,里面还能看到 Jake Wharton 最近也在踩一些 KotlinJs 的坑呢。

我们先来说说 DCE,这个东西的功能有点儿类似大家很熟悉的 Proguard 中去除没有引用到的代码的功能,就是传说中的 Shrink 啦。显然,Kotlinjs 标准库里面的那 37k 代码我们不可能完全用到,例如我就写了下面一点儿代码给 React Native 代码用:

package com.bennyhuo.rnkt

@JsName("hello")
fun hello() = "I'm a String from Kotlin!"

标准库里的代码根本用不到好伐。

import React, { Component } from 'react';
import {
  AppRegistry,  Text,  View
} from 'react-native';
import HelloKotlinJs from "./rnkt/output/min/rnkt"

class HelloWorld extends Component {
  render() {
    React.createElement
    return <View>
      <Text>{HelloKotlinJs.com.bennyhuo.rnkt.hello()}</Text>
    </View>
  }
}

这种情况下,我们只需要告诉 DCE,给我留着 hello 这个函数,其他用不到的都丢掉就好啦。

除了基本的 js 编译的配置,我们再加上下面两句:

apply plugin: 'kotlin-dce-js'
runDceKotlinJs.keep 'rnkt.com.bennyhuo.rnkt.hello'

rnkt 是我编译 js 输出的模块名,后面就是是报名和函数名了。

编译之后 kotlinjs 标准库变成什么样了呢?

只有 2k 行了哦!有没有很腻害!运行结果就是下面酱紫:

3. 能给我来一个 Component 么?

OK,我们其实已经把 KotlinJs 运用到了 React-Native 上面了,不过这时候肯定有人不服:能写 JSX 么?答案当然是不能啊。那不能写 JSX 的话要怎么实现 Component 呢?

实际上 JSX 不过也是一些函数调用罢了,给大家看例子:

package com.bennyhuo.rnkt
@JsModule("react")
external object React{
    open class Component

    fun createElement(vararg args: dynamic)
}

@JsModule("react-native")
external object ReactNative{
    val Text: dynamic
}

class HelloKotlinJs: React.Component(){
    fun render(): dynamic{
    // 这里就相当于 <Text>I'm a Component from Kotlin!!!</Text>
        return React.createElement(Text, null, "I'm a Component from Kotlin!!!") 
    }
}

这时候需要注意了,我们还需要加点儿配置以防 DCE 把这些类给干掉:

runDceKotlinJs.keep "rnkt.com.bennyhuo.rnkt.HelloKotlinJs",
        "rnkt.com.bennyhuo.rnkt.HelloKotlinJs.render"

这样我们就定义了一个 Component,在 Js 当中我们就可以这么用这个组件:

class HelloWorld extends Component {
  render() {
    return <View><HelloKotlinJs.com.bennyhuo.rnkt.HelloKotlinJs/></View>
  }
}

如果嫌名字难看,那么你也可以选择把包名去掉。运行结果如下:

这时候我们用 Kotlin 写的那个 Component 渲染出来了。

4. 为什么要用 Kotlin 写 React Native?

尽管我们能实现功能,不过肯定有人要吐槽了,费了半天劲儿,结果用 Kotlin 写 React Native 就是这个鬼样子?简直费力不讨好啊。

用 Kotlin 写 React Native 程序当然不是目的,Js 挺好用的啊,为什么要让我换?但如果我手头有一个用 Kotlin 编写的算法模块想要移植到 React Native 或者其他 JavaScript 运行环境,移植起来就会轻松许多。

所以还是那句话,总是讨论替代谁是没有意义的,在给定特定的需求场景时,Kotlin 全栈的能力只是为我们多了一种选择。


本文分享自微信公众号 - Kotlin(KotlinX),作者:bennyhuo

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-01-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Kotlin Native 也能运行在 Android 当中?

    Kotlin Native 可以编译成 *.so 也就是我们常说的动态库,自然也就可以被 Android 的 Jni 调用,显然 Kotlin Native 官...

    bennyhuo
  • Kotlin 1.2 有哪些值得关注的点?

    Kotlin 1.2 的发版节奏越来越快了。从 16 年 2 月 19 日发布 1.0 到 17 年 3 月 14 日发布 1.1,这次只花了半年多的时间,厉害...

    bennyhuo
  • Kotlin 1.4 现已发布,专注于质量和性能

    Kotlin 1.4.0 今日发布!在过去的几年里,我们一直在努力使 Kotlin 成为一种有趣、令人愉快且高效的编程语言。为了借助此版本的 Kotlin 继续...

    bennyhuo
  • 我们是如何将 Cordova 应用嵌入到 React Native 中

    重写一个应用是一件简单的事,可是演进一个应用则是一件复杂的工作。 过去的一年多里,我在工作上的主要职责是:手机 APP 开发。日常主要是编写基于 Ionic 和...

    Phodal
  • 聊聊Mysql中的int(1)

    昨天有个读者问了我这样一个问题在mysql中建表的时候,我设置一个字段为int类型,长度为1,但是我发现这个字段却可以存储任意长度的数字,这是什么情况?这个问题...

    Java旅途
  • LeetCode 刷题记录 1-5

    给定一个整数数组 nums 和一个目标值 target ,找出数组中和为目标值的两个数,并返回它们的数组下标。

    口仆
  • 算法训练营-第一周-数组链表

    栈是一种线性逻辑结构,栈的元素只能后进先出。最早进入的元素存放的位置叫做栈底,最后进入的元素存放的位置叫栈顶。

    编程之心
  • Git版本控制系统之基本使用

         最早是通过接触著名的开源社区Github了解到Git的,但一直没有系统学习过。这次下定决心从头到尾系统的学一学,也将学习过程记录于此,供大家批驳。本篇...

    Single
  • Leetcode 1-10

    常规方法:使用双重循环,第一重从左往右固定索引,计算需要查找的结果,第二层循环从固定索引出发依次向右查找第一层计算的结果。时间复杂度\(O(n^2)\), 空间...

    努力努力再努力F
  • kmp算法模板

    _DIY

扫码关注云+社区

领取腾讯云代金券