JavaScript Support: Difference between revisions
Added more docs |
|||
Line 10: | Line 10: | ||
* If you want Mafia to run your <code>main</code> function, you '''<u>must</u>''' export it by adding it to module.exports, just as you would for a Node module. For the uninitiated, this just means adding <code>module.exports.main = main</code> to the end of your script. You will want to do the same with any function or value you want to be available to other scripts via require. | * If you want Mafia to run your <code>main</code> function, you '''<u>must</u>''' export it by adding it to module.exports, just as you would for a Node module. For the uninitiated, this just means adding <code>module.exports.main = main</code> to the end of your script. You will want to do the same with any function or value you want to be available to other scripts via require. | ||
== | == JavaScript Version and Features == | ||
Folks with experience doing | KoLmafia uses the [[wikipedia:Rhino (JavaScript engine)|Rhino]] engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia. | ||
Here is an incomplete list of features supported by Rhino ([https://kolmafia.us/threads/javascript-bugs.25638/post-160384 source]): | |||
=== Supported === | |||
* Syntax | |||
** <code>let</code> and (partially) <code>const</code> | |||
*** Does not support block-level scoping or temporal dead zones, meaning that you cannot use <code>const</code> for loop variables. <code>for (const a in obj) { ... }</code> is a syntax error. | |||
** Array/object destructuring (but spread/rest syntax (<code>...</code>) is ''not'' supported) | |||
** <code>for...of</code> loop | |||
** Arrow functions: <code>() => {}</code> | |||
** Octal and binary literals | |||
* Features | |||
** Symbol | |||
** Set, Map, WeakSet, WeakMap | |||
** ES2015 methods in Array, Math, Number, Object, String | |||
** <code>Array.prototype.includes()</code> | |||
** <code>String.prototype.padStart()/padEnd()/trimStart()/trimEnd()</code> | |||
** TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable. | |||
=== Unsupported === | |||
* Syntax | |||
** Spread/rest syntax (<code>...</code>) | |||
** Template string literals: Backtick string literals (<code>``</code>) are not a syntax error, but are treated as plain string literals. | |||
** Classes | |||
** Default function parameters | |||
** Computed property names | |||
** Async/Await | |||
** Trailing commas in function definitions (oddly, trailing commas are supported in function ''calls'') | |||
* Features | |||
** Promise | |||
** Proxy | |||
** Reflect | |||
=== Other === | |||
Most JavaScript globals available in browsers and/or server-side environments like Node.js are ''not'' available. This includes <code>alert()</code>, <code>console.log()</code>, and <code>setTimeout()</code>. | |||
== Transpiling == | |||
Folks with experience doing JavaScript web development are likely well-acquainted with tools such as Babel, Webpack, and TypeScript. These tools allow you to write modern JavaScript code. and can transpile the code down to an older version of JS supported by a particular engine. That approach works well with Rhino. | |||
* Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package. | |||
* TypeScript: If you use Babel without TypeScript, setting the [https://www.typescriptlang.org/tsconfig#target target] to <samp>"ES5"</samp> will usually work. |
Revision as of 11:13, 20 December 2020
As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using js <code>
, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. betweenBattleScript
) are supported as well as of revision 20519. This support is still experimental - you have been warned.
Basics
- All the methods in the ASH runtime library are available, with names of methods converted to camelCase. So, for example,
print_html
in ASH becomesprintHtml
in JS. - In scripts called from a file, you can access the runtime library by calling
require("kolmafia")
, soconst { printHtml } = require("kolmafia")
. If running from the command line viajs
, the runtime library functions are all available in the global scope (so you can dojs print("Hello world!");
). - ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.
- You can look at the type reference for the JS version of the ASH runtime library with
jsref
, which works just likeashref
. - Objects like monsters and items can be constructed via the
Monster
andItem
global objects, along with the rest of ASH's enumerated types (stat, phylum, location, etc.).Monster.get
takes a number or a string, just like$monster
in ASH, or an array of numbers and strings to construct an array of monsters.Monster.all
works like$monsters[]
in ASH; it takes no arguments and returns an array of all monsters. - Mafia supports
require
for both ASH and JS scripts. For ASH scripts, it will execute top-level code but only export functions, not variables, in the top scope. - If you want Mafia to run your
main
function, you must export it by adding it to module.exports, just as you would for a Node module. For the uninitiated, this just means addingmodule.exports.main = main
to the end of your script. You will want to do the same with any function or value you want to be available to other scripts via require.
JavaScript Version and Features
KoLmafia uses the Rhino engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia.
Here is an incomplete list of features supported by Rhino (source):
Supported
- Syntax
let
and (partially)const
- Does not support block-level scoping or temporal dead zones, meaning that you cannot use
const
for loop variables.for (const a in obj) { ... }
is a syntax error.
- Does not support block-level scoping or temporal dead zones, meaning that you cannot use
- Array/object destructuring (but spread/rest syntax (
...
) is not supported) for...of
loop- Arrow functions:
() => {}
- Octal and binary literals
- Features
- Symbol
- Set, Map, WeakSet, WeakMap
- ES2015 methods in Array, Math, Number, Object, String
Array.prototype.includes()
String.prototype.padStart()/padEnd()/trimStart()/trimEnd()
- TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable.
Unsupported
- Syntax
- Spread/rest syntax (
...
) - Template string literals: Backtick string literals (
``
) are not a syntax error, but are treated as plain string literals. - Classes
- Default function parameters
- Computed property names
- Async/Await
- Trailing commas in function definitions (oddly, trailing commas are supported in function calls)
- Spread/rest syntax (
- Features
- Promise
- Proxy
- Reflect
Other
Most JavaScript globals available in browsers and/or server-side environments like Node.js are not available. This includes alert()
, console.log()
, and setTimeout()
.
Transpiling
Folks with experience doing JavaScript web development are likely well-acquainted with tools such as Babel, Webpack, and TypeScript. These tools allow you to write modern JavaScript code. and can transpile the code down to an older version of JS supported by a particular engine. That approach works well with Rhino.
- Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [1] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.
- TypeScript: If you use Babel without TypeScript, setting the target to "ES5" will usually work.