From aeb932e1d0b073a58b16d0ac389f96991c05b3b1 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Sat, 21 Oct 2023 07:15:28 -0400 Subject: [PATCH] esbuild-plugin --- .../01-frontend/19-bundler/04-esbuild.md | 9 +- .../01-frontend/19-bundler/09-browserify.md | 151 ++++++++ .../01-frontend/19-bundler/21-swcpack.md | 186 +++++++++ .../03-demos/01-frontend/19-bundler/index.md | 212 +--------- docz/docs/03-demos/04-static/04-esbuild.md | 361 ++++++++++++++++++ docz/docs/03-demos/42-engines/02-v8.md | 2 +- docz/docs/03-demos/42-engines/21-boa.md | 2 +- docz/docs/03-demos/42-engines/index.md | 2 + 8 files changed, 715 insertions(+), 210 deletions(-) create mode 100644 docz/docs/03-demos/01-frontend/19-bundler/09-browserify.md create mode 100644 docz/docs/03-demos/01-frontend/19-bundler/21-swcpack.md create mode 100644 docz/docs/03-demos/04-static/04-esbuild.md diff --git a/docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md b/docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md index 2cc331c..4718025 100644 --- a/docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md +++ b/docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md @@ -25,7 +25,7 @@ bundle with ESBuild for browser use. - ["NodeJS"](#nodejs) explores how to import SheetJS libraries in a script and bundle with ESBuild for NodeJS use. -:::info pass +:::note pass This demo focuses on integration details with the ESBuild bundler. @@ -34,6 +34,13 @@ The tutorial covers SheetJS library usage. ::: +:::info pass + +The [ESBuild section of the Content demo](/docs/demos/static/esbuild) covers +loaders. They are ideal for static sites pulling data from sheets at build time. + +::: + :::note This demo was last tested on 2023 October 19 against esbuild `0.19.5` diff --git a/docz/docs/03-demos/01-frontend/19-bundler/09-browserify.md b/docz/docs/03-demos/01-frontend/19-bundler/09-browserify.md new file mode 100644 index 0000000..978289e --- /dev/null +++ b/docz/docs/03-demos/01-frontend/19-bundler/09-browserify.md @@ -0,0 +1,151 @@ +--- +title: Bundling Sheets with Browserify +sidebar_label: Browserify +pagination_prev: demos/index +pagination_next: demos/grid/index +sidebar_position: 9 +--- + +import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + +[Browserify](https://browserify.org/) is a module bundler. + +[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing +data from spreadsheets. + +This demo uses Browserify and SheetJS to export data. We'll explore how to add +SheetJS to a site using Browserify and how to export data to spreadsheets. + +:::note + +This demo was last tested on 2023 October 21 against Browserify `17.0.0` + +::: + +## Integration Details + +[The "Frameworks" section](/docs/getting-started/installation/frameworks) covers +installation with Yarn and other package managers. + +After installing the SheetJS module in a Browserify project, `require` +expressions can load relevant parts of the library. + +```js +var XLSX = require("xlsx"); +// ... use XLSX ... +``` + +Browserify can also process `require` expressions in Web Worker scripts. + +## Complete Example + +0) Initialize a new project: + +```bash +mkdir sheetjs-browserify +cd sheetjs-browserify +npm init -y +``` + +1) Install the tarball using a package manager: + + + +{`\ +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} + + + +{`\ +pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} + + + +{`\ +yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} + + + + +2) Save the following to `index.js`: + +```js title="index.js" +// highlight-next-line +const { utils, version, writeFileXLSX } = require('xlsx'); + +document.getElementById("xport").addEventListener("click", function() { + /* fetch JSON data and parse */ + var url = "https://sheetjs.com/data/executive.json"; + fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) { + + /* filter for the Presidents */ + var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); }); + + /* sort by first presidential term */ + prez.forEach(function(row) { + row.start = row.terms.find(function(term) { + return term.type === "prez"; + }).start + }); + prez.sort(function(l,r) { return l.start.localeCompare(r.start); }); + + /* flatten objects */ + var rows = prez.map(function(row) { return { + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday + }; }); + + /* generate worksheet and workbook */ + var worksheet = utils.json_to_sheet(rows); + var workbook = utils.book_new(); + utils.book_append_sheet(workbook, worksheet, "Dates"); + + /* fix headers */ + utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + + /* calculate column width */ + var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10); + worksheet["!cols"] = [ { wch: max_width } ]; + + /* create an XLSX file and try to save to Presidents.xlsx */ + writeFileXLSX(workbook, "Presidents.xlsx"); + }); +}); +``` + +3) Bundle the scripts: + +```bash +npx browserify app.js > browserify.js +``` + +4) Spin up a local web server: + +```bash +npx http-server +``` + +5) Create a small HTML page that loads the script. Save to `index.html`: + +```html title="index.html" + + + + +

SheetJS Presidents Demo

+ + + + +``` + +6) Start a local HTTP server and go to `http://localhost:8080/` + +```bash +npx http-server . +``` + +Click on "Click here to export" to generate a file. diff --git a/docz/docs/03-demos/01-frontend/19-bundler/21-swcpack.md b/docz/docs/03-demos/01-frontend/19-bundler/21-swcpack.md new file mode 100644 index 0000000..486c344 --- /dev/null +++ b/docz/docs/03-demos/01-frontend/19-bundler/21-swcpack.md @@ -0,0 +1,186 @@ +--- +title: Bundling Sheets with SWC +sidebar_label: SWC spack +pagination_prev: demos/index +pagination_next: demos/grid/index +sidebar_position: 21 +--- + +import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + +SWC[^1] is a JS toolchain. SWC provides `spack` (formally called "swcpack") for +bundling scripts. + +[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing +data from spreadsheets. + +This demo uses `spack` and SheetJS to export data. We'll explore how to bundle +SheetJS in a site using `spack` and how to export data to spreadsheets. + +:::note + +This demo was last tested on 2023 October 20 against SWC 1.2.246 + +::: + +## Integration Details + +[The "Frameworks" section](/docs/getting-started/installation/frameworks) covers +installation with Yarn and other package managers. + +After installing the SheetJS module in a SWC `spack` project, `import` +statements can load relevant parts of the library. + +Projects that import data will use methods such as `read`[^2] to parse workbooks +and `sheet_to_json`[^3] to generate usable data from files. As `sheet_to_json` +is part of the `utils` object, the required import is: + +```js +import { read, utils } from 'xlsx'; +``` + +Projects that export data will use methods such as `json_to_sheet`[^4] to +generate worksheets and `writeFile`[^5] to export files. As `json_to_sheet` is +part of the `utils` object, the required import is: + +```js +import { utils, writeFile } from 'xlsx'; +``` + +:::warning pass + +When this demo was tested against the latest version, `spack` crashed: + +``` +thread '' panicked at 'cannot access a scoped thread local variable without calling `set` first', +``` + +Until the bug is fixed, it is strongly recommended to use `@swc/core@1.2.246`. + +::: + +## Complete Example + +0) Initialize a new project: + +```bash +mkdir sheetjs-spack +cd sheetjs-spack +npm init -y +``` + +1) Install the dependencies using a package manager: + + + +{`\ +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246 + + + +{`\ +pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246 + + + +{`\ +yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246 + + + + +:::note pass + +The `regenerator-runtime` dependency is used for transpiling `fetch` and is not +required if the interface code does not use `fetch` or Promises. + +::: + +2) Save the following to `index.js`: + +```js title="index.js" +import { utils, version, writeFileXLSX } from 'xlsx'; + +document.getElementById("xport").addEventListener("click", async() => { +/* fetch JSON data and parse */ +const url = "https://sheetjs.com/data/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +writeFileXLSX(workbook, "Presidents.xlsx"); +}); +``` + +3) Create an `spack.config.js` config file: + +```js title="spack.config.js" +module.exports = ({ + entry: { + 'web': __dirname + '/index.js', + }, + output: { + path: __dirname + '/lib' + }, + module: {}, +}); +``` + +4) Build for production: + +```bash +npx spack +``` + +This command will create the script `lib/web.js` + +5) Create a small HTML page that loads the generated script: + +```html title="index.html" + + + + +

SheetJS Presidents Demo

+ + + + +``` + +6) Start a local HTTP server, then go to `http://localhost:8080/` + +```bash +npx http-server +``` + +Click on "Click here to export" to generate a file. + +[^1]: See ["Bundling Configuration"](https://swc.rs/docs/configuration/bundling) in the SWC documentation for more details. +[^2]: See [`read` in "Reading Files"](/docs/api/parse-options) +[^3]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) +[^4]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input) +[^5]: See [`writeFile` in "Writing Files"](/docs/api/write-options) \ No newline at end of file diff --git a/docz/docs/03-demos/01-frontend/19-bundler/index.md b/docz/docs/03-demos/01-frontend/19-bundler/index.md index d6e9d0c..b309cc3 100644 --- a/docz/docs/03-demos/01-frontend/19-bundler/index.md +++ b/docz/docs/03-demos/01-frontend/19-bundler/index.md @@ -35,84 +35,9 @@ The following tools are covered in separate pages: ); })} -## Browserify - -`browserify` is compatible with the library and should "just work" with the -`require` form in a main page or in a web worker: - -```js -var XLSX = require("xlsx"); -// ... use XLSX ... -``` - -[After installing the NodeJS module](/docs/getting-started/installation/nodejs), -bundling is straightforward: - -```bash -browserify app.js > browserify.js -uglifyjs browserify.js > browserify.min.js -``` - -Web Worker scripts can be bundled using the same approach. - -
Complete Example (click to show) - -:::note - -This demo was last tested on 2023 May 07 against Browserify `17.0.0` - -::: - -1) Install the tarball using a package manager: - - - -{`\ -npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} - - - -{`\ -pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} - - - -{`\ -yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} - - - - -2) Download the following files: - -- [`app.js`](pathname:///browserify/app.js) -- [`index.html`](pathname:///browserify/index.html) -- [`xlsxworker.js`](pathname:///browserify/xlsxworker.js) - -```bash -curl -LO https://docs.sheetjs.com/browserify/app.js -curl -LO https://docs.sheetjs.com/browserify/index.html -curl -LO https://docs.sheetjs.com/browserify/xlsxworker.js -``` - -3) Bundle the scripts: - -```bash -npx browserify app.js > browserify.js -npx browserify xlsxworker.js > worker.js -``` - -4) Spin up a local web server: - -```bash -npx http-server -``` - -5) Access the site `http://localhost:8080/` and use the file input element to -select a spreadsheet. - -
+#### Browserify +**[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/browserify)** ## Bun @@ -312,7 +237,7 @@ click the "Click to Export!" button to generate a file. -## RequireJS +#### RequireJS **[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/requirejs)** @@ -405,7 +330,6 @@ npx rollup index.js --plugin @rollup/plugin-node-resolve --file bundle.js --form ``` - 5) Start a local HTTP server, then go to `http://localhost:8080/` ```bash @@ -521,135 +445,9 @@ Click on "Click here to export" to generate a file. -## SWC +#### SWC -SWC provides `spack` for bundling scripts. - -:::warning pass - -When this demo was last tested, there was a bug affecting 1.2.247 and 1.3 . It -is strongly recommended to use `@swc/core@1.2.245` until the bug is fixed. - -::: - -
Complete Example (click to show) - -:::note - -This demo was last tested on 2023 May 07 against SWC 1.2.246 - -::: - -1) Install the dependencies using a package manager: - - - -{`\ -npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246 - - - -{`\ -pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246 - - - -{`\ -yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246 - - - - -:::note pass - -The `regenerator-runtime` dependency is used for transpiling `fetch` and is not -required if the interface code does not use `fetch` or Promises. - -::: - -2) Save the following to `index.js`: - -```js title="index.js" -import { utils, version, writeFileXLSX } from 'xlsx'; - -document.getElementById("xport").addEventListener("click", async() => { -/* fetch JSON data and parse */ -const url = "https://sheetjs.com/data/executive.json"; -const raw_data = await (await fetch(url)).json(); - -/* filter for the Presidents */ -const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); - -/* flatten objects */ -const rows = prez.map(row => ({ - name: row.name.first + " " + row.name.last, - birthday: row.bio.birthday -})); - -/* generate worksheet and workbook */ -const worksheet = utils.json_to_sheet(rows); -const workbook = utils.book_new(); -utils.book_append_sheet(workbook, worksheet, "Dates"); - -/* fix headers */ -utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); - -/* calculate column width */ -const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); -worksheet["!cols"] = [ { wch: max_width } ]; - -/* create an XLSX file and try to save to Presidents.xlsx */ -writeFileXLSX(workbook, "Presidents.xlsx"); -}); -``` - -3) Create an `spack.config.js` config file: - -```js title="spack.config.js" -const { config } = require('@swc/core/spack'); - -module.exports = ({ - entry: { - 'web': __dirname + '/index.js', - }, - output: { - path: __dirname + '/lib' - }, - module: {}, -}); -``` - -4) Build for production: - -```bash -npx spack -``` - -This command will create the script `lib/web.js` - -5) Create a small HTML page that loads the generated script: - -```html title="index.html" - - - - -

SheetJS Presidents Demo

- - - - -``` - -6) Start a local HTTP server, then go to `http://localhost:8080/` - -```bash -npx http-server -``` - -Click on "Click here to export" to generate a file. - -
+**[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/swcpack)** #### SystemJS diff --git a/docz/docs/03-demos/04-static/04-esbuild.md b/docz/docs/03-demos/04-static/04-esbuild.md new file mode 100644 index 0000000..5814d32 --- /dev/null +++ b/docz/docs/03-demos/04-static/04-esbuild.md @@ -0,0 +1,361 @@ +--- +title: Building Sheets with ESBuild +sidebar_label: ESBuild +pagination_prev: demos/net/index +pagination_next: demos/mobile/index +sidebar_custom_props: + type: bundler +--- + +import current from '/version.js'; +import CodeBlock from '@theme/CodeBlock'; + +[ESBuild](https://esbuild.github.io/) is a modern build tool for generating +static sites. It has a robust JavaScript-powered plugin system[^1] + +[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing +data from spreadsheets. + +This demo uses ESBuild and SheetJS to pull data from a spreadsheet and display +the content in an HTML table. We'll explore how to load SheetJS in a ESBuild +loader and generate data for use in webpages. + +The ["Demo"](#demo) creates a complete website powered by a XLSX spreadsheet. + +:::info pass + +This demo covers static asset imports. For processing files in the browser, the +["Bundlers" demo](/docs/demos/frontend/bundler/esbuild) includes an example of +importing the SheetJS library in a browser script. + +::: + +## ESBuild Loader + +ESBuild supports custom loader plugins. The loader receives an absolute path to +the spreadsheet on the filesystem. + +The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be +imported from ESBuild loader plugins. + +:::info pass + +ESBuild loader plugins use ECMAScript Modules. The plugin ultimately receives +raw paths to files. [`fs`](/docs/getting-started/installation/nodejs#esm-import) +must be manually imported: + +```js +import * as XLSX from 'xlsx'; + +/* load 'fs' for readFile and writeFile support */ +import * as fs from 'fs'; +XLSX.set_fs(fs); +``` + +::: + +The following diagram depicts the workbook waltz: + +```mermaid +flowchart LR + subgraph ESBuild Custom Plugin in build.mjs + file[(workbook\nfile)] + wb(((SheetJS\nWorkbook))) + aoo(array of\nobjects) + end + html{{HTML\nTABLE}} + file --> |`readFile`\n\n| wb + wb --> |`sheet_to_json`\n\n| aoo + aoo --> |app.js\nfrontend code| html +``` + +### ESBuild Config + +Plugins can be referenced in the `plugins` array of the build config object: + +```js title="build.mjs (structure)" +import * as esbuild from 'esbuild' + +// highlight-next-line +let sheetjsPlugin = { + name: 'sheetjs', + setup(build) { + // ... + } +}; + +await esbuild.build({ + entryPoints: ['app.js'], + bundle: true, + outfile: 'out.js', + // highlight-next-line + plugins: [sheetjsPlugin], +}) +``` + +### Registering File Extensions + +The `setup` method receives the build options. Handlers for custom files should +be added using `build.onLoad`. + +The first argument to `onLoad` is a configuration object. The `filter` property +is expected to be a regular expression. The following regular expression matches +NUMBERS, XLSX, XLS, and XLSB files: + +```js + const EXTS = /.(numbers|xlsx|xls|xlsb)$/; +``` + +The second argument to `onLoad` is a callback that receives an arguments object. +The `path` property of the object is the absolute path to the file. + +```js + setup(build) { + build.onLoad({ filter: EXTS }, (args) => { + const path = args.path; + // ... + }); + }, +``` + +### SheetJS Operations + +The SheetJS `readFile` method[^2] will directly read the file on the filesystem. +The return value is a SheetJS workbook object[^3]. + +The loader in this demo will parse the workbook, pull the first worksheet, and +generate an array of row objects using the `sheet_to_json` method[^4]. + +:::caution pass + +JSON does not natively support Dates! `JSON.stringify` will generate strings. + +Through a clever workaround, it is possible to encode dates separately and +recover the Date objects in the generated code module. + +::: + +```js +import * as XLSX from 'xlsx'; +import * as fs from 'fs'; +XLSX.set_fs(fs); + +/* plugin */ +let sheetjsPlugin = { + name: 'sheetjs', + setup(build) { + /* match NUMBERS, XLSX, XLS, and XLSB files */ + const EXTS = /.(numbers|xlsx|xls|xlsb)$/; + + /* this method will be called once for each referenced file */ + build.onLoad({ filter: EXTS }, (args) => { + /* parse file from filesystem */ + const wb = XLSX.readFile(args.path); + /* get first worksheet */ + const ws = wb.Sheets[wb.SheetNames[0]]; + + /* workaround for JSON limitation */ + Date.prototype.toJSON2 = Date.prototype.toJSON; + Date.prototype.toJSON = function() { return {d:this.toISOString()}; }; + + /* generate row objects */ + const data = XLSX.utils.sheet_to_json(ws); + + /* generate final module code */ + const res = JSON.stringify(data); + Date.prototype.toJSON = Date.prototype.toJSON2; + const contents = `const data = ${res}; +data.forEach(row => { + Object.keys(row).forEach(k => { + if(row[k]?.d) row[k] = new Date(row[k].d); + }) +}); +export default data;` + return { contents, loader: 'js' }; + }); + }, +}; +``` + +### Asset Imports + +Spreadsheets can be imported using the plugin. Assuming `pres.xlsx` is stored +in the same folder as the script, `./pres.xlsx` will be a data module: + +```js title="src/index.js" +import data from './pres.xlsx'; +/* `data` is an array of objects from data/pres.xlsx */ + +const elt = document.createElement('div'); +elt.innerHTML = "" + + data.map((row) => ` + + + `).join("") + +"
NameIndex
${row.Name}${row.Index}
"; +document.body.appendChild(elt); +``` + +## Demo + +:::note + +This demo was last tested on 2023 October 21 against ESBuild 0.19.5 + +::: + +### Initial Setup + +0) Create a new skeleton project: + +```bash +mkdir sheetjs-esb +cd sheetjs-esb +npm init -y +npm i --save esbuild@0.19.5 +``` + +1) Install the SheetJS NodeJS module: + +{`\ +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} + + +2) Save the following to `index.html`: + +```html title="index.html" + + + + SheetJS + ESBuild + + + + + +``` + +3) Save the following to `app.js`: + +```js title="app.js" +import data from './pres.numbers' +const elt = document.createElement('div'); +elt.innerHTML = "" + + data.map((row) => ` + + + `).join("") + +"
NameIndex
${row.Name}${row.Index}
"; +document.body.appendChild(elt); +``` + +4) Save the following to `build.mjs`: + +```js title="build.mjs" +import * as esbuild from 'esbuild' +import * as XLSX from 'xlsx'; +import * as fs from 'fs'; +XLSX.set_fs(fs); + +let sheetjsPlugin = { + name: 'sheetjs', + setup(build) { + /* match NUMBERS, XLSX, XLS, and XLSB files */ + const EXTS = /.(numbers|xlsx|xls|xlsb)$/; + + /* this method will be called once for each referenced file */ + build.onLoad({ filter: EXTS }, (args) => { + /* parse file from filesystem */ + const wb = XLSX.readFile(args.path); + /* get first worksheet */ + const ws = wb.Sheets[wb.SheetNames[0]]; + + /* workaround for JSON limitation */ + Date.prototype.toJSON2 = Date.prototype.toJSON; + Date.prototype.toJSON = function() { return {d:this.toISOString()}; }; + + /* generate row objects */ + const data = XLSX.utils.sheet_to_json(ws); + + /* generate final module code */ + const res = JSON.stringify(data); + Date.prototype.toJSON = Date.prototype.toJSON2; + const contents = `const data = ${res}; +data.forEach(row => { + Object.keys(row).forEach(k => { + if(row[k]?.d) row[k] = new Date(row[k].d); + }) +}); +export default data;` + return { contents, loader: 'js' }; + }); + }, +}; + +await esbuild.build({ + entryPoints: ['app.js'], + bundle: true, + outfile: 'out.js', + plugins: [sheetjsPlugin], +}); +``` + +5) Download and save to the project folder: + +```bash +curl -LO https://sheetjs.com/pres.numbers +``` + +### Static Site Test + +6) Build the site: + +```bash +node build.mjs +``` + +The final script will be saved to `out.js` + +7) Start a local web server to host the project folder: + +```bash +npx http-server . +``` + +The command will print a list of URLs. + +8) Open one of the URLs printed in the previous step (`http://localhost:8080`) +and confirm that the same data is displayed. + +To verify that the data was added to the page, append `out.js` to the URL +(`http://localhost:8080/out.js`) and view the source. The source will include +president names. It will not include SheetJS library references! + +In the last test, the generated source looked like the following snippet + +```js title="out.js" +(() => { + // pres.numbers + var data = [{ "Name": "Bill Clinton", "Index": 42 }, /* ... more data */]; + data.forEach((row) => { + Object.keys(row).forEach((k) => { + if (row[k]?.d) + row[k] = new Date(row[k].d); + }); + }); + var pres_default = data; + + // app.js + var elt = document.createElement("div"); + elt.innerHTML = "" + pres_default.map((row) => ` + + + `).join("") + "
NameIndex
${row.Name}${row.Index}
"; + document.body.appendChild(elt); +})(); +``` + +[^1]: See ["Plugins"](https://esbuild.github.io/plugins/) in the ESBuild documentation. +[^2]: See [`readFile` in "Reading Files"](/docs/api/parse-options) +[^3]: See ["Workbook Object"](/docs/csf/book) +[^4]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) diff --git a/docz/docs/03-demos/42-engines/02-v8.md b/docz/docs/03-demos/42-engines/02-v8.md index 8dea05f..954b468 100644 --- a/docz/docs/03-demos/42-engines/02-v8.md +++ b/docz/docs/03-demos/42-engines/02-v8.md @@ -125,7 +125,7 @@ This demo was tested in the following deployments: | V8 Version | Platform | OS Version | Compiler | Date | |:--------------|:-------------|:--------------|:-----------------|:-----------| | `11.8.82` | `darwin-x64` | macOS 13.5.1 | `clang 14.0.3` | 2023-08-26 | -| `11.8.82` | `darwin-arm` | macOS 13.5.1 | `clang 14.0.3` | 2023-08-26 | +| `12.0.175` | `darwin-arm` | macOS 14.0 | `clang 15.0.0` | 2023-10-20 | | `11.8.82` | `win10-x64` | Windows 10 | `CL 19.37.32822` | 2023-08-26 | | `12.0.72` | `linux-x64` | HoloOS 3.4.11 | `gcc 12.2.0` | 2023-10-11 | | `11.8.82` | `linux-arm` | Debian 11 | `gcc 10.2.1` | 2023-09-26 | diff --git a/docz/docs/03-demos/42-engines/21-boa.md b/docz/docs/03-demos/42-engines/21-boa.md index 96febc7..3dca1db 100644 --- a/docz/docs/03-demos/42-engines/21-boa.md +++ b/docz/docs/03-demos/42-engines/21-boa.md @@ -115,7 +115,7 @@ This demo was tested in the following deployments: | Architecture | Date | |:-------------|:-----------| | `darwin-x64` | 2023-08-31 | -| `darwin-arm` | 2023-07-05 | +| `darwin-arm` | 2023-10-20 | | `win10-x64` | 2023-08-31 | | `win11-arm` | 2023-09-26 | | `linux-x64` | 2023-10-11 | diff --git a/docz/docs/03-demos/42-engines/index.md b/docz/docs/03-demos/42-engines/index.md index b67a3ef..b50d411 100644 --- a/docz/docs/03-demos/42-engines/index.md +++ b/docz/docs/03-demos/42-engines/index.md @@ -134,6 +134,8 @@ This demo was tested in the following deployments: | `darwin-x64` | `a588e49` | 2023-09-22 | | `linux-x64` | `a588e49` | 2023-10-11 | +::: + :::note pass While applications should link against the official libraries, the standalone tool