ViteJS Static Demo refresh
This commit is contained in:
parent
1a80a55e76
commit
14bd6a4ed0
@ -86,16 +86,16 @@
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/cli/nodesea#complete-example"><Data ss:Type="String">NodeJS SEA</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/cli/bunsea#complete-example"><Data ss:Type="String">Bun SEA</Data></Cell>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/cli/bunsea#complete-example"><Data ss:Type="String">BunJS SEA</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
|
@ -12,15 +12,15 @@ sidebar_custom_props:
|
||||
import current from '/version.js';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
[ViteJS](https://vitejs.dev/) is a modern build tool for generating static sites.
|
||||
It has a robust JavaScript-powered plugin system[^1]
|
||||
[ViteJS](https://vitejs.dev/) is a build tool for generating static websites. 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 ViteJS 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 ViteJS
|
||||
plugin and compare a few different data loading strategies.
|
||||
plugin and evaluate data loading strategies.
|
||||
|
||||
The ["Complete Demo"](#complete-demo) section creates a complete website powered
|
||||
by a XLSX spreadsheet.
|
||||
@ -32,16 +32,97 @@ suitable for end of week or end of month (EOM) reports published in HTML tables.
|
||||
|
||||
For processing user-submitted files in the browser, the
|
||||
[ViteJS "Bundlers" demo](/docs/demos/frontend/bundler/vitejs) shows client-side
|
||||
bundling of the SheetJS library. The ["ReactJS" demo](/docs/demos/frontend/react)
|
||||
bundling of SheetJS libraries. The ["ReactJS" demo](/docs/demos/frontend/react)
|
||||
shows example sites using ViteJS with the ReactJS starter.
|
||||
|
||||
:::
|
||||
|
||||
## Plugins
|
||||
|
||||
ViteJS supports static asset imports[^2], but the default raw loader interprets data
|
||||
as UTF-8 strings. This corrupts binary formats like XLSX and XLS, but a custom
|
||||
loader can override the default behavior.
|
||||
ViteJS supports static asset imports[^2], but the default raw loader interprets
|
||||
data as UTF-8 strings. This corrupts binary formats including XLSX and XLS. A
|
||||
custom loader can bypass the raw loader and directly read files.
|
||||
|
||||
Since a custom loader must be used, some data processing work can be performed
|
||||
by the loader. Three approaches are explored in this demo.
|
||||
|
||||
The following diagrams show the ViteJS data flow. The pink "Main Script import"
|
||||
boxes represent the division between the loader and the main script. The green
|
||||
"SheetJS Operations" boxes represent the steps performed by SheetJS libraries.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>[HTML](#html-plugin)</th>
|
||||
<th>[Data](#pure-data-plugin)</th>
|
||||
<th>[Base64](#base64-plugin)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style={{verticalAlign: "top"}}>
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
file[(workbook\nfile)]
|
||||
buffer(NodeJS\nBuffer)
|
||||
sheetjs[[SheetJS Operations]]
|
||||
tabeller{{HTML\nString}}
|
||||
handoff[[Main Script import]]
|
||||
html{{HTML\nTABLE}}
|
||||
style handoff fill:#FFC7CE
|
||||
style sheetjs fill:#C6EFCE
|
||||
file --> buffer
|
||||
buffer --> sheetjs
|
||||
sheetjs --> tabeller
|
||||
tabeller --> handoff
|
||||
handoff --------> html
|
||||
```
|
||||
|
||||
</td>
|
||||
<td style={{verticalAlign: "top"}}>
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
file[(workbook\nfile)]
|
||||
buffer(NodeJS\nBuffer)
|
||||
sheetjs[[SheetJS Operations]]
|
||||
aoo(array of\nobjects)
|
||||
handoff[[Main Script import]]
|
||||
import(array of\nobjects)
|
||||
html{{HTML\nTABLE}}
|
||||
style handoff fill:#FFC7CE
|
||||
style sheetjs fill:#C6EFCE
|
||||
file --> buffer
|
||||
buffer --> sheetjs
|
||||
sheetjs --> aoo
|
||||
aoo --> handoff
|
||||
handoff ------> import
|
||||
import --> html
|
||||
```
|
||||
|
||||
</td>
|
||||
<td style={{verticalAlign: "top"}}>
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
file[(workbook\nfile)]
|
||||
base64(Base64\nString)
|
||||
handoff[[Main Script import]]
|
||||
import(Base64\nString)
|
||||
sheetjs[[SheetJS Operations]]
|
||||
aoo(array of\nobjects)
|
||||
html{{HTML\nTABLE}}
|
||||
style handoff fill:#FFC7CE
|
||||
style sheetjs fill:#C6EFCE
|
||||
file --> base64
|
||||
base64 ------> handoff
|
||||
handoff --> import
|
||||
import --> sheetjs
|
||||
sheetjs --> aoo
|
||||
aoo --> html
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
For simple tables of data, ["Pure Data Plugin"](#pure-data-plugin) is strongly
|
||||
recommended. The file processing is performed at build time and the generated
|
||||
@ -51,6 +132,9 @@ For more complex parsing or display logic, ["Base64 Plugin"](#base64-plugin) is
|
||||
preferable. Since the raw parsing logic is performed in the page, the library
|
||||
will be included in the final bundle.
|
||||
|
||||
The ["HTML Plugin"](#html-plugin) generates HTML in the loader script. The
|
||||
SheetJS HTML writer renders merged cells and other features.
|
||||
|
||||
### Pure Data Plugin
|
||||
|
||||
For a pure static site, a plugin can load data into an array of row objects. The
|
||||
@ -72,7 +156,7 @@ flowchart LR
|
||||
```
|
||||
|
||||
This ViteJS plugin will read spreadsheets using the SheetJS `read` method[^3]
|
||||
and generate arrays of row objects with `sheet_to_json`[^4]:
|
||||
and generate arrays of row objects with the SheetJS `sheet_to_json`[^4] method:
|
||||
|
||||
```js title="vite.config.js"
|
||||
import { readFileSync } from 'fs';
|
||||
@ -89,13 +173,23 @@ export default defineConfig({
|
||||
if(!id.match(/\?sheetjs$/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?sheetjs$/, "")));
|
||||
var data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
return `export default JSON.parse('${JSON.stringify(data)}')`;
|
||||
return `export default JSON.parse('${JSON.stringify(data).replace(/\\/g, "\\\\")}')`;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
:::info pass
|
||||
|
||||
ViteJS plugins are expected to return strings representing ECMAScript modules.
|
||||
|
||||
The plugin uses `JSON.stringify` to encode the array of objects. The generated
|
||||
string is injected into the new module code. When ViteJS processes the module,
|
||||
`JSON.parse` recovers the array of objects.
|
||||
|
||||
:::
|
||||
|
||||
In frontend code, the loader will look for all modules with a `?sheetjs`
|
||||
query string. The default export is an array of row objects.
|
||||
|
||||
@ -115,9 +209,75 @@ document.querySelector('#app').innerHTML = `<table>
|
||||
</table>`;
|
||||
```
|
||||
|
||||
### HTML Plugin
|
||||
|
||||
A plugin can generate raw HTML strings that can be added to a page. The SheetJS
|
||||
libraries are used in the plugin but will not be added to the site.
|
||||
|
||||
The following diagram depicts the workbook waltz:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
file[(workbook\nfile)]
|
||||
subgraph SheetJS operations
|
||||
buffer(NodeJS\nBuffer)
|
||||
tavolo{{HTML\nString}}
|
||||
end
|
||||
html{{HTML\nTABLE}}
|
||||
file --> |vite.config.js\ncustom plugin| buffer
|
||||
buffer --> |vite.config.js\ncustom plugin| tavolo
|
||||
tavolo --> |main.js\nfrontend code| html
|
||||
```
|
||||
|
||||
This ViteJS plugin will read spreadsheets using the SheetJS `read` method[^5]
|
||||
and generate HTML using the SheetJS `sheet_to_html`[^6] method:
|
||||
|
||||
```js title="vite.config.js"
|
||||
import { readFileSync } from 'fs';
|
||||
import { read, utils } from 'xlsx';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
assetsInclude: ['**/*.xlsx'], // xlsx file should be treated as assets
|
||||
|
||||
plugins: [
|
||||
{ // this plugin handles ?html tags
|
||||
name: "vite-sheet-html",
|
||||
transform(code, id) {
|
||||
if(!id.match(/\?html/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?html/, "")));
|
||||
var html = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
return (`export default JSON.parse('${JSON.stringify(html).replace(/\\/g, "\\\\")}')`);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
:::info pass
|
||||
|
||||
ViteJS plugins are expected to return strings representing ECMAScript modules.
|
||||
|
||||
The plugin uses `JSON.stringify` to encode the HTML string. The generated string
|
||||
is injected into the new module code. When ViteJS processes the module,
|
||||
`JSON.parse` recovers the original HTML string.
|
||||
|
||||
:::
|
||||
|
||||
In frontend code, the loader will look for all modules with a `?html` query
|
||||
string. The default export is a string that can be directly added to the page.
|
||||
|
||||
The following example script sets the `innerHTML` property of the container:
|
||||
|
||||
```js title="main.js"
|
||||
import html from './data/pres.xlsx?html';
|
||||
|
||||
document.querySelector('#app').innerHTML = html;
|
||||
```
|
||||
|
||||
### Base64 Plugin
|
||||
|
||||
This plugin pulls in data as a Base64 string that can be read with `read`[^5].
|
||||
This plugin pulls in data as a Base64 string that can be read with `read`[^7].
|
||||
While this approach works, it is not recommended since it loads the library in
|
||||
the front-end site.
|
||||
|
||||
@ -161,7 +321,7 @@ export default defineConfig({
|
||||
```
|
||||
|
||||
When importing using the `b64` query, the raw Base64 string will be exposed.
|
||||
`read` will process the Base64 string using the `base64` input type[^6]:
|
||||
`read` will process the Base64 string using the `base64` input type[^8]:
|
||||
|
||||
```js title="main.js"
|
||||
import { read, utils } from "xlsx";
|
||||
@ -187,22 +347,22 @@ document.querySelector('#app').innerHTML = `<table>
|
||||
|
||||
## Complete Demo
|
||||
|
||||
The demo walks through the process of creating a new ViteJS website from scratch.
|
||||
A Git repository with the completed site can be cloned[^9].
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| ViteJS | Date |
|
||||
|:---------|:-----------|
|
||||
| `5.0.5` | 2023-12-04 |
|
||||
| `4.5.0` | 2023-12-04 |
|
||||
| `3.2.7` | 2023-12-04 |
|
||||
| `2.9.16` | 2023-12-04 |
|
||||
| `5.2.12` | 2024-06-02 |
|
||||
| `4.5.3` | 2024-06-02 |
|
||||
| `3.2.10` | 2024-06-02 |
|
||||
| `2.9.18` | 2024-06-02 |
|
||||
|
||||
:::
|
||||
|
||||
The demo walks through the process of creating a new ViteJS website from scratch.
|
||||
A Git repository with the completed site can be cloned[^7].
|
||||
|
||||
### Initial Setup
|
||||
|
||||
1) Create a new site with the `vue-ts` template and install the SheetJS package:
|
||||
@ -275,9 +435,30 @@ npx http-server dist/
|
||||
The terminal will display a URL, typically `http://127.0.0.1:8080` . Access
|
||||
that page with a web browser.
|
||||
|
||||
:::caution pass
|
||||
|
||||
When this demo was tested against ViteJS `2.9.18`, the build failed:
|
||||
|
||||
```
|
||||
src/App.vue:8:3 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
|
||||
|
||||
8 <img alt="Vue logo" src="./assets/logo.png" />
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
```
|
||||
|
||||
**As it affects the project template, this is a bug in ViteJS.**
|
||||
|
||||
The simplest workaround is to force upgrade the `vue-tsc` dependency:
|
||||
|
||||
```bash
|
||||
npm i vue-tsc@latest
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
7) To confirm that only the raw data is present in the page, view the page
|
||||
source. The code will reference some script like `/assets/index-HASH.js`.
|
||||
Open that script.
|
||||
source. The code will reference a script `/assets/index-HASH.js` where `HASH` is
|
||||
a string of characters. Open that script.
|
||||
|
||||
Searching for `Bill Clinton` reveals the following:
|
||||
|
||||
@ -291,11 +472,11 @@ included in the final site!
|
||||
:::info pass
|
||||
|
||||
ViteJS also supports "Server-Side Rendering". In SSR, only the HTML table
|
||||
would be added to the final page. Details are covered in the ViteJS docs[^8].
|
||||
would be added to the final page. Details are covered in the ViteJS docs[^10].
|
||||
|
||||
:::
|
||||
|
||||
### Base64 Test
|
||||
### HTML Test
|
||||
|
||||
8) Run the dev server:
|
||||
|
||||
@ -303,10 +484,88 @@ would be added to the final page. Details are covered in the ViteJS docs[^8].
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Open a browser window to the displayed URL.
|
||||
Open a browser window to the displayed URL (typically `http://localhost:5173` )
|
||||
|
||||
9) Replace the component `src/components/HelloWorld.vue` with:
|
||||
|
||||
```html title="src/components/HelloWorld.vue"
|
||||
<script setup lang="ts">
|
||||
// @ts-ignore
|
||||
import html from '../../data/pres.xlsx?html';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-html="html"></div>
|
||||
</template>
|
||||
```
|
||||
|
||||
Save and refresh the page. A data table should be displayed
|
||||
|
||||
10) Stop the dev server and build the site
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
npx http-server dist/
|
||||
```
|
||||
|
||||
The terminal will display a URL, typically `http://127.0.0.1:8080` . Access
|
||||
that page with a web browser.
|
||||
|
||||
:::caution pass
|
||||
|
||||
When this demo was tested against ViteJS `2.9.18`, the build failed:
|
||||
|
||||
```
|
||||
src/App.vue:8:3 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
|
||||
|
||||
8 <img alt="Vue logo" src="./assets/logo.png" />
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
```
|
||||
|
||||
**As it affects the project template, this is a bug in ViteJS.**
|
||||
|
||||
The simplest workaround is to force upgrade the `vue-tsc` dependency:
|
||||
|
||||
```bash
|
||||
npm i vue-tsc@latest
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
11) To confirm that only the raw HTML is present in the page, view the page
|
||||
source. The code will reference a script `/assets/index-HASH.js` where `HASH` is
|
||||
a string of characters. Open that script.
|
||||
|
||||
Searching for `Bill Clinton` reveals the following encoded HTML element:
|
||||
|
||||
```
|
||||
<td data-t=\\"s\\" data-v=\\"Bill Clinton\\" id=\\"sjs-A2\\">Bill Clinton</td>
|
||||
```
|
||||
|
||||
Searching for `BESSELJ` should reveal no results. The SheetJS scripts are not
|
||||
included in the final site!
|
||||
|
||||
:::info pass
|
||||
|
||||
The HTML code is still stored in a script and is injected dynamically.
|
||||
|
||||
ViteJS "Server-Side Rendering" offers the option to render the site at build
|
||||
time, ensuring that the HTML table is directly added to the page.
|
||||
|
||||
:::
|
||||
|
||||
### Base64 Test
|
||||
|
||||
12) Run the dev server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Open a browser window to the displayed URL (typically `http://localhost:5173` )
|
||||
|
||||
13) Replace the component `src/components/HelloWorld.vue` with:
|
||||
|
||||
```html title="src/components/HelloWorld.vue"
|
||||
<script setup lang="ts">
|
||||
// @ts-ignore
|
||||
@ -330,7 +589,7 @@ const data = utils.sheet_to_json<IPresident>(ws);
|
||||
</template>
|
||||
```
|
||||
|
||||
10) Stop the dev server and build the site
|
||||
14) Stop the dev server and build the site
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
@ -340,9 +599,30 @@ npx http-server dist/
|
||||
The terminal will display a URL ( `http://127.0.0.1:8080` ). Access that page
|
||||
with a web browser.
|
||||
|
||||
11) To confirm that the object data is not present in the page, view the page
|
||||
source. The code will reference some script like `/assets/index-HASH.js` with
|
||||
a different hash from the previous test. Open that script.
|
||||
:::caution pass
|
||||
|
||||
When this demo was tested against ViteJS `2.9.18`, the build failed:
|
||||
|
||||
```
|
||||
src/App.vue:8:3 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
|
||||
|
||||
8 <img alt="Vue logo" src="./assets/logo.png" />
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
```
|
||||
|
||||
**As it affects the project template, this is a bug in ViteJS.**
|
||||
|
||||
The simplest workaround is to force upgrade the `vue-tsc` dependency:
|
||||
|
||||
```bash
|
||||
npm i vue-tsc@latest
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
15) To confirm that the object data is not present in the page, view the page
|
||||
source. The code will reference a script `/assets/index-HASH.js` where `HASH` is
|
||||
a string of characters. Open that script.
|
||||
|
||||
Searching for `BESSELJ` should match the code:
|
||||
|
||||
@ -356,8 +636,10 @@ embedded in the final site and the data is parsed when the page is loaded.
|
||||
[^1]: See ["Using Plugins"](https://vitejs.dev/guide/using-plugins.html) in the ViteJS documentation.
|
||||
[^2]: See ["Static Asset Handling"](https://vitejs.dev/guide/assets.html) in the ViteJS documentation.
|
||||
[^3]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^4]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^4]: See [`sheet_to_html` in "Utilities"](/docs/api/utilities/html#html-table-output)
|
||||
[^5]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^6]: See [the "base64" type in "Reading Files"](/docs/api/parse-options#input-type)
|
||||
[^7]: See [`SheetJS/sheetjs-vite`](https://git.sheetjs.com/sheetjs/sheetjs-vite/) on the SheetJS git server.
|
||||
[^8]: See ["Server-Side Rendering"](https://vitejs.dev/guide/ssr.html) in the ViteJS documentation.
|
||||
[^6]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^7]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^8]: See [the "base64" type in "Reading Files"](/docs/api/parse-options#input-type)
|
||||
[^9]: See [`examples/sheetjs-vite`](https://git.sheetjs.com/examples/sheetjs-vite/) on the SheetJS git server.
|
||||
[^10]: See ["Server-Side Rendering"](https://vitejs.dev/guide/ssr.html) in the ViteJS documentation.
|
@ -159,6 +159,7 @@ This demo was tested in the following deployments:
|
||||
| Architecture | NodeJS | Date |
|
||||
|:-------------|:----------|:-----------|
|
||||
| `darwin-x64` | `22.2.0` | 2024-05-28 |
|
||||
| `darwin-arm` | `22.2.0` | 2024-05-29 |
|
||||
| `win10-x64` | `20.12.0` | 2024-03-26 |
|
||||
| `win11-x64` | `20.13.1` | 2024-05-22 |
|
||||
| `linux-x64` | `20.11.1` | 2024-03-18 |
|
||||
|
@ -80,6 +80,7 @@ This demo was last tested in the following deployments:
|
||||
| Architecture | BunJS | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `1.1.10` | 2024-05-28 |
|
||||
| `darwin-arm` | `1.1.10` | 2024-05-29 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -14,7 +14,16 @@ export default defineConfig({
|
||||
if(!id.match(/\?sheetjs$/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?sheetjs$/, "")));
|
||||
var data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
return `export default JSON.parse('${JSON.stringify(data)}')`;
|
||||
return `export default JSON.parse('${JSON.stringify(data).replace(/\\/g, "\\\\")}')`;
|
||||
}
|
||||
},
|
||||
{ // this plugin handles ?html tags
|
||||
name: "vite-sheet-html",
|
||||
transform(code, id) {
|
||||
if(!id.match(/\?html/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?html/, "")));
|
||||
var html = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
return (`export default JSON.parse('${JSON.stringify(html).replace(/\\/g, "\\\\")}')`);
|
||||
}
|
||||
},
|
||||
{ // this plugin handles ?b64 tags
|
||||
|
@ -81,16 +81,16 @@ const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.static('./'));
|
||||
app.listen(7262, async() => {
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
page.on("console", msg => console.log("PAGE LOG:", msg.text()));
|
||||
await page.setViewport({width: 1920, height: 1080});
|
||||
await page.goto('http://localhost:7262/');
|
||||
await page.click("#xport");
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await browser.close();
|
||||
process.exit();
|
||||
process.exit();
|
||||
});
|
||||
EOF
|
||||
|
||||
|
@ -68,7 +68,7 @@ const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.static('./'));
|
||||
app.listen(7262, async() => {
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
page.on("console", msg => console.log("PAGE LOG:", msg.text()));
|
||||
@ -77,12 +77,12 @@ app.listen(7262, async() => {
|
||||
|
||||
/* wait for requirejs to request xlsx.full.min.js */
|
||||
await page.waitForRequest(request => request.url().indexOf('xlsx.full.min.js') !== -1);
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
|
||||
await page.click("#xport");
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await browser.close();
|
||||
process.exit();
|
||||
process.exit();
|
||||
});
|
||||
EOF
|
||||
|
||||
@ -92,16 +92,16 @@ const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.static('./'));
|
||||
app.listen(7262, async() => {
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
page.on("console", msg => console.log("PAGE LOG:", msg.text()));
|
||||
await page.setViewport({width: 1920, height: 1080});
|
||||
await page.goto('http://localhost:7262/optimized.html');
|
||||
await page.click("#xport");
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
await browser.close();
|
||||
process.exit();
|
||||
process.exit();
|
||||
});
|
||||
EOF
|
||||
|
||||
|
@ -21,10 +21,10 @@ curl -LO https://sheetjs.com/pres.xlsx
|
||||
curl -LO https://docs.sheetjs.com/nashorn/SheetJSNashorn.java
|
||||
|
||||
for n in {17..22}; do
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
rm -fr SheetJSNashorn.class SheetJSNashorn.jar sheethorn
|
||||
javac SheetJSNashorn.java
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
rm -fr SheetJSNashorn.class SheetJSNashorn.jar sheethorn
|
||||
javac SheetJSNashorn.java
|
||||
|
||||
java -cp ".:js-scriptengine-24.0.1.jar:js-language-24.0.1.jar:polyglot-24.0.1.jar:collections-24.0.1.jar:truffle-api-24.0.1.jar:nativeimage-24.0.1.jar:icu4j-24.0.1.jar:regex-24.0.1.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
|
||||
|
||||
|
@ -19,31 +19,31 @@ curl -L -o asm-util-9.5.jar "https://search.maven.org/remotecontent?filepath=org
|
||||
|
||||
# Standalone Nashorn
|
||||
for n in {15..22}; do
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
rm -fr SheetJSNashorn.class SheetJSNashorn.jar sheethorn
|
||||
javac SheetJSNashorn.java
|
||||
java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar SheetJSNashorn pres.xlsx
|
||||
jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
|
||||
mkdir -p sheethorn
|
||||
cp *.jar pres.xlsx sheethorn
|
||||
cd sheethorn
|
||||
java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar:SheetJSNashorn.jar SheetJSNashorn pres.xlsx
|
||||
cd -
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
rm -fr SheetJSNashorn.class SheetJSNashorn.jar sheethorn
|
||||
javac SheetJSNashorn.java
|
||||
java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar SheetJSNashorn pres.xlsx
|
||||
jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
|
||||
mkdir -p sheethorn
|
||||
cp *.jar pres.xlsx sheethorn
|
||||
cd sheethorn
|
||||
java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar:SheetJSNashorn.jar SheetJSNashorn pres.xlsx
|
||||
cd -
|
||||
done
|
||||
|
||||
# Built-in Nashorn
|
||||
for n in 1.8 {9..14}; do
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
rm -fr SheetJSNashorn.class SheetJSNashorn.jar sheethorn
|
||||
javac SheetJSNashorn.java
|
||||
java SheetJSNashorn pres.xlsx
|
||||
jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
|
||||
mkdir -p sheethorn
|
||||
cp *.jar pres.xlsx sheethorn
|
||||
cd sheethorn
|
||||
java -cp .:SheetJSNashorn.jar SheetJSNashorn pres.xlsx
|
||||
cd -
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
rm -fr SheetJSNashorn.class SheetJSNashorn.jar sheethorn
|
||||
javac SheetJSNashorn.java
|
||||
java SheetJSNashorn pres.xlsx
|
||||
jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
|
||||
mkdir -p sheethorn
|
||||
cp *.jar pres.xlsx sheethorn
|
||||
cd sheethorn
|
||||
java -cp .:SheetJSNashorn.jar SheetJSNashorn pres.xlsx
|
||||
cd -
|
||||
done
|
||||
|
||||
|
@ -43,8 +43,8 @@ public class SheetJSRhino {
|
||||
EOF
|
||||
|
||||
for n in 1.8 {9..22}; do
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
find . -name \*.class | while read x; do rm $x; done
|
||||
|
||||
javac -cp ".:rhino.jar" SheetJSRhino.java
|
||||
|
137
tests/static-vite.sh
Executable file
137
tests/static-vite.sh
Executable file
@ -0,0 +1,137 @@
|
||||
#!/bin/bash
|
||||
# https://docs.sheetjs.com/docs/demos/static/vitejs
|
||||
# This script builds the Pure Data test and Base64 test. It does not test HMR!
|
||||
cd /tmp
|
||||
rm -rf sheetjs-vite-static
|
||||
mkdir sheetjs-vite-static
|
||||
cd sheetjs-vite-static
|
||||
|
||||
for n in {2..5}; do
|
||||
npm create -y vite@$n sheetjs-vite-$n -- --template vue-ts
|
||||
cd sheetjs-vite-$n
|
||||
npm i
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz
|
||||
npm i --save puppeteer express@4
|
||||
if [[ "$n" == "2" ]]; then
|
||||
# The default vitejs2 + vuejs project does not build
|
||||
#
|
||||
# src/App.vue:8:3 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
|
||||
#
|
||||
# 8 <img alt="Vue logo" src="./assets/logo.png" />
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#
|
||||
# Before the TS errors, there is a message:
|
||||
# Please update to v0.35.0 or higher for TypeScript version: 4.9.5
|
||||
#
|
||||
# Forcefully upgrading `vue-tsc` appears to be innocuous.
|
||||
npm i --save vue-tsc@latest
|
||||
fi
|
||||
curl -O https://docs.sheetjs.com/vitejs/vite.config.ts
|
||||
mkdir -p data
|
||||
curl -L -o data/pres.xlsx https://docs.sheetjs.com/pres.xlsx
|
||||
|
||||
cat >test.cjs <<EOF
|
||||
const puppeteer = require('puppeteer');
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.static('./dist/'));
|
||||
app.listen(7262, async() => {
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
page.on("console", msg => console.log("PAGE LOG:", msg.text()));
|
||||
await page.setViewport({width: 1920, height: 1080});
|
||||
await page.goto('http://localhost:7262/');
|
||||
await page.addScriptTag({ url: 'https://cdn.sheetjs.com/xlsx-0.20.2/package/dist/xlsx.full.min.js' });
|
||||
await new Promise((res,rej) => setTimeout(res, 1000));
|
||||
const csv = await page.evaluate(() => {
|
||||
const tbl = document.querySelector('table');
|
||||
const ws = XLSX.utils.table_to_sheet(tbl);
|
||||
return XLSX.utils.sheet_to_csv(ws);
|
||||
});
|
||||
console.log(csv);
|
||||
await browser.close();
|
||||
process.exit();
|
||||
});
|
||||
EOF
|
||||
|
||||
## Pure Data Test
|
||||
cat >src/components/HelloWorld.vue <<EOF
|
||||
<script setup lang="ts">
|
||||
// @ts-ignore
|
||||
import data from '../../data/pres.xlsx?sheetjs';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table>
|
||||
<tr><th>Name</th><th>Index</th></tr>
|
||||
<tr v-for="(row,R) in data" v-bind:key="R">
|
||||
<td>{{row.Name}}</td>
|
||||
<td>{{row.Index}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
EOF
|
||||
|
||||
npm run build
|
||||
npm ls | grep "vite@"
|
||||
node test.cjs
|
||||
# Expected output: CSV contents of first sheet
|
||||
|
||||
echo "Clinton" $(grep Clinton dist/assets/*.js | wc -l) "BESSELJ" $(grep BESSELJ dist/assets/*.js | wc -l)
|
||||
# Expected output: Clinton 1 BESSELJ 0
|
||||
|
||||
## HTML Test
|
||||
cat >src/components/HelloWorld.vue <<EOF
|
||||
<script setup lang="ts">
|
||||
// @ts-ignore
|
||||
import html from '../../data/pres.xlsx?html';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-html="html"></div>
|
||||
</template>
|
||||
EOF
|
||||
|
||||
npm run build
|
||||
npm ls | grep "vite@"
|
||||
node test.cjs
|
||||
# Expected output: CSV contents of first sheet
|
||||
|
||||
echo "Clinton" $(grep Clinton dist/assets/*.js | wc -l) "BESSELJ" $(grep BESSELJ dist/assets/*.js | wc -l)
|
||||
# Expected output: Clinton 1 BESSELJ 0
|
||||
|
||||
## Base64 Test
|
||||
cat >src/components/HelloWorld.vue <<EOF
|
||||
<script setup lang="ts">
|
||||
// @ts-ignore
|
||||
import b64 from '../../data/pres.xlsx?b64';
|
||||
import { read, utils } from "xlsx";
|
||||
/* parse workbook and convert first sheet to row array */
|
||||
const wb = read(b64);
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
interface IPresident { Name: string; Index: number; };
|
||||
const data = utils.sheet_to_json<IPresident>(ws);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table>
|
||||
<tr><th>Name</th><th>Index</th></tr>
|
||||
<tr v-for="(row,R) in data" v-bind:key="R">
|
||||
<td>{{row.Name}}</td>
|
||||
<td>{{row.Index}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
EOF
|
||||
|
||||
npm run build
|
||||
npm ls | grep "vite@"
|
||||
node test.cjs
|
||||
# Expected output: CSV contents of first sheet
|
||||
|
||||
echo "Clinton" $(grep Clinton dist/assets/*.js | wc -l) "BESSELJ" $(grep BESSELJ dist/assets/*.js | wc -l)
|
||||
# Expected output: Clinton 0 BESSELJ 1
|
||||
|
||||
cd -
|
||||
done
|
Loading…
Reference in New Issue
Block a user