|
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