Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Javascript module with Duktape in Android

I am successfully parsing and evaluating a javascript file with Duktape in my Android application using Kotlin.

val file_name = "lib.js"

val js_string = application.assets.open(file_name).bufferedReader().use {
  it.readText()
}


val duktape = Duktape.create()

try {
  Log.d("Greeting", duktape.evaluate("'hello world'.toUpperCase();").toString())
  duktape.evaluate(js_string)

} finally {
  duktape.close()
}

The javascript file was created with Browserify, so it is one single file with everything and it is working fine. But I need to request a module and a method from the module, example:

var test = require('testjs-lib');
test.EVPair.makeRandom().toWTF();

I have no idea of how to do it and have not found any example, besides this link: http://wiki.duktape.org/HowtoModules.html

It tells me to use a modsearch, but I don't have a clue how to do it or where it should be placed, not even if it is applicable for the Duktape Android (https://github.com/square/duktape-android).

Has anybody done it successfully that could shed some light on this matter?

like image 894
erickva Avatar asked Apr 16 '18 07:04

erickva


2 Answers

in the testjs-lib.js, add the JS code that makes use of the module testjs-lib.js itself exports. For example:

function myModule() {
  this.hello = function() {
    return 'hello!';
  }

  this.goodbye = function() {
    return 'goodbye!';
  }
}

module.exports = myModule;

//You code goes here
console.log(myModule.hello());
console.log(myModule.goodbye());

Then ask Duktape to evaluate the entire file.

like image 91
Alexandre Andrade Avatar answered Nov 20 '22 01:11

Alexandre Andrade


Say you want to include Underscore in duktape.

  1. Put your module/library code in a separate js file. In an android project, you can put this js file in Assets folder. In our example, it'd be sth like: underscore.js

  2. Create a java interface that'd be used by duktape to get inputstream to this js file. Sth like:

```

public interface DuktapeHelper {

    @JavascriptInterface
    String getUnderScore();
}

````

  1. Bind this java interface to a js interface in your duktape instance.

```

duktape.bind("helper", DuktapeHelper.class, <instance of your DuktapeHelperImplementation>);

```

  1. Implment modSearch function in duktape using helper interface that you injected before.

```

 duktape.evaluate("Duktape.modSearch = function (id) {\n" +
                    "  if (id == \"underscore\") {" +
                    "  return helper.getUnderScore();" +
                    "  } " +
                    "   throw new Error('cannot find module: ' + id);" +
                    "  };" +
                "var _ = require('underscore')._; ");

```

like image 2
Yash Avatar answered Nov 20 '22 02:11

Yash