Skip to main content

使用 SystemJS 打包工作表

SystemJS[^1] 是 NodeJS 和浏览器的模块加载器。

¥SystemJS[^1] is a module loader for NodeJS and browsers.

SheetJS 是一个用于从电子表格读取和写入数据的 JavaScript 库。

¥SheetJS is a JavaScript library for reading and writing data from spreadsheets.

该演示使用 SystemJS 和 SheetJS 导出数据。我们将探讨两个工作流程:

¥This demo uses SystemJS and SheetJS to export data. We'll explore two workflows:

  • "浏览器" 探索如何使用浏览器内动态加载器通过 SystemJS 加载 SheetJS

    ¥"Browser" explores how to load SheetJS with SystemJS using the in-browser dynamic loader

  • "NodeJS" 探讨了如何在 NodeJS 中使用 SystemJS 加载 SheetJS。

    ¥"NodeJS" explores how to load SheetJS with SystemJS in NodeJS.

该演示最初是为 SystemJS 0.19 编写的,这是 Angular 项目中使用的最流行的 SystemJS 版本。自发布以来的几年里,Angular 和其他使用 SystemJS 的工具已经转向 Webpack。

¥This demo was originally written for SystemJS 0.19, the most popular SystemJS version used with Angular projects. In the years since the release, Angular and other tools using SystemJS have switched to Webpack.

该演示重点介绍与 SystemJS 加载器的集成细节。

¥This demo focuses on integration details with the SystemJS loader.

这些演示遵循 "导出教程",其中更详细地介绍了 SheetJS 库的用法。

¥The demos follow the "Export Tutorial", which covers SheetJS library usage in more detail.

测试部署

本 demo 在以下环境下进行了测试:

¥This demo was tested in the following environments:

版本平台日期
0.19.47NodeJS2024-03-31
0.20.16浏览器2024-03-31
0.20.19NodeJS2024-03-31
0.21.6NodeJS2024-03-31
6.14.3NodeJS2024-03-31

浏览器

¥Browser

在线演示 从 CDN 加载 SystemJS,使用它从 SheetJS CDN 加载独立脚本,并在加载 main.js 时模拟 require 实现

¥The Live demo loads SystemJS from the CDN, uses it to load the standalone script from the SheetJS CDN and emulate a require implementation when loading main.js

"查看源代码" 在 HTML 主页面和 main.js 脚本上运行。

¥"View Source" works on the main HTML page and the main.js script.

SystemJS 默认失败,因为该库不会在 Web 浏览器中导出任何内容。meta 配置选项可用于公开 XLSX

¥SystemJS fails by default because the library does not export anything in the web browser. The meta configuration option can be used to expose XLSX:

SystemJS.config({
meta: {
'xlsx': {
exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
}
},
map: {
'xlsx': 'https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js',
'fs': '', // <--|
'crypto': '', // <--| suppress native node modules
'stream': '' // <--|
}
});
SystemJS.import('main.js'); // load `main.js`

通过此导入,main.js 脚本可以自由地 require("xlsx")

¥With this import, the main.js script can freely require("xlsx").

Web Worker

Web Workers 可以使用 importScripts 加载 SystemJS 库,但导入的代码无法分配原始 Worker 的 onmessage 回调。推荐的方法是从所需的脚本中公开一个全局变量,例如,假设共享名称是 _cb,主工作脚本将调用回调:

¥Web Workers can load the SystemJS library with importScripts, but the imported code cannot assign the original worker's onmessage callback. The recommended approach is to expose a global from the required script, For example, supposing the shared name is _cb, the primary worker script would call the callback:

worker.js
/* main worker script */
importScripts('system.js');

SystemJS.config({ /* ... browser config ... */ });

onmessage = function(evt) {
SystemJS.import('workermain.js').then(function() { _cb(evt); });
};

工作脚本将定义并公开该函数:

¥The worker script would define and expose the function:

workermain.js
/* Loaded with SystemJS import */
var XLSX = require('xlsx');

_cb = function(evt) { /* ... do work here ... */ };

NodeJS

强烈建议尽可能使用 NodeJS require 方法。

¥It is strongly recommended to use the NodeJS require method when possible.

该演示与使用 SystemJS NodeJS 加载器的旧项目相关。

¥This demo is relevant for legacy projects that use the SystemJS NodeJS loader.

老式

¥Old Style

NodeJS 模块主脚本是 xlsx/xlsx.js,应该映射:

¥The NodeJS module main script is xlsx/xlsx.js and should be mapped:

SystemJS.config({
map: {
"xlsx": "./node_modules/xlsx/xlsx.js"
}
});

独立脚本可能是必需的,但 SystemJS 配置必须包含脚本分配全局的提示:

¥The standalone scripts can be required, but SystemJS config must include a hint that the script assigns a global:

SystemJS.config({
meta: {
"standalone": { format: "global" }
},
map: {
"standalone": "xlsx.full.min.js"
}
});

新风格

¥New Style

较新版本的 SystemJS 支持 "导入映射" 到 applyImportMap

¥Newer versions of SystemJS supports "import maps" through applyImportMap:

const SystemJS = require('systemjs');
const src = require("path").join(process.cwd(), 'node_modules/xlsx/xlsx.js');
SystemJS.applyImportMap(SystemJS.System, {
imports: {
'xlsx': "file://" + src,
'fs': 'node:fs',
'crypto': 'node:crypto',
'stream': 'node:stream'
}
});

`

在现代风格中,导入名称 XLSX 会引起冲突。

¥In the modern style, importing to the name XLSX will cause conflicts.

强烈建议以 _XLSX 名称导入!

¥It is strongly recommended to import to the name _XLSX!

SystemJS.System.import("xlsx").then(function(
_XLSX // use _XLSX instead of XLSX
) {
if(typeof XLSX == "undefined") throw "Import failed!";

// XLSX is defined here
console.log(XLSX.version);
});

NodeJS 演示

¥NodeJS Demo

  1. 准备一个空白项目:

    ¥Prepare a blank project:

mkdir sheetjs-systemjs
cd sheetjs-systemjs
npm init -y
  1. 安装依赖:

    ¥Install the dependencies:

npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz systemjs@6.14.3
  1. 下载 SheetJSystem.js 并移至项目文件夹:

    ¥Download SheetJSystem.js and move to the project folder:

curl -LO https://xlsx.nodejs.cn/systemjs/SheetJSystem.js

该脚本处理旧式和新式 SystemJS 加载器。

¥The script handles old-style and new-style SystemJS loaders.

  1. 在 NodeJS 中运行:

    ¥Run in NodeJS:

node SheetJSystem.js

如果演示成功,将会创建 Presidents.xlsx

¥If the demo worked, Presidents.xlsx will be created.

由于它使用 fetch,因此该演示需要 Node 18。

¥As it uses fetch, this demo requires Node 18.

[^1]: 该项目没有单独的网站。源存储库托管在 GitHub

¥The project does not have a separate website. The source repository is hosted on GitHub