使用 NextJS 的 ReactJS 站点中的工作表
NextJS 是一个服务器端框架,用于使用 ReactJS 框架构建静态和动态站点。
¥NextJS is a server-side framework for building static and dynamic sites using the ReactJS framework.
SheetJS 是一个用于从电子表格读取和写入数据的 JavaScript 库。
¥SheetJS is a JavaScript library for reading and writing data from spreadsheets.
本讨论涵盖三个关键的 SheetJS + NextJS 操作:
¥This discussion covers three key SheetJS + NextJS operations:
-
加载数据中:NextJS 可以在生命周期方法中读取文件,或者自定义 Webpack 加载器可以创建资源模块。
¥Loading Data: NextJS can read files in lifecycle methods OR custom Webpack loaders can create asset modules.
-
生命周期方法:NextJS 包括静态页面 (
getStaticProps
) 和动态页面 (getServerSideProps
) 的策略。¥Lifecycle Methods: NextJS includes strategies for static pages (
getStaticProps
) as well as dynamic pages (getServerSideProps
). -
数据渲染:页面使用 React 和 JSX。
¥Data Presentation: Pages use React and JSX.
"演示" 使用 NextJS 和 SheetJS 从电子表格中提取数据。我们将探索如何创建在构建时处理电子表格数据的资源模块,以及如何在 NextJS 生命周期方法中读取服务器上的文件。
¥The "Demo" uses NextJS and SheetJS to pull data from a spreadsheet. We'll explore how to create asset modules that process spreadsheet data at build time and how to read files on the server in NextJS lifecycle methods.
NextJS 默认收集遥测数据。telemetry
子命令可以禁用它:
¥NextJS collects telemetry by default. The telemetry
subcommand can disable it:
npx -y next@13.5.6 telemetry disable
可以通过运行来验证设置
¥The setting can be verified by running
npx -y next@13.5.6 telemetry status
该演示重点关注在构建时处理数据文件的静态站点。
¥This demo focuses on static sites where data files are processed at build time.
ReactJS 演示 显示 NextJS "客户端组件"。
¥The ReactJS demo shows NextJS "Client Components".
接下来 13 切换到 SWC 压缩器。缩小器存在已知问题。在这些问题得到解决之前,SWC 应在 next.config.js
中禁用:
¥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
:
module.exports = {
swcMinify: false
};
本 demo 在以下环境下进行了测试:
¥This demo was tested in the following environments:
NextJS | NodeJS | 日期 |
---|---|---|
9.5.5 | 16.20.2 | 2024-06-07 |
10.2.3 | 16.20.2 | 2024-06-07 |
11.1.4 | 16.20.2 | 2024-06-07 |
12.3.4 | 20.14.0 | 2024-06-07 |
13.5.6 | 20.14.0 | 2024-06-07 |
14.2.3 | 20.14.0 | 2024-06-07 |
SheetJS 库可在旧版 NextJS 应用中运行。此演示的旧版本已针对版本 3.2.3
、4.2.3
、5.1.0
、6.1.2
和 7.0.3
进行了测试。
¥SheetJS libraries work in legacy NextJS apps. Older versions of this demo have
been tested against versions 3.2.3
, 4.2.3
, 5.1.0
, 6.1.2
and 7.0.3
.
多年来,NextJS 做出了许多重大改变。旧版本的 NextJS 使用不支持函数组件和其他习语的旧版 ReactJS。
¥NextJS has made a number of breaking changes over the years. Older versions of NextJS use legacy versions of ReactJS that do not support function components and other idioms.
SheetJS git 服务器上的 examples/reactjs-legacy
包含旧版 NextJS 版本的代码示例。
¥examples/reactjs-legacy
on
the SheetJS git server includes code samples for legacy NextJS versions.
加载数据中
¥Loading Data
概括地说,有两种方法可以将电子表格数据提取到 NextJS 应用中:从 NextJS 生命周期方法加载资源模块或执行文件读取操作。
¥At a high level, there are two ways to pull spreadsheet data into NextJS apps: loading an asset module or performing the file read operations from the NextJS lifecycle methods.
当文件名预先已知时,资源模块适用于静态站点。在生命周期方法中执行文件读取操作更加灵活,但不支持实时重新加载。
¥Asset modules are appropriate for static sites when the file names are known in advance. Performing file read operations in lifecycle methods is more flexible but does not support live reloading.
资源模块
¥Asset Module
上次测试演示时,Turbopack 不支持真正的原始加载器。对于开发用途,应使用普通的 npx next dev
。
¥When the demo was last tested, Turbopack did not support true raw loaders. For
development use, the normal npx next dev
should be used.
SheetJS NodeJS 模块 可以导入到 Webpack 资源模块 [^1] 中。
¥The SheetJS NodeJS module can be imported in Webpack asset modules[^1].
下图描绘了练习册华尔兹:
¥The following diagram depicts the workbook waltz:
在此流程中,强烈建议让加载程序返回 Base64 字符串:
¥In this flow, it is strongly recommended to make a loader return a Base64 string:
function loader(content) {
/* since `loader.raw` is true, `content` is a Buffer */
return `export default '${content.toString("base64")}'`;
}
/* ensure the function receives a Buffer */
loader.raw = true;
module.exports = loader;
webpack 配置在 next.config.js
中控制:
¥The webpack configuration is controlled in next.config.js
:
module.exports = {
webpack: (config) => {
/* add to the webpack config module.rules array */
config.module.rules.push({
/* `test` matches file extensions */
test: /\.(numbers|xls|xlsx|xlsb)/,
/* use the loader script */
use: [ { loader: './base64-loader' } ]
});
return config;
}
};
模块别名目录可以在 jsconfig.json
或 tsconfig.json
中定义:
¥Module alias directories can be defined in jsconfig.json
or tsconfig.json
:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["*"]
}
}
}
页面可以直接导入文件。强烈建议将文件存储在 data
文件夹中。
¥Pages can import the files directly. It is strongly recommended to store files
in a data
folder.
在此示例中,导入语句将 sheetjs.xlsx
文件提取为 Base64 字符串。SheetJS read
方法 [^2] 解析字符串并返回工作簿对象 [^3]。sheet_to_json
[^4] 实用程序函数根据数据生成对象数组。只要 base64
变量仅在 getStaticProps
中使用,库和文件就会在构建时进行处理。
¥In this example, the import statement pulls the sheetjs.xlsx
file as a Base64
string. The SheetJS read
method[^2] parses the string and returns a workbook
object[^3]. The sheet_to_json
[^4] utility function generates an array of
objects based on the data. As long as the base64
variable is only used in
getStaticProps
, the library and file will be processed at build time.
import { read, utils } from 'xlsx';
import base64 from '@/data/sheetjs.xlsx';
export async function getStaticProps() {
/* parse base64 data */
const wb = read(base64, { type: "base64" });
return { props: {
/* generate array of objects from the first sheet */
data: utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])
} };
}
原始操作
¥Raw Operations
SheetJS NodeJS 模块 可以从页面脚本导入。
¥The SheetJS NodeJS module can be imported from page scripts.
SheetJS ESM 构建 不直接加载 NodeJS 原生模块。安装部分包含有关在生命周期方法中动态导入 fs
的注释。
¥The SheetJS ESM build
does not load NodeJS native modules directly. The Installation section includes
a note on dynamic import of fs
within lifecycle methods.
可以使用生命周期方法中的 SheetJS readFile
[^5] 方法读取文件。process
模块中的 cwd
方法将指向项目的根目录。
¥Files can be read using the SheetJS readFile
[^5] method in lifecycle methods.
The cwd
method in the process
module will point to the root of the project.
下图描绘了练习册华尔兹:
¥The following diagram depicts the workbook waltz:
本例读取项目中 data
文件夹下的文件 sheetjs.xlsx
,并使用 sheet_to_json
[^6] 生成数据行。
¥This example reads the file sheetjs.xlsx
in the data
folder in the project
and uses sheet_to_json
[^6] to generate data rows.
import { readFile, utils, set_fs } from 'xlsx';
import { join } from 'path';
import { cwd } from 'process';
export async function getServerSideProps() {
set_fs(await import("fs")); // dynamically import 'fs' when needed
const filename = join(cwd(), "data", "sheetjs.xlsx"); // /data/sheetjs.xlsx
const wb = readFile(filename);
/* generate and return the html from the first worksheet */
const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
return { props: { data } };
}
由于 NextJS 解决方法是非传统的,因此值得重复:
¥As the NextJS workaround is non-traditional, it bears repeating:
fs
无法从 NextJS 页面的顶层静态导入。动态导入必须发生在生命周期函数内。
¥fs
cannot be statically imported from the top level in NextJS pages. The
dynamic import must happen within a lifecycle function.
NextJS 策略
¥NextJS Strategies
NextJS 目前提供了 3 种策略:
¥NextJS currently provides 3 strategies:
-
"静态站点生成" 使用
getStaticProps
[^7]¥"Static Site Generation" using
getStaticProps
[^7] -
"具有动态路由的 SSG" 使用
getStaticPaths
[^8]¥"SSG with Dynamic Routes" using
getStaticPaths
[^8] -
"服务器端渲染" 使用
getServerSideProps
[^9]¥"Server-Side Rendering" using
getServerSideProps
[^9]
静态站点生成
¥Static Site Generation
当使用 getStaticProps
时,该文件将在构建期间被读取一次。此示例从 data
文件夹中读取 sheetjs.xlsx
:
¥When using getStaticProps
, the file will be read once during build time.
This example reads sheetjs.xlsx
from the data
folder:
- Asset Module
- Raw Operations
import { read, utils } from 'xlsx';
import base64 from '@/data/sheetjs.xlsx';
export async function getStaticProps() {
const wb = read(base64, { type: "base64" });
/* generate and return the html from the first worksheet */
const html = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
return { props: { html } };
};
import { readFile, set_fs, utils } from 'xlsx';
import { join } from 'path';
import { cwd } from 'process';
export async function getStaticProps() {
set_fs(await import("fs"));
const filename = join(cwd(), "data", "sheetjs.xlsx"); // /data/sheetjs.xlsx
const wb = readFile(filename);
/* generate and return the html from the first worksheet */
const html = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
return { props: { html } };
};
动态路由
¥Dynamic Routes
通常,具有动态路由的静态站点具有同时实现 getStaticPaths
和 getStaticProps
的端点 /sheets/[id]
。
¥Typically a static site with dynamic routes has an endpoint /sheets/[id]
that
implements both getStaticPaths
and getStaticProps
.
-
getStaticPaths
应返回工作表索引数组:¥
getStaticPaths
should return an array of worksheet indices:
- Asset Module
- Raw Operations
import { read } from 'xlsx';
import base64 from '@/data/sheetjs.xlsx';
export async function getStaticPaths() {
/* read file */
const wb = read(base64, { type: "base64" });
/* generate an array of objects that will be used for generating pages */
const paths = wb.SheetNames.map((name, idx) => ({ params: { id: idx.toString() } }));
return { paths, fallback: false };
};
import { readFile, set_fs } from 'xlsx';
import { join } from 'path';
import { cwd } from 'process';
export async function getStaticPaths() {
/* read file */
set_fs(await import("fs"));
const filename = join(cwd(), "data", "sheetjs.xlsx"); // /data/sheetjs.xlsx
const wb = readFile(path);
/* generate an array of objects that will be used for generating pages */
const paths = wb.SheetNames.map((name, idx) => ({ params: { id: idx.toString() } }));
return { paths, fallback: false };
};
对于纯静态站点,fallback
必须设置为 false
![^10]
¥For a pure static site, fallback
must be set to false
![^10]
-
getStaticProps
将为每个页面生成实际的 HTML:¥
getStaticProps
will generate the actual HTML for each page:
- Asset Module
- Raw Operations
import { read, utils } from 'xlsx';
import base64 from '@/data/sheetjs.xlsx';
export async function getStaticProps(ctx) {
/* read file */
const wb = read(base64, { type: "base64" });
/* get the corresponding worksheet and generate HTML */
const ws = wb.Sheets[wb.SheetNames[ctx.params.id]]; // id from getStaticPaths
const html = utils.sheet_to_html(ws);
return { props: { html } };
};
import { readFile, set_fs, utils } from 'xlsx';
import { join } from 'path';
import { cwd } from 'process';
export async function getStaticProps(ctx) {
/* read file */
set_fs(await import("fs"));
const filename = join(cwd(), "data", "sheetjs.xlsx"); // /data/sheetjs.xlsx
const wb = readFile(path);
/* get the corresponding worksheet and generate HTML */
const ws = wb.Sheets[wb.SheetNames[ctx.params.id]]; // id from getStaticPaths
const html = utils.sheet_to_html(ws);
return { props: { html } };
};
服务器端渲染
¥Server-Side Rendering
这些路由需要 NodeJS 动态服务器。静态页面生成会失败!
¥These routes require a NodeJS dynamic server. Static page generation will fail!
getStaticProps
和 getStaticPaths
支持静态站点生成 (SSG)。
¥getStaticProps
and getStaticPaths
support static site generation (SSG).
getServerSideProps
适合 NodeJS 托管部署,其中工作簿经常更改并且不需要静态站点。
¥getServerSideProps
is suited for NodeJS hosted deployments where the workbook
changes frequently and a static site is undesirable.
使用 getServerSideProps
时,将在每次请求时读取该文件。
¥When using getServerSideProps
, the file will be read on each request.
- Asset Module
- Raw Operations
使用资源模块时,文件名和文件路径会在构建步骤中进行处理。内容是固定的。在这种情况下,强烈建议使用静态方法,例如 getStaticProps
。
¥When using asset modules, the file names and file paths are processed during the
build step. The content is fixed. In this situation, a static approach such as
getStaticProps
is strongly recommended.
import { read } from 'xlsx';
import base64 from '@/data/sheetjs.xlsx';
export async function getServerSideProps() {
/* read file */
const wb = read(base64, { type: "base64" });
/* generate and return the html from the first worksheet */
const html = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
return { props: { html } };
};
import { readFile, set_fs, utils } from 'xlsx';
import { join } from 'path';
import { cwd } from 'process';
export async function getServerSideProps() {
/* read file */
set_fs(await import("fs"));
const filename = join(cwd(), "data", "sheetjs.xlsx"); // /data/sheetjs.xlsx
const wb = readFile(path);
/* generate and return the html from the first worksheet */
const html = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
return { props: { html } };
};
数据渲染
¥Data Presentation
ReactJS 演示 比较了常见的方法。
¥The ReactJS demo compares common approaches.
HTML
可以使用 SheetJS sheet_to_html
[^11] 方法生成 HTML 输出,并使用 dangerouslySetInnerHTML
[^12] 属性插入到文档中:
¥HTML output can be generated using the SheetJS sheet_to_html
[^11] method and
inserted into the document using the dangerouslySetInnerHTML
[^12] attribute:
export default function Index({html, type}) { return (
<div dangerouslySetInnerHTML={{ __html: html }} />
); }
对象数组
¥Arrays of Objects
可以使用 SheetJS sheet_to_json
[^13] 方法生成对象数组,并使用标准 JSX[^14] 插入到文档中:
¥Arrays of objects can be generated using the SheetJS sheet_to_json
[^13] method
and inserted into the document using standard JSX[^14]:
export default function Index({aoo, type}) { return (
<table><thead><tr key={0}><th>Name</th><th>Index</th></tr></thead><tbody>
{aoo.map(row => ( <tr>
<td>{row.Name}</td>
<td>{row.Index}</td>
</tr>))}
</tbody></table>
); }
演示
¥Demo
该演示展示了以下 SheetJS + NextJS 流程:
¥This demo showcases the following SheetJS + NextJS flows:
页 | 加载数据中 | 生命周期法 | SheetJS API |
---|---|---|---|
/getStaticProps | 资源模块 | getStaticProps | sheet_to_json |
/sheets/[id] | 资源模块 | getStaticPaths | sheet_to_html |
/getServerSideProps | lifecycle | getServerSideProps | sheet_to_html |
本演示中的命令使用 next@13.5.6
。其他版本通过替换相关命令中的版本号进行测试。
¥The commands in this demo use next@13.5.6
. Other versions were tested by
replacing the version number in the relevant commands.
旧版本的 NextJS 将拒绝在新版本的 NodeJS 中运行。该错误消息指出 OpenSSL 存在问题:
¥Older versions of NextJS will refuse to run in newer versions of NodeJS. The error message points to an issue with OpenSSL:
Error: error:0308010C:digital envelope routines::unsupported
当无法升级 NextJS 时,NodeJS 应降级至 v16。
¥When upgrading NextJS is not an option, NodeJS should be downgraded to v16.
初始设置
¥Initial Setup
-
禁用 NextJS 遥测:
¥Disable NextJS telemetry:
npx -y next@13.5.6 telemetry disable
通过运行确认它已被禁用
¥Confirm it is disabled by running
npx -y next@13.5.6 telemetry status
-
设置文件夹结构。最后,必须创建一个带有
sheets
子文件夹的pages
文件夹。在 Linux 或 MacOS 或 WSL 上:¥Set up folder structure. At the end, a
pages
folder with asheets
subfolder must be created. On Linux or MacOS or WSL:
mkdir sheetjs-next
cd sheetjs-next
mkdir -p pages/sheets/
-
下载 测试文件 并将其放置在项目根目录中。在 Linux 或 MacOS 或 WSL 上:
¥Download the test file and place in the project root. On Linux or MacOS or WSL:
curl -LO https://xlsx.nodejs.cn/next/sheetjs.xlsx
-
安装依赖:
¥Install dependencies:
可以调整 next@13.5.6
依赖以选择不同的版本。例如,NextJS 12.3.4
安装有
¥The next@13.5.6
depefndency can be adjusted to pick a different version. For
example, NextJS 12.3.4
is installed with
npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz next@12.3.4
npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz next@13.5.6
-
下载 NextJS 配置脚本并将其放置在根文件夹中:
¥Download NextJS config scripts and place in the root folder:
在 Linux 或 MacOS 或 WSL 上:
¥On Linux or MacOS or WSL:
curl -LO https://xlsx.nodejs.cn/next/base64-loader.js
curl -LO https://xlsx.nodejs.cn/next/jsconfig.json
curl -LO https://xlsx.nodejs.cn/next/next.config.js
curl -LO https://xlsx.nodejs.cn/next/styles.css
-
下载测试脚本:
¥Download test scripts:
下载以下脚本并将其放入 pages
子文件夹中:
¥Download and place the following scripts in the pages
subfolder:
下载 [id].js
并将其放置在 pages/sheets
子文件夹中。
¥Download [id].js
and place in the
pages/sheets
subfolder.
[id].js
脚本的名称中必须包含字面量方括号。如果你的浏览器将文件保存到 %5Bid%5D.js
。重命名该文件。
¥The [id].js
script must have the literal square brackets in the name. If your
browser saved the file to %5Bid%5D.js
. rename the file.
在 Linux 或 MacOS 或 WSL 上:
¥On Linux or MacOS or WSL:
cd pages
curl -LO https://xlsx.nodejs.cn/next/_app.js
curl -LO https://xlsx.nodejs.cn/next/index.js
curl -LO https://xlsx.nodejs.cn/next/getServerSideProps.js
curl -LO https://xlsx.nodejs.cn/next/getStaticPaths.js
curl -LO https://xlsx.nodejs.cn/next/getStaticProps.js
cd sheets
curl -LOg 'https://xlsx.nodejs.cn/next/[id].js'
cd ../..
测试
¥Testing
-
测试部署:
¥Test the deployment:
npx next
打开网络浏览器并访问:
¥Open a web browser and access:
-
http://localhost:3000
着陆页¥
http://localhost:3000
landing page -
http://localhost:3000/getStaticProps
显示第一张表中的数据¥
http://localhost:3000/getStaticProps
shows data from the first sheet -
http://localhost:3000/getServerSideProps
显示第一张表中的数据¥
http://localhost:3000/getServerSideProps
shows data from the first sheet -
http://localhost:3000/getStaticPaths
显示列表(2 张)¥
http://localhost:3000/getStaticPaths
shows a list (2 sheets)
单独的工作表可在
¥The individual worksheets are available at
-
http://localhost:3000/sheets/0
-
http://localhost:3000/sheets/1
-
当开发服务器运行时,打开
/getStaticProps
页面并使用电子表格编辑器打开sheetjs.xlsx
。在编辑器中,在 "指数" 工作表的底部添加一行(将A7
设置为 "SheetJS 开发",将B7
设置为47
)¥While the development server is running, open the
/getStaticProps
page and opensheetjs.xlsx
with a spreadsheet editor. In the editor, add a row to the bottom of the "Indices" worksheet (setA7
to "SheetJS Dev" andB7
to47
)
保存文件后,网站应刷新新行。
¥After saving the file, the website should refresh with the new row.
生产构建
¥Production Build
-
停止服务器并运行生产构建:
¥Stop the server and run a production build:
npx next build
最终输出将显示路由和类型的列表:
¥The final output will show a list of the routes and types:
Route (pages) Size First Load JS
┌ ○ / 563 B 75.3 kB
├ /_app 0 B 74.8 kB
├ ○ /404 182 B 75 kB
├ λ /getServerSideProps 522 B 75.3 kB
├ ● /getStaticPaths 2.91 kB 77.7 kB
├ ● /getStaticProps 586 B 75.4 kB
└ ● /sheets/[id] (303 ms) 522 B 75.3 kB
├ /sheets/0
└ /sheets/1
正如摘要中所解释的,/getStaticPaths
和 /getStaticProps
路由是完全静态的。生成了 2 个 /sheets/#
页,对应于文件中的 2 个工作表。/getServerSideProps
是服务器渲染的。
¥As explained in the summary, the /getStaticPaths
and /getStaticProps
routes
are completely static. 2 /sheets/#
pages were generated, corresponding to 2
worksheets in the file. /getServerSideProps
is server-rendered.
NextJS 历来使用小写 Lambda(λ
)来表示动态路径。在 NextJS 的最新版本中,它已更改为风格化的小写 F (ƒ
)。
¥NextJS historically used lowercase Lambda (λ
) to denote dynamic paths. This
was changed to a stylized lowercase F (ƒ
) in recent versions of NextJS.
-
尝试建立一个静态站点:
¥Try to build a static site:
- NextJS 9 - 13
- NextJS 14
npx next export
NextJS 14 删除了 export
子命令!
¥NextJS 14 removed the export
subcommand!
编辑 next.config.js
并添加高亮的行:
¥Edit next.config.js
and add the highlighted line:
module.exports = {
output: "export",
webpack: (config) => {
添加该行后,运行 build
命令:
¥After adding the line, run the build
command:
npx next build
此构建将会失败。此时无法生成静态页面,因为 /getServerSideProps
是服务器渲染的。
¥This build will fail. A static page cannot be generated at this point because
/getServerSideProps
is server-rendered.
静态站点
¥Static Site
-
删除
pages/getServerSideProps.js
:¥Delete
pages/getServerSideProps.js
:
rm -f pages/getServerSideProps.js
-
重建静态站点:
¥Rebuild the static site:
- NextJS 9 - 13
- NextJS 14
编辑 next.config.js
并注释高亮的行:
¥Edit next.config.js
and comment the highlighted line:
module.exports = {
// output: "export",
webpack: (config) => {
编辑 next.config.js
后,运行构建命令:
¥After editing next.config.js
, run the build command:
npx next build
检查输出,不应有带有 λ
或 ƒ
的行:
¥Inspecting the output, there should be no lines with λ
or ƒ
:
Route (pages) Size First Load JS
┌ ○ / 563 B 75.3 kB
├ /_app 0 B 74.8 kB
├ ○ /404 182 B 75 kB
├ ● /getStaticPaths 2.91 kB 77.7 kB
├ ● /getStaticProps 586 B 75.4 kB
└ ● /sheets/[id] 522 B 75.3 kB
├ /sheets/0
└ /sheets/1
-
生成静态站点:
¥Generate the static site:
- NextJS 9 - 13
- NextJS 14
npx next export
编辑 next.config.js
并恢复高亮的行:
¥Edit next.config.js
and restore the highlighted line:
module.exports = {
output: "export",
webpack: (config) => {
添加该行后,运行 build
命令:
¥After adding the line, run the build
command:
npx next build
静态站点将写入 out
子文件夹
¥The static site will be written to the out
subfolder
-
提供静态站点:
¥Serve the static site:
npx http-server out
该命令将在 http://localhost:8080/
启动本地 HTTP 服务器以测试生成的站点。请注意,由于页面被删除,/getServerSideProps
将返回 404。
¥The command will start a local HTTP server at http://localhost:8080/
for
testing the generated site. Note that /getServerSideProps
will 404 since the
page was removed.
[^1]: 有关详细信息,请参阅 "Webpack" 资源模块演示。
¥See the "Webpack" asset module demo for more details.
[^2]: 参见 read
于 "读取文件"。
¥See read
in "Reading Files".
[^3]: 详细信息请参见 "SheetJS 数据模型"。
¥See "SheetJS Data Model" for more details.
[^4]: 参见 sheet_to_json
于 "实用工具"。
¥See sheet_to_json
in "Utilities".
[^5]: 参见 readFile
于 "读取文件"。
¥See readFile
in "Reading Files".
[^6]: 参见 sheet_to_json
于 "实用工具"。
¥See sheet_to_json
in "Utilities".
[^7]: 请参阅 NextJS 文档中的 getStaticProps
。
¥See getStaticProps
in the NextJS documentation.
[^8]: 请参阅 NextJS 文档中的 getStaticPaths
。
¥See getStaticPaths
in the NextJS documentation.
[^9]: 请参阅 NextJS 文档中的 getServerSideProps
。
¥See getServerSideProps
in the NextJS documentation.
[^10]: 请参阅 NextJS 文档中的 getStaticPaths 中的 fallback
。
¥See fallback
in getStaticPaths in the NextJS documentation.
[^11]: 见 sheet_to_html
于 "实用工具"
¥See sheet_to_html
in "Utilities"
[^12]: dangerouslySetInnerHTML
是所有内置组件都支持的 ReactJS prop。
¥dangerouslySetInnerHTML
is a ReactJS prop supported for all built-in components.
[^13]: 参见 sheet_to_json
于 "实用工具"。
¥See sheet_to_json
in "Utilities".
[^14]: 参见 ReactJS 演示中的 "对象数组"。