forked from sheetjs/docs.sheetjs.com
		
	esbuild-plugin
This commit is contained in:
		
							parent
							
								
									3ab0c1ab67
								
							
						
					
					
						commit
						aeb932e1d0
					
				@ -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`
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										151
									
								
								docz/docs/03-demos/01-frontend/19-bundler/09-browserify.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										151
									
								
								docz/docs/03-demos/01-frontend/19-bundler/09-browserify.md
									
									
									
									
									
										Normal file
									
								
							@ -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:
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="pm">
 | 
			
		||||
  <TabItem value="npm" label="npm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="pnpm" label="pnpm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="yarn" label="Yarn" default>
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
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"
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head></head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>SheetJS Presidents Demo</h1>
 | 
			
		||||
    <button id="xport">Click here to export</button>
 | 
			
		||||
    <script src="./index.min.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
							
								
								
									
										186
									
								
								docz/docs/03-demos/01-frontend/19-bundler/21-swcpack.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										186
									
								
								docz/docs/03-demos/01-frontend/19-bundler/21-swcpack.md
									
									
									
									
									
										Normal file
									
								
							@ -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 '<unnamed>' 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:
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="pm">
 | 
			
		||||
  <TabItem value="npm" label="npm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="pnpm" label="pnpm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="yarn" label="Yarn" default>
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
:::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"
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head></head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>SheetJS Presidents Demo</h1>
 | 
			
		||||
    <button id="xport">Click here to export</button>
 | 
			
		||||
    <script src="lib/web.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
@ -35,84 +35,9 @@ The following tools are covered in separate pages:
 | 
			
		||||
  </li>);
 | 
			
		||||
})}</ul>
 | 
			
		||||
 | 
			
		||||
## 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.
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 May 07 against Browserify `17.0.0`
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
1) Install the tarball using a package manager:
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="pm">
 | 
			
		||||
  <TabItem value="npm" label="npm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="pnpm" label="pnpm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="yarn" label="Yarn" default>
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
#### 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.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
## 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
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
## 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.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 May 07 against SWC 1.2.246
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
1) Install the dependencies using a package manager:
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="pm">
 | 
			
		||||
  <TabItem value="npm" label="npm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="pnpm" label="pnpm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="yarn" label="Yarn" default>
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
:::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"
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head></head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>SheetJS Presidents Demo</h1>
 | 
			
		||||
    <button id="xport">Click here to export</button>
 | 
			
		||||
    <script src="lib/web.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
**[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/swcpack)**
 | 
			
		||||
 | 
			
		||||
#### SystemJS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										361
									
								
								docz/docs/03-demos/04-static/04-esbuild.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										361
									
								
								docz/docs/03-demos/04-static/04-esbuild.md
									
									
									
									
									
										Normal file
									
								
							@ -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 = "<table><tr><th>Name</th><th>Index</th></tr>" +
 | 
			
		||||
  data.map((row) => `<tr>
 | 
			
		||||
    <td>${row.Name}</td>
 | 
			
		||||
    <td>${row.Index}</td>
 | 
			
		||||
  </tr>`).join("") +
 | 
			
		||||
"</table>";
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
2) Save the following to `index.html`:
 | 
			
		||||
 | 
			
		||||
```html title="index.html"
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <title>SheetJS + ESBuild</title>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
   <script src="out.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Save the following to `app.js`:
 | 
			
		||||
 | 
			
		||||
```js title="app.js"
 | 
			
		||||
import data from './pres.numbers'
 | 
			
		||||
const elt = document.createElement('div');
 | 
			
		||||
elt.innerHTML = "<table><tr><th>Name</th><th>Index</th></tr>" +
 | 
			
		||||
  data.map((row) => `<tr>
 | 
			
		||||
    <td>${row.Name}</td>
 | 
			
		||||
    <td>${row.Index}</td>
 | 
			
		||||
  </tr>`).join("") +
 | 
			
		||||
"</table>";
 | 
			
		||||
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 <https://sheetjs.com/pres.numbers> 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 = "<table><tr><th>Name</th><th>Index</th></tr>" + pres_default.map((row) => `<tr>
 | 
			
		||||
    <td>${row.Name}</td>
 | 
			
		||||
    <td>${row.Index}</td>
 | 
			
		||||
  </tr>`).join("") + "</table>";
 | 
			
		||||
  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)
 | 
			
		||||
@ -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 |
 | 
			
		||||
 | 
			
		||||
@ -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 |
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user