swcMinify
This commit is contained in:
parent
ae9e15716b
commit
b8eeab685c
@ -17,7 +17,7 @@ to load data from spreadsheets.
|
||||
|
||||
:::note
|
||||
|
||||
This was tested against `lume v1.12.0` on 2022 October 4.
|
||||
This was tested against `lume v1.14.2` on 2022 December 27.
|
||||
|
||||
:::
|
||||
|
||||
@ -28,7 +28,7 @@ This was tested against `lume v1.12.0` on 2022 October 4.
|
||||
```bash
|
||||
mkdir -p sheetjs-lume
|
||||
cd sheetjs-lume
|
||||
deno run -A https://deno.land/x/lume/init.ts
|
||||
deno run -Ar https://deno.land/x/lume/init.ts
|
||||
```
|
||||
|
||||
When prompted, enter the following options:
|
||||
@ -132,7 +132,7 @@ The following query pulls the `Name` and `Index` fields from each row:
|
||||
allPresXlsxSheet1 { # "all" followed by type
|
||||
edges {
|
||||
node { # each line in this block should be a field in the data
|
||||
Name
|
||||
Name
|
||||
Index
|
||||
}
|
||||
}
|
||||
@ -157,6 +157,8 @@ overridden through a `package.json` override in the latest versions of NodeJS:
|
||||
|
||||
:::
|
||||
|
||||
#### GatsbyJS Demo
|
||||
|
||||
<details><summary><b>Complete Example</b> (click to show)</summary>
|
||||
|
||||
:::note
|
||||
@ -471,7 +473,7 @@ ${csv}
|
||||
|
||||
:::note
|
||||
|
||||
This was tested against `next v12.2.5` on 2022 August 16.
|
||||
This was tested against `next v13.1.1` on 2022 December 28.
|
||||
|
||||
:::
|
||||
|
||||
@ -500,7 +502,7 @@ export default function Index({html, type}) { return (
|
||||
); }
|
||||
```
|
||||
|
||||
:::warning
|
||||
:::warning Reading and writing files during the build process
|
||||
|
||||
`fs` cannot be statically imported from the top level in NextJS pages. The
|
||||
dynamic import must happen within a lifecycle function. For example:
|
||||
@ -523,6 +525,20 @@ export async function getServerSideProps() {
|
||||
|
||||
:::
|
||||
|
||||
:::caution Next 13+ and SWC
|
||||
|
||||
Next 13 switched to the SWC minifier. There are known issues with the minifier.
|
||||
Until those issues are resolved, SWC should be disabled in `next.config.js`:
|
||||
|
||||
```js title="next.config.js"
|
||||
module.exports = {
|
||||
// highlight-next-line
|
||||
swcMinify: false
|
||||
};
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
#### Demo
|
||||
|
||||
<details><summary><b>Complete Example</b> (click to show)</summary>
|
||||
@ -530,13 +546,13 @@ export async function getServerSideProps() {
|
||||
0) Disable NextJS telemetry:
|
||||
|
||||
```js
|
||||
npx next telemetry disable
|
||||
npx next@13.1.1 telemetry disable
|
||||
```
|
||||
|
||||
Confirm it is disabled by running
|
||||
|
||||
```js
|
||||
npx next telemetry status
|
||||
npx next@13.1.1 telemetry status
|
||||
```
|
||||
|
||||
1) Set up folder structure. At the end, a `pages` folder with a `sheets`
|
||||
@ -556,7 +572,7 @@ curl -LO https://docs.sheetjs.com/next/sheetjs.xlsx
|
||||
3) Install dependencies:
|
||||
|
||||
```bash
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz next@12.2.5
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz next@13.1.1
|
||||
```
|
||||
|
||||
4) Download test scripts:
|
||||
@ -594,7 +610,7 @@ cd ../..
|
||||
5) Test the deployment:
|
||||
|
||||
```bash
|
||||
npx next@12.2.5
|
||||
npx next@13.1.1
|
||||
```
|
||||
|
||||
Open a web browser and access:
|
||||
@ -613,19 +629,19 @@ The individual worksheets are available at
|
||||
6) Stop the server and run a production build:
|
||||
|
||||
```bash
|
||||
npx next@12.2.5 build
|
||||
npx next@13.1.1 build
|
||||
```
|
||||
|
||||
The final output will show a list of the routes and types:
|
||||
|
||||
```
|
||||
Route (pages) Size First Load JS
|
||||
┌ ○ / 551 B 81.7 kB
|
||||
├ ○ /404 194 B 77.2 kB
|
||||
├ λ /getServerSideProps 602 B 81.7 kB
|
||||
├ ● /getStaticPaths 2.7 kB 83.8 kB
|
||||
├ ● /getStaticProps 600 B 81.7 kB
|
||||
└ ● /sheets/[id] (312 ms) 580 B 81.7 kB
|
||||
┌ ○ / 541 B 77.4 kB
|
||||
├ ○ /404 181 B 73.7 kB
|
||||
├ λ /getServerSideProps 594 B 77.4 kB
|
||||
├ ● /getStaticPaths 2.56 kB 79.4 kB
|
||||
├ ● /getStaticProps 591 B 77.4 kB
|
||||
└ ● /sheets/[id] (447 ms) 569 B 77.4 kB
|
||||
├ /sheets/0
|
||||
├ /sheets/1
|
||||
└ /sheets/2
|
||||
@ -638,7 +654,7 @@ worksheets in the file. `/getServerSideProps` is server-rendered.
|
||||
7) Try to build a static site:
|
||||
|
||||
```bash
|
||||
npx next@12.2.5 export
|
||||
npx next@13.1.1 export
|
||||
```
|
||||
|
||||
:::note The static export will fail!
|
||||
@ -648,17 +664,17 @@ is still server-rendered.
|
||||
|
||||
:::
|
||||
|
||||
8) Remove `pages/getServerSideProps.js` and rebuild with `npx next@12.2.5 build`
|
||||
8) Remove `pages/getServerSideProps.js` and rebuild with `npx next@13.1.1 build`
|
||||
|
||||
Inspecting the output, there should be no lines with the `λ` symbol:
|
||||
|
||||
```
|
||||
Route (pages) Size First Load JS
|
||||
┌ ○ / 551 B 81.7 kB
|
||||
├ ○ /404 194 B 77.2 kB
|
||||
├ ● /getStaticPaths 2.7 kB 83.8 kB
|
||||
├ ● /getStaticProps 600 B 81.7 kB
|
||||
└ ● /sheets/[id] (312 ms) 580 B 81.7 kB
|
||||
┌ ○ / 541 B 77.4 kB
|
||||
├ ○ /404 181 B 73.7 kB
|
||||
├ ● /getStaticPaths 2.56 kB 79.4 kB
|
||||
├ ● /getStaticProps 591 B 77.4 kB
|
||||
└ ● /sheets/[id] (459 ms) 569 B 77.4 kB
|
||||
├ /sheets/0
|
||||
├ /sheets/1
|
||||
└ /sheets/2
|
||||
@ -667,7 +683,7 @@ Route (pages) Size First Load JS
|
||||
9) Generate the static site:
|
||||
|
||||
```bash
|
||||
npx next@12.2.5 export
|
||||
npx next@13.1.1 export
|
||||
```
|
||||
|
||||
The static site will be written to the `out` subfolder, which can be hosted with
|
||||
|
@ -6,7 +6,60 @@ Parsing and writing large spreadsheets takes time. During the process, if the
|
||||
SheetJS library is running in the web browser, the website may freeze.
|
||||
|
||||
Workers provide a way to off-load the hard work so that the website does not
|
||||
freeze during processing.
|
||||
freeze during processing. The work is still performed locally. No data is sent
|
||||
to a remote server.
|
||||
|
||||
The following diagrams show the normal and Web Worker flows when exporting a
|
||||
dataset. The regions with a red background mark when the browser is frozen.
|
||||
|
||||
<table><thead><tr><th>Normal Export</th><th>Web Worker Export</th></tr>
|
||||
</thead><tbody><tr><td>
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User
|
||||
participant Page
|
||||
User->>Page: click button
|
||||
rect rgba(255,0,0,.2)
|
||||
activate Page
|
||||
Note over Page: collect dataset
|
||||
Note over Page: generate workbook
|
||||
Note over Page: create file
|
||||
Note over Page: setup download
|
||||
end
|
||||
Page->>User: download workbook
|
||||
deactivate Page
|
||||
```
|
||||
|
||||
</td><td>
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User
|
||||
participant Page
|
||||
participant Worker
|
||||
User->>Page: click button
|
||||
rect rgba(255,0,0,.2)
|
||||
activate Page
|
||||
Note over Page: collect dataset
|
||||
Page->>Worker: transfer dataset
|
||||
end
|
||||
deactivate Page
|
||||
activate Worker
|
||||
Note over Worker: generate workbook
|
||||
Note over Worker: create file
|
||||
Note over Worker: setup download
|
||||
Worker->>Page: URL to download
|
||||
deactivate Worker
|
||||
activate Page
|
||||
Page->>User: download workbook
|
||||
deactivate Page
|
||||
```
|
||||
|
||||
</td></tr></tbody></table>
|
||||
|
||||
|
||||
:::note Browser Compatibility
|
||||
|
||||
@ -17,7 +70,7 @@ added later. Feature testing is highly recommended.
|
||||
|
||||
:::info Inline Workers
|
||||
|
||||
Due to limitations of the live codeblocks, all of the workers in this section
|
||||
Due to limitations of the live code blocks, all of the workers in this section
|
||||
are in-line. The code is embedded in template literals. For production sites,
|
||||
typically workers are written in separate JS files.
|
||||
|
||||
@ -119,7 +172,31 @@ const worker = new Worker(
|
||||
:::
|
||||
|
||||
Typically the Web Worker performs the `fetch` operation, processes the workbook,
|
||||
and sends a final result to the main browser context for processing.
|
||||
and sends a final result (HTML table or raw data) to the main browser context:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User
|
||||
participant Page
|
||||
participant Worker
|
||||
User->>Page: click button
|
||||
activate Page
|
||||
Page->>Worker: send URL
|
||||
deactivate Page
|
||||
activate Worker
|
||||
Note over Worker: fetch file
|
||||
Note over Worker: parse file
|
||||
Note over Worker: generate table
|
||||
Worker->>Page: HTML table
|
||||
deactivate Worker
|
||||
activate Page
|
||||
Note over Page: add to DOM
|
||||
Page->>User: table is visible
|
||||
deactivate Page
|
||||
```
|
||||
|
||||
<details><summary><b>Live Demo</b> (click to show)</summary>
|
||||
|
||||
In the following example, the script:
|
||||
|
||||
@ -172,6 +249,8 @@ self.addEventListener('message', async(e) => {
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Creating a Local File
|
||||
|
||||
:::caution Writing files from Web Workers
|
||||
@ -181,8 +260,36 @@ the Web Worker to the main browser context for downloading.
|
||||
|
||||
:::
|
||||
|
||||
Typically the Web Worker receives an array of JS objects, generates a workbook,
|
||||
and sends a URL to the main browser context for download:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User
|
||||
participant Page
|
||||
participant Worker
|
||||
User->>Page: click button
|
||||
activate Page
|
||||
Note over Page: collect dataset
|
||||
Page->>Worker: transfer dataset
|
||||
deactivate Page
|
||||
activate Worker
|
||||
Note over Worker: generate workbook
|
||||
Note over Worker: create file
|
||||
Note over Worker: setup download
|
||||
Worker->>Page: URL to download
|
||||
deactivate Worker
|
||||
activate Page
|
||||
Page->>User: download workbook
|
||||
deactivate Page
|
||||
```
|
||||
|
||||
<details><summary><b>Live Demo</b> (click to show)</summary>
|
||||
|
||||
In the following example, the script:
|
||||
|
||||
- sends a dataset (array of JS objects) to the Web Worker
|
||||
- generates a workbook object in the Web Worker
|
||||
- generates a XLSB file using `XLSX.write` in the Web Worker
|
||||
- generates an object URL in the Web Worker
|
||||
@ -193,6 +300,11 @@ In the following example, the script:
|
||||
function SheetJSWriteFileWorker() {
|
||||
const [__html, setHTML] = React.useState("");
|
||||
|
||||
const data = [
|
||||
{ "SheetJS": "வணக்கம்", "in": "สวัสดี", "Web": "你好", "Workers": "가지마" },
|
||||
{ "SheetJS": 1, "in": 2, "Web": 3, "Workers": 4 },
|
||||
];
|
||||
|
||||
return ( <>
|
||||
<button onClick={() => { setHTML("");
|
||||
/* this mantra embeds the worker source in the function */
|
||||
@ -203,12 +315,10 @@ importScripts("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
|
||||
/* this callback will run once the main context sends a message */
|
||||
self.addEventListener('message', async(e) => {
|
||||
try {
|
||||
/* Create a new Workbook (in this case, from a CSV string) */
|
||||
const csv = \`\
|
||||
SheetJS,in,Web,Workers
|
||||
வணக்கம்,สวัสดี,你好,가지마
|
||||
1,2,3,4\`;
|
||||
const wb = XLSX.read(csv, { type: "string", dense: true });
|
||||
/* Create a new workbook from the data */
|
||||
const ws = XLSX.utils.json_to_sheet(e.data.data);
|
||||
const wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Data");
|
||||
|
||||
/* Write XLSB data (Uint8Array) */
|
||||
const u8 = XLSX.write(wb, { bookType: "xlsb", type: "buffer" });
|
||||
@ -237,13 +347,15 @@ SheetJS,in,Web,Workers
|
||||
document.body.removeChild(a);
|
||||
};
|
||||
/* post a message to the worker */
|
||||
worker.postMessage({});
|
||||
worker.postMessage({ data });
|
||||
}}><b>Click to Start</b></button>
|
||||
<div dangerouslySetInnerHTML={{ __html }}/>
|
||||
</> );
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## User-Submitted File
|
||||
|
||||
:::note FileReaderSync
|
||||
@ -253,6 +365,33 @@ synchronous version `FileReaderSync` is more efficient.
|
||||
|
||||
:::
|
||||
|
||||
Typically the Web Worker receives a file pointer, reads and parses the file,
|
||||
and sends a final result (HTML table or raw data) to the main browser context:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User
|
||||
participant Page
|
||||
participant Worker
|
||||
User->>Page: click button
|
||||
activate Page
|
||||
Page->>Worker: send URL
|
||||
deactivate Page
|
||||
activate Worker
|
||||
Note over Worker: fetch file
|
||||
Note over Worker: parse file
|
||||
Note over Worker: generate table
|
||||
Worker->>Page: HTML table
|
||||
deactivate Worker
|
||||
activate Page
|
||||
Note over Page: add to DOM
|
||||
Page->>User: table is visible
|
||||
deactivate Page
|
||||
```
|
||||
|
||||
<details><summary><b>Live Demo</b> (click to show)</summary>
|
||||
|
||||
In the following example, when a file is dropped over the DIV or when the INPUT
|
||||
element is used to select a file, the script:
|
||||
|
||||
@ -312,11 +451,15 @@ self.addEventListener('message', (e) => {
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Streaming Write
|
||||
|
||||
A more general discussion, including row-oriented processing demos, is included
|
||||
in the ["Large Datasets"](/docs/demos/stream#browser) demo.
|
||||
|
||||
`XLSX.stream.to_csv` incrementally generates CSV rows.
|
||||
|
||||
#### File System Access API
|
||||
|
||||
:::warning Browser Compatibility
|
||||
@ -336,6 +479,41 @@ Strings larger than 500M may hit browser length limits.
|
||||
|
||||
:::
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User
|
||||
participant Page
|
||||
participant Worker
|
||||
User->>Page: click button
|
||||
activate Page
|
||||
Page->>User: seek permission
|
||||
User->>Page: grant permission
|
||||
Note over Page: collect dataset
|
||||
Page->>Worker: transfer dataset
|
||||
deactivate Page
|
||||
activate Worker
|
||||
Note over Worker: setup stream
|
||||
Worker->>User: start download
|
||||
loop every 100 rows
|
||||
Note over Worker: generate rows
|
||||
Worker->>User: write rows to file (without freezing)
|
||||
Worker->>Page: progress message
|
||||
activate Page
|
||||
Page->>User: display progress
|
||||
deactivate Page
|
||||
end
|
||||
Worker->>User: finish download
|
||||
Worker->>Page: send competion message
|
||||
deactivate Worker
|
||||
activate Page
|
||||
Page->>User: download complete
|
||||
deactivate Page
|
||||
```
|
||||
|
||||
|
||||
<details><summary><b>Live Demo</b> (click to show)</summary>
|
||||
|
||||
The following live demo fetches and parses a file in a Web Worker. The script:
|
||||
|
||||
- prompts user to save file (`window.showSaveFilePicker` in the main thread)
|
||||
@ -461,3 +639,5 @@ self.addEventListener('message', async(e) => {
|
||||
</> );
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -316,4 +316,16 @@ function add_to_sheet(sheet, cell) {
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
</details>
|
||||
|
||||
#### Corrupt files
|
||||
|
||||
Third-party build tools and frameworks may post-process SheetJS scripts. The
|
||||
changes may result in corrupt files.
|
||||
|
||||
In the web browser, the standalone scripts from the SheetJS CDN will use proper
|
||||
encodings and should work in applications. The scripts typically can be added
|
||||
to an `index.html` file, bypassing any third-party post-processing
|
||||
|
||||
There are known bugs with the SWC minifier (used in Next.js 13+). The original
|
||||
minifier can be enabled by setting `swcMinify: false` in `next.config.js`.
|
||||
|
@ -7,7 +7,7 @@ title: Overview
|
||||
# SheetJS CE
|
||||
|
||||
![License](https://img.shields.io/github/license/SheetJS/sheetjs)
|
||||
[![Build Status](https://img.shields.io/github/workflow/status/sheetjs/sheetjs/Tests:%20node.js)](https://github.com/SheetJS/sheetjs/actions)
|
||||
[![Build Status](https://img.shields.io/github/actions/workflow/status/sheetjs/sheetjs/node-4+.yml?branch=master)](https://github.com/SheetJS/sheetjs/actions/workflows/node-4+.yml)
|
||||
[![Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/SheetJS/sheetjs)](https://snyk.io/test/github/SheetJS/sheetjs)
|
||||
[![npm Downloads](https://img.shields.io/npm/dm/xlsx.svg)](https://cdn.sheetjs.com/)
|
||||
[![GitHub stars](https://img.shields.io/github/stars/SheetJS/sheetjs?style=social)](https://github.com/SheetJS/sheetjs)
|
||||
|
@ -149,8 +149,12 @@ const config = {
|
||||
}
|
||||
}),
|
||||
themes: [
|
||||
"@docusaurus/theme-live-codeblock"
|
||||
"@docusaurus/theme-live-codeblock",
|
||||
"@docusaurus/theme-mermaid"
|
||||
],
|
||||
markdown: {
|
||||
mermaid: true
|
||||
},
|
||||
scripts: [
|
||||
{
|
||||
src: "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"@docusaurus/preset-classic": "2.2.0",
|
||||
"@docusaurus/theme-common": "2.2.0",
|
||||
"@docusaurus/theme-live-codeblock": "2.2.0",
|
||||
"@docusaurus/theme-mermaid": "2.2.0",
|
||||
"@mdx-js/react": "1.6.22",
|
||||
"clsx": "1.2.1",
|
||||
"prism-react-renderer": "1.3.5",
|
||||
|
@ -16,7 +16,7 @@ export default function Index({type, snames}) { return ( <div>
|
||||
Each worksheet maps to a path:<br/><br/>
|
||||
<ul>
|
||||
{snames.map((sname, idx) => (<li key={idx}>
|
||||
<Link href="/sheets/[id]" as={`/sheets/${idx}`}><a>{`Sheet index=${idx} name="${sname}"`}</a></Link>
|
||||
<Link href="/sheets/[id]" as={`/sheets/${idx}`}>{`Sheet index=${idx} name="${sname}"`}</Link>
|
||||
</li>))}
|
||||
</ul>
|
||||
</pre>
|
||||
|
Loading…
Reference in New Issue
Block a user