A new dead code elimination tool for JS


#1

A new 1.1.4 EAP provides a new cool feature for JavaScript: a dead code elimination (DCE) tool. This tool allows to strip out unused pieces of code from generated JS. When you are writing an application, you, hopefully, don’t write unused code. However, you might use libraries, which may be huge and of which you use only small parts. Examples are: kotlin.js (~1.3 mb), kotlinx-html-js.js (~550 kb). DCE tool is good at removing unused code from these libraries. Currently, DCE reduces size of kotlin.js file down to ~65 kb for a simple “Hello, World” application.

How to use

DCE tool is currently available from Gradle and as a command-line tool. We will describe how to use it from CLI later. For now, we are going to show how to use it from Gradle.

Simply add the following line to your build.gradle:

apply plugin: 'kotlin-dce-js'

Note that if you are using multi-project build, you should apply plugin to the main project that is an entry point to your application.

For example as for 1.1.4 EAP, the build script may look like this:

group 'org.jetbrains.kotlin'
version '1.0-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.1.4-eap-11'

    repositories {
        maven { url 'https://dl.bintray.com/kotlin/kotlin-eap-1.1' }
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

apply plugin: 'kotlin2js'
apply plugin: 'kotlin-dce-js'

repositories {
    maven { url 'http://dl.bintray.com/kotlin/kotlin-eap-1.1' }
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
}

By default, the resulting set of JavaScript files (your application together with all dependencies) can be found at build/classes/main/min/.

Configuring

To configure DCE on the main source set, you can use the runDceKotlinJs task (and corresponding runDce<sourceSetName>KotlinJs for other source sets).

Sometimes you are going to use a Kotlin declaration directly from JavaScript, and it’s being stripped out by DCE. You may want to keep this declaration. To do so, you can use the following syntax in build.gradle:

runDceKotlinJs.keep "declarationToKeep"[, "declarationToKeep", ...]

Where declarationToKeep has the following syntax:

moduleName.dot.separated.package.name.declarationName

For example, if our module is named kotlin-js-example and we have a function named toKeep in package org.jetbrains.kotlin.examples, we should use the following line:

runDceKotlinJs.keep "kotlin-js-example_main.org.jetbrains.kotlin.examples.toKeep"

Note that if your function has parameters, its name will be mangled, so the mangled name should be used in the keep directive.

Notes

  • DCE tool is an experimental feature. This does not mean we are going to remove it, or that it’s unusable for production. This means that we can change names of configuration parameters, default settings, etc.
  • Currently you should not use DCE tool if your project is a shared library. It’s only applicable when you are developing an application (which may use shared libraries). The reason is: DCE does not know which parts of the library are going to be used by the user’s application.
  • DCE does not perform minification (uglification) of your code by removing unnecessary whitespaces and shortening identifiers. You should use existing tools, like UglifyJS (https://github.com/mishoo/UglifyJS2) or Google Closure Compiler (https://developers.google.com/closure/compiler/) for this purpose.
  • Full documentation and examples will be available later.

Kotlin 1.1.4 EAP
Kotlin 1.1.4 EAP
#2

Looks like this tool works by processing compileKotlin2Js output + kotlin.js into “min” sub folder which is a nice bonus, no need to copy kotlin.js manually anymore.

If anybody tried using it as cli tool I would recommend using plugin instead, it is plain simpler, and works ok, no need to build kotlin sdk etc.

Also it is really efficient (or kotlin.js stdlib really not efficient :slight_smile: ) With 60kloc kotlin (js target part) project it reduces kotlin.js from 1.2MB down to 247kb. No bugs encountered everything is still working.

It is hard to understand how kotlin gradle plugin is working btw, I was not able to deduce any options if any for runDceKotlinJs task by looking at code.


#3

Man, this plugin is really nice! Like said before there is no need to copy the dependency files. You just need to configure a bundler like webpack to create a bundle using the min directory.

Nice work, guys!


#4

BTW, here’s an example of using DCE with webpack: https://github.com/JetBrains/kotlin-examples/tree/master/gradle/js-dce

I’ll give a link to this example on kotlinlang.org as soon as we release 1.1.4


#5

Nice!


#6

I’m using this, but I realized that apply plugin: 'kotlin-dce-js' is all that’s needed for the plugin to run.

No need to add runDceKotlinJs to any configuration.

My problem is now I’ld like to turn off dce for the test-sources, is that possible?


#7

Is it possible to generate source maps with kotlin-dce-js plugin?


#8

Currently, DCE does not support source maps, but it’s planned to support them soon, see KT-19821