|
1 | 1 | # Other JS Engines and Deployments |
2 | 2 |
|
3 | | -There are many JS engines and deployments outside of web browsers. NodeJS is the |
4 | | -most popular deployment, but there are many others for special use cases. Some |
5 | | -optimize for low overhead and others optimize for ease of embedding within other |
6 | | -applications. Since it was designed for ES3 engines, the library can be used in |
7 | | -those settings! This demo tries to demonstrate a few alternative deployments. |
| 3 | +[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/engines) |
| 4 | +includes more detailed instructions and more JS engines. |
8 | 5 |
|
9 | | -Some engines provide no default global object. To create a global reference: |
10 | | - |
11 | | -```js |
12 | | -var global = (function(){ return this; }).call(null); |
13 | | -``` |
14 | | - |
15 | | - |
16 | | -## Swift + JavaScriptCore |
17 | | - |
18 | | -iOS and OSX ship with the JavaScriptCore framework for running JS scripts from |
19 | | -Swift and Objective-C. Hybrid function invocation is tricky, but explicit data |
20 | | -passing is straightforward. The demo shows a standalone example for OSX. For |
21 | | -playgrounds, the library should be copied to shared playground data directory |
22 | | -(usually `~/Documents/Shared Playground Data`): |
23 | | - |
24 | | -```swift |
25 | | -/* This only works in a playground, see SheetJSCore.swift for standalone use */ |
26 | | -import JavaScriptCore; |
27 | | -import PlaygroundSupport; |
28 | | - |
29 | | -/* build path variable for the library */ |
30 | | -let shared_dir = PlaygroundSupport.playgroundSharedDataDirectory; |
31 | | -let lib_path = shared_dir.appendingPathComponent("xlsx.full.min.js"); |
32 | | - |
33 | | -/* prepare JS context */ |
34 | | -var context: JSContext! = JSContext(); |
35 | | -var src = "var global = (function(){ return this; }).call(null);"; |
36 | | -context.evaluateScript(src); |
37 | | - |
38 | | -/* load library */ |
39 | | -var lib = try? String(contentsOf: lib_path); |
40 | | -context.evaluateScript(lib); |
41 | | -let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX"); |
42 | | - |
43 | | -/* to verify the library was loaded, get the version string */ |
44 | | -let XLSXversion: JSValue! = XLSX.objectForKeyedSubscript("version") |
45 | | -var version = XLSXversion.toString(); |
46 | | -``` |
47 | | - |
48 | | -Binary strings can be passed back and forth using `String.Encoding.isoLatin1`: |
49 | | - |
50 | | -```swift |
51 | | -/* parse sheetjs.xls */ |
52 | | -let file_path = shared_dir.appendingPathComponent("sheetjs.xls"); |
53 | | -let data: String! = try String(contentsOf: file_path, encoding: String.Encoding.isoLatin1); |
54 | | -context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)); |
55 | | -src = "var wb = XLSX.read(payload, {type:'binary'});"; |
56 | | -context.evaluateScript(src); |
57 | | - |
58 | | -/* write to sheetjsw.xlsx */ |
59 | | -let out_path = shared_dir.appendingPathComponent("sheetjsw.xlsx"); |
60 | | -src = "var out = XLSX.write(wb, {type:'binary', bookType:'xlsx'})"; |
61 | | -context.evaluateScript(src); |
62 | | -let outvalue: JSValue! = context.objectForKeyedSubscript("out"); |
63 | | -var out: String! = outvalue.toString(); |
64 | | -try? out.write(to: out_path, atomically: false, encoding: String.Encoding.isoLatin1); |
65 | | -``` |
66 | | - |
67 | | - |
68 | | -## Nashorn |
69 | | - |
70 | | -Nashorn ships with Java 8. It includes a command-line tool `jjs` for running JS |
71 | | -scripts. It is somewhat limited but does offer access to the full Java runtime. |
72 | | - |
73 | | -The `load` function in `jjs` can load the minified source directly: |
74 | | - |
75 | | -```js |
76 | | -var global = (function(){ return this; }).call(null); |
77 | | -load('xlsx.full.min.js'); |
78 | | -``` |
79 | | - |
80 | | -The Java `nio` API provides the `Files.readAllBytes` method to read a file into |
81 | | -a byte array. To use in `XLSX.read`, the demo copies the bytes into a plain JS |
82 | | -array and calls `XLSX.read` with type `"array"`. |
83 | | - |
84 | | - |
85 | | -## Rhino |
86 | | - |
87 | | -[Rhino](http://www.mozilla.org/rhino) is an ES3+ engine written in Java. The |
88 | | -`SheetJSRhino` class and `com.sheetjs` package show a complete JAR deployment, |
89 | | -including the full XLSX source. |
90 | | - |
91 | | -Due to code generation errors, optimization must be turned off: |
92 | | - |
93 | | -```java |
94 | | -Context context = Context.enter(); |
95 | | -context.setOptimizationLevel(-1); |
96 | | -``` |
97 | | - |
98 | | - |
99 | | -## ChakraCore |
100 | | - |
101 | | -ChakraCore is an embeddable JS engine written in C++. The library and binary |
102 | | -distributions include a command-line tool `chakra` for running JS scripts. |
103 | | - |
104 | | -The simplest way to interact with the engine is to pass Base64 strings. The make |
105 | | -target builds a very simple payload with the data. |
106 | | - |
107 | | - |
108 | | -## Duktape |
109 | | - |
110 | | -[Duktape](http://duktape.org/) is an embeddable JS engine written in C. The |
111 | | -amalgamation makes integration extremely simple! It supports `Buffer` natively |
112 | | -but should be sliced before processing: |
113 | | - |
114 | | -```C |
115 | | -/* parse a C char array as a workbook object */ |
116 | | -duk_push_external_buffer(ctx); |
117 | | -duk_config_buffer(ctx, -1, buf, len); |
118 | | -duk_put_global_string(ctx, "buf"); |
119 | | -duk_eval_string_noresult("workbook = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});"); |
120 | | - |
121 | | -/* write a workbook object to a C char array */ |
122 | | -duk_eval_string(ctx, "XLSX.write(workbook, {type:'array', bookType:'xlsx'})"); |
123 | | -duk_size_t sz; |
124 | | -char *buf = (char *)duk_get_buffer_data(ctx, -1, sz); |
125 | | -duk_pop(ctx); |
126 | | -``` |
127 | | -
|
128 | | -
|
129 | | -## QuickJS |
130 | | -
|
131 | | -QuickJS is an embeddable JS engine written in C. It provides a separate set of |
132 | | -functions for interacting with the filesystem and the global object. It can run |
133 | | -the browser dist build. |
134 | | -
|
135 | | -The `global` object is available as `std.global`. To make it visible to the |
136 | | -loader, create a reference to itself: |
137 | | -
|
138 | | -```js |
139 | | -std.global.global = std.global; |
140 | | -std.loadScript("xlsx.full.min.js"); |
141 | | -``` |
142 | | - |
143 | | -The filesystem interaction mirrors POSIX, including separate allocations: |
144 | | - |
145 | | -```js |
146 | | -/* read file */ |
147 | | -var rh = std.open(filename, "rb"); rh.seek(0, std.SEEK_END); |
148 | | -var sz = rh.tell(); rh.seek(); |
149 | | -var ab = new ArrayBuffer(sz); rh.read(ab, 0, sz); rh.close(); |
150 | | -var wb = XLSX.read(ab, {type: 'array'}); |
151 | | - |
152 | | -/* write file */ |
153 | | -var ab = XLSX.write(wb, {type: 'array'}); |
154 | | -var wh = std.open("sheetjs.qjs.xlsx", "wb"); |
155 | | -wh.write(out, 0, ab.byteLength); wh.close(); |
156 | | -``` |
157 | | - |
158 | | - |
159 | | -## Goja |
160 | | - |
161 | | -Goja is a pure Go implementation of ECMAScript 5. `[]byte` should be converted |
162 | | -to a binary string in the engine: |
163 | | - |
164 | | -```go |
165 | | -/* read file */ |
166 | | -data, _ := ioutil.ReadFile("sheetjs.xlsx") |
167 | | - |
168 | | -/* load into engine */ |
169 | | -vm.Set("buf", data) |
170 | | - |
171 | | -/* convert to binary string */ |
172 | | -_, _ = vm.RunString("var bstr = ''; for(var i = 0; i < buf.length; ++i) bstr += String.fromCharCode(buf[i]);") |
173 | | - |
174 | | -/* parse */ |
175 | | -wb, _ = vm.RunString("wb = XLSX.read(bstr, {type:'binary', cellNF:true});") |
176 | | -``` |
177 | | - |
178 | | -On the write side, `"base64"` strings can be decoded in Go: |
179 | | - |
180 | | -```go |
181 | | -b64str, _ := vm.RunString("XLSX.write(wb, {type:'base64', bookType:'xlsx'})") |
182 | | -buf, _ := base64.StdEncoding.DecodeString(b64str.String()) |
183 | | -_ = ioutil.WriteFile("sheetjs.xlsx", buf, 0644) |
184 | | -``` |
185 | 6 |
|
186 | 7 | [](https://github.com/SheetJS/js-xlsx) |
0 commit comments