I have been writing a Kotlin wrapper for a react Material UI component set which once in a reasonable condition I plan to release to (or on ) the public… it seems to work reasonably well so far and almost ready to be previewed.
However, I have been using create-react-kotlin-app and yarn start for development. It now takes about 20 seconds to recompile after any changes.
I now want to move on and try using my wrapper in a real app (the component project has a demo app and that works fine - just slow to compile).
To separate things, and to avoid having to compile my wrapper every time, I am trying to get my Kotlin react component project compiling and then using it in my second Kotlin javascript project.
I am planning on using Gradle (kts). I have played with the kotlin-frontend-plugin and had some success for getting a single project running.
However, I have abandoned that in favour of using node (yarn) and webpack directly.
I have spent many hours trying to make this work… I am at my closest now where my project and the component project seem to get compiled into the one bundle, however this is now throwing up errors.
I am no Gradle or javascript (and therefore neither node nor webpack) expert, so that has been half of the struggle.
I have attached a zip file of the project (see end of post) for anyone that would like to take a look. As mentioned, once I get this working there will be a few thousand lines of Kotlin react material UI wrapper code to be released :-)… the attached zip is a smaller test application with just a dummy react component to get started. I am also happy to release the wrapper earlier if anyone would like to help make the component side of things work.
I have also posted the build.gradle.kts files and package.json files, etc. below, but not sure how useful they would be for solving my problem in isolation (as mentioned, full zip attachment at the end of the post).
Right now I get the following error:
Uncaught TypeError: throwCCE is not a function
at get_js (kotlin.js:32305)
at RDOMBuilder.RBuilder.child_bzgiuu$ (kotlin-react.js:119)
at testComponent1 (index.js:47)
at includeComponent$lambda (app.js:92)
at buildElements (kotlin-react.js:163)
at render_0 (kotlin-react-dom.js:165)
at includeComponent (app.js:101)
at main (app.js:21)
at eval (app.js:111)
at eval (app.js:114)
get_js @ kotlin.js:32305
RBuilder.child_bzgiuu$ @ kotlin-react.js:119
testComponent1 @ index.js:47
includeComponent$lambda @ app.js:92
buildElements @ kotlin-react.js:163
render_0 @ kotlin-react-dom.js:165
includeComponent @ app.js:101
main @ app.js:21
(anonymous) @ app.js:111
(anonymous) @ app.js:114
./build/js/app.js @ bundle.js:807
__webpack_require__ @ bundle.js:20
(anonymous) @ bundle.js:69
(anonymous) @ bundle.js:72
As mentioned, I have spent quite a few hours on this over the last couple of weeks (spare time project), but if anyone could help… I would be so grateful.
I would also greatfully recieve feedback on how to do any of this is a better or more standard way
Thanks!
Component project build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
val production: Boolean = (parent!!.properties["production"] as String ).toBoolean()
buildscript {
var kotlinVersion: String by extra
kotlinVersion = "1.2.41"
repositories {
jcenter()
maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }
}
dependencies {
classpath(kotlin("gradle-plugin", kotlinVersion))
}
}
apply {
plugin("kotlin2js")
}
// Not sure why this is needed, but it makes "compile(kotlinModule("stdlib-js", kotlinVersion))" line down below work
plugins {
java
id("com.moowork.node") version "1.2.0"
}
val kotlinVersion: String by extra
repositories {
jcenter()
maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }
maven { setUrl("https://dl.bintray.com/kotlin/kotlin-dev") }
maven { setUrl("http://dl.bintray.com/kotlin/kotlin-js-wrappers") }
}
dependencies {
compile(kotlin("stdlib-js", kotlinVersion))
compile("org.jetbrains", "kotlin-react", "16.3.1-pre.28-kotlin-1.2.30")
compile("org.jetbrains", "kotlin-react-dom", "16.3.1-pre.28-kotlin-1.2.30")
}
val compileKotlin2Js: Kotlin2JsCompile by tasks
compileKotlin2Js.kotlinOptions {
sourceMap = true
metaInfo = true
outputFile = "${project.buildDir.path}/js/index.js"
main = "call"
moduleKind = "commonjs"
}
val webpack by tasks.creating(Exec::class) {
inputs.file("yarn.lock")
// NOTE: Add inputs.file("webpack.config.js") for projects that have it
inputs.dir("$buildDir/js")
// inputs.dir("node_modules")
outputs.dir("$projectDir/dist")
// commandLine("$projectDir/node_modules/.bin/webpack", "app/index.js", "$buildDir/js/bundle.js")
// commandLine("$projectDir/node_modules/.bin/webpack-cli", "--verbose", "--mode=development", "$buildDir/js/index.js", "$projectDir/dist/main.js")
commandLine("$projectDir/node_modules/.bin/webpack-cli", "--verbose", "--mode=development", "$buildDir/js/index.js")
// commandLine("$projectDir/node_modules/.bin/webpack-cli", "$projectDir/webpack.config.js")
}
Component project package.json: (Note it has hard coded paths to @jetbrains packages… not sure how it is supposed to work, but the @jetbrains node modules are not found otherwise… I saw that the kotlin-frontend-plugin does something sort of similar… if you know a better way, I would love to know )
{
"name": "test-comonents-1",
"version": "0.1.0-SNAPSHOT",
"description": "A couple of test components",
"main": "build/js/index.js",
"private": true,
"dependencies": {
"@jetbrains/kotlin-extensions": "^1.0.1-pre.28",
"@jetbrains/kotlin-react": "^16.3.1-pre.28",
"@jetbrains/kotlin-react-dom": "^16.3.1-pre.28",
"core-js": "^2.5.3",
"kotlin": "^1.2.41",
"kotlin-extensions": "file:///home/colin/Documents/IdeaProjects/test-react/components/node_modules_imported/kotlin-extensions/",
"kotlin-react": "file:///home/colin/Documents/IdeaProjects/test-react/components/node_modules_imported/kotlin-react/",
"kotlin-react-dom": "file:///home/colin/Documents/IdeaProjects/test-react/components/node_modules_imported/kotlin-react-dom/",
"kotlinx-html-js": "^0.6.4",
"react": "^16.3.1",
"react-dom": "^16.3.1"
},
"devDependencies": {
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3"
}
}
Test App build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
buildscript {
var kotlin_version: String by extra
kotlin_version = "1.2.41"
repositories {
jcenter()
maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }
}
dependencies {
classpath(kotlin("gradle-plugin", kotlin_version))
}
}
group = "com.ccfraser.testing"
version = "1.0-SNAPSHOT"
apply {
plugin("kotlin2js")
}
// Not sure why this is needed, but it makes "compile(...)" lines down below work
plugins {
java
id("com.moowork.node") version "1.2.0"
}
val kotlin_version: String by extra
repositories {
repositories {
jcenter()
maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }
maven { setUrl("https://dl.bintray.com/kotlin/kotlin-dev") }
maven { setUrl("http://dl.bintray.com/kotlin/kotlin-js-wrappers") }
}
}
dependencies {
compile(kotlin("stdlib-js", kotlin_version))
compile("org.jetbrains", "kotlin-react", "16.3.1-pre.28-kotlin-1.2.30")
compile("org.jetbrains", "kotlin-react-dom", "16.3.1-pre.28-kotlin-1.2.30")
compile(project(":components"))
}
val compileKotlin2Js: Kotlin2JsCompile by tasks
compileKotlin2Js.kotlinOptions {
sourceMap = true
metaInfo = true
// outputFile = "${project.buildDir.path}/js/index.js"
outputFile = "${project.buildDir.path}/js/app.js"
main = "call"
moduleKind = "commonjs"
freeCompilerArgs = listOf("-Xcoroutines=enable")
}
val webpack by tasks.creating(Exec::class) {
inputs.file("yarn.lock")
// NOTE: Add inputs.file("webpack.config.js") for projects that have it
inputs.file("webpack.config.js")
inputs.dir("$buildDir/js")
// inputs.dir("node_modules")
outputs.dir("$buildDir/dist")
// commandLine("$projectDir/node_modules/.bin/webpack", "app/index.js", "$buildDir/js/bundle.js")
// commandLine("$projectDir/node_modules/.bin/webpack", "--verbose", "$buildDir/js/index.js", "$buildDir/dist/bundle.js")
// commandLine("$projectDir/node_modules/.bin/webpack-cli", "--verbose", "--mode=development", "$buildDir/js/index.js", "/home/colin/Documents/IdeaProjects/test-react/components/build/js/index.js")
commandLine("$projectDir/node_modules/.bin/webpack-cli", "--config", "$projectDir/webpack.config.js")
}
Test App package.json: (again with hard coded paths)
{
"name": "test-new-kotlin-react-app",
"version": "0.1.0",
"main": "build/js/index.js",
"private": true,
"dependencies": {
"@jetbrains/kotlin-extensions": "^1.0.1-pre.28",
"@jetbrains/kotlin-react": "^16.3.1-pre.28",
"@jetbrains/kotlin-react-dom": "^16.3.1-pre.28",
"core-js": "^2.5.3",
"kotlin": "^1.2.41",
"kotlin-extensions": "file:///home/colin/Documents/IdeaProjects/test-react/components/node_modules_imported/kotlin-extensions/",
"kotlin-react": "file:///home/colin/Documents/IdeaProjects/test-react/components/node_modules_imported/kotlin-react/",
"kotlin-react-dom": "file:///home/colin/Documents/IdeaProjects/test-react/components/node_modules_imported/kotlin-react-dom/",
"kotlinx-html-js": "^0.6.4",
"react": "^16.3.1",
"react-dom": "^16.3.1"
},
"devDependencies": {
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3"
}
}
Test app webpack.config.js:
'use strict';
const path = require('path');
module.exports = {
};
const config = {
mode: 'development',
entry: './build/js/app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
// module: {
// rules: [
// { test: /\.txt$/, use: 'raw-loader' }
// ]
// },
resolve: {
modules: [
"js",
"build/js",
"resources",
"node_modules",
"../../test-react/components/build/js"
]
}
};
module.exports = config;
test-react.zip (190.9 KB)