Package: dukpy
DukPy is a simple javascript interpreter for Python built on top of
duktape enginewithout any external dependency.
It comes with a bunch of common transpilers built-in for convenience:CoffeeScriptBabelJSTypeScriptJSXLESSCoffeeScript CompilerUsing the coffeescript compiler is as easy as running:>>>importdukpy>>>dukpy.coffee_compile('''
...     fill = (container, liquid = "coffee") ->
...         "Filling the #{container}with #{liquid}..."
... ''')'(function() {\nvar fill;\n\nfill = function*(container, liquid) {\nif (liquid == null) {\nliquid = "coffee";\n}\nreturn "Filling the " + container + " with " + liquid + "...";\n};\n\n}).call(this);\n'TypeScript TranspilerThe TypeScript compiler can be used through thedukpy.typescript_compilefunction:>>>importdukpy>>>dukpy.typescript_compile('''
... class Greeter {
...     constructor(public greeting: string) { }
...     greet() {
...         return "<h1>" + this.greeting + "</h1>";
...     }
... };
...
... var greeter = new Greeter("Hello, world!");
... ''')'var Greeter = (function () {\nfunction Greeter(greeting) {\nthis.greeting = greeting;\n}\nGreeter.prototype.greet = function () {\nreturn "<h1>" + this.greeting + "</h1>";\n};\nreturn Greeter;\n})();\n;\nvar greeter = new Greeter("Hello, world!");\n'Currently the compiler has built-in options and doesn’t accept additional ones,The DukPY based TypeScript compiler also provides a WebAssets (http://webassets.readthedocs.org/en/latest/) filter to automatically
compile TypeScript code in your assets pipeline.  You register this filter astypescriptwithin WebAssets using:fromwebassets.filterimportregister_filterfromdukpy.webassetsimportTypeScriptregister_filter(TypeScript)Which makes the filter available with thetypescriptname.NOTE:When using the TypeScript compiler for code that needs to run
in the browser, make sure to addhttps://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.24/system.jsdependency. Asimportstatements are resolved using SystemJS.EcmaScript6 BabelJS TranspilerTo compile ES6 code to ES5 for everyday usage you can usedukpy.babel_compile:>>>importdukpy>>>dukpy.babel_compile('''
... class Point {
...     constructor(x, y) {
...             this.x = x;
...         this.y = y;
...         }
...         toString() {
...             return '(' + this.x + ', ' + this.y + ')';
...         }
... }
... ''')'"use strict";\n\nvar _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };\n\nvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };\n\nvar Point = (function () {\nfunction Point(x, y) {\n_classCallCheck(this, Point);\n\nthis.x = x;\nthis.y = y;\n}\n\n_prototypeProperties(Point, null, {\ntoString: {\nvalue: function toString() {\nreturn "(" + this.x + ", " + this.y + ")";\n},\nwritable: true,\nconfigurable: true\n}\n});\n\nreturn Point;\n})();\n'You  can passoptionsto the BabelJS compiler just as keywords on
the call tobabel_compile().The DukPY based BabelJS compiler also provides a WebAssets (http://webassets.readthedocs.org/en/latest/) filter to automatically
compile ES6 code in your assets pipeline.  You register this filter asbabeljswithin WebAssets using:fromwebassets.filterimportregister_filterfromdukpy.webassetsimportBabelJSregister_filter(BabelJS)Which makes the filter available with thebabeljsname.
Only supported filter option is currentlyBABEL_MODULES_LOADERwith valuesystemjsorumdto specify that compiled code should use SystemJS
or UMD instead of CommonJS for modules.NOTE:When using the BabelJS compiler for code that needs to run
in the browser, make sure to addhttps://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.26.0/polyfill.min.jsdependency.JSX to React TranspilingDukPy provides a built-in compiler from JSX to React, this is available asdukpy.jsx_compile:>>>importdukpy>>>dukpy.jsx_compile('var react_hello = <h1>Hello, world!</h1>;')u'"use strict";\n\nvar react_hello = React.createElement(\n"h1",\nnull,\n"Hello, world!"\n);'The DukPY based JSX compiler also provides a WebAssets (http://webassets.readthedocs.org/en/latest/) filter to automatically
compile JSX+ES6 code in your assets pipeline.  You register this filter asbabeljsxwithin WebAssets using:fromwebassets.filterimportregister_filterfromdukpy.webassetsimportBabelJSXregister_filter(BabelJSX)Which makes the filter available with thebabeljsxname.
This filter supports the same options as the babel one.Less TranspilingDukPy provides a built-in distribution of the less compiler available
throughdukpy.less_compile:>>>importdukpy>>>dukpy.less_compile('.class { width: (1 + 1) }')'.class {\nwidth: 2;\n}\n'The DukPY based LESS compiler also provides a WebAssets (http://webassets.readthedocs.org/en/latest/) filter to automatically
compile LESS code in your assets pipeline.  You register this filter aslesscwithin WebAssets using:fromwebassets.filterimportregister_filterfromdukpy.webassetsimportCompileLessregister_filter(CompileLess)Which makes the filter available with thelesscname.Using the JavaScript InterpreterUsing dukpy is as simple as calling thedukpy.evaljsfunction with
the javascript code:>>>importdukpy>>>dukpy.evaljs("var o = {'value': 5}; o['value'] += 3; o"){'value':8}Theevaljsfunction executes the javascript and returns the
resulting value as far as it is possible to encode it in JSON.If execution fails adukpy.JSRuntimeErrorexception is raised
with the failure reason.Passing ArgumentsAny argument passed toevaljsis available in JavaScript inside
thedukpyobject in javascript. It must be possible to encode
the arguments using JSON for them to be available in Javascript:>>>importdukpy>>>>>>defsum3(value):...returndukpy.evaljs("dukpy['value'] + 3",value=value)...>>>sum3(7)10Running Multiple ScriptsTheevaljsfunction supports providing multiple source codes to
be executed in the same context.Multiple script can be passed in a list or tuple:>>>importdukpy>>>dukpy.evaljs(["var o = {'value': 5}",..."o['value'] += 3",..."o"]){'value':8}This is useful when your code requires dependencies to work,
as you can load the dependency and then your code.This is actually how the coffeescript compiler is implemented
by DukPy itself:defcoffee_compile(source):withopen(COFFEE_COMPILER,'r')ascoffeescript_js:returnevaljs((coffeescript_js.read(),'CoffeeScript.compile(dukpy.coffeecode)'),coffeecode=source)Using a persistent JavaScript InterpreterTheevaljsfunction creates a new interpreter on each call,
this is usually convenient and avoid errors due to dirt global variables
or unexpected execution status.In some cases you might want to run code that has a slow bootstrap, so
it’s convenient to reuse the same interpreter between two different calls
so that the bootstrap cost has already been paid during the first execution.This can be achieved by using thedukpy.JSInterpreterobject.Creating adukpy.JSInterpreterpermits to evaluate code inside that interpreter
and multipleevalcalls will share the same interpreter and global status:>>>importdukpy>>>interpreter=dukpy.JSInterpreter()>>>interpreter.evaljs("var o = {'value': 5}; o"){u'value':5}>>>interpreter.evaljs("o.value += 1; o"){u'value':6}Loading modules with requireWhen using thedukpy.JSInterpreterobject it is possible to use
therequire('modulename')instruction to load a module inside javascript.Modules are looked up in all directories registered withdukpy.JSInterpreter.loader.register_path:>>>importdukpy>>>jsi=dukpy.JSInterpreter()>>>jsi.loader.register_path('./js_modules')>>>jsi.evaljs("isEmpty = require('fbjs/lib/isEmpty'); isEmpty([1])")FalseInstalling packages from npmjs.orgWhen using the persistent javascript interpreter it is also possible to install packages
fromnpmjs.orgthrough thedukpy.install_jspackagefunction:>>>importdukpy>>>jsi=dukpy.JSInterpreter()>>>dukpy.install_jspackage('promise',None,'./js_modules')Packagesgoingtobeinstalled:promise->7.1.1,asap->2.0.3Fetchinghttps://registry.npmjs.org/promise/-/promise-7.1.1.tgz..........................Fetchinghttps://registry.npmjs.org/asap/-/asap-2.0.3.tgz............Installingpromisein./js_modulesDone!The same functionality is also provided by thedukpy-installshell command:$ dukpy-install -d ./js_modules promise
Packages going to be installed: promise->7.1.1, asap->2.0.3
Fetching https://registry.npmjs.org/promise/-/promise-7.1.1.tgz..........................
Fetching https://registry.npmjs.org/asap/-/asap-2.0.3.tgz............
Installing promise in ./js_modules Done!Please note that currentlyinstall_jspackageis not able to resolve conflicting
dependencies.