如何解决在 Node 模块中,如何分块导出模块,以便可以根据需要分块导入 test_all.jstest_500ms.js
这是很难向 Google 表达的那些相当简单的问题之一:我有一个 Node 模块,我想将其分块导出,以便可以根据用户需要的数量分块导入,其中有对文件大小有重大影响。
我的小模块叫做 Piano-Notes,它导出一个 88 长的简单对象数组,描述钢琴上的每个键。
除此之外,我还下载了由爱荷华大学电子音乐工作室提供的 high-quality,public-domain samples from a Steinway,每个文件的大小约为 10MB .aiff
。 (这些不包含在 repo 中,但可以使用 shell 脚本下载——请参阅 README。然后我执行以下转换(也可作为 repo 中的 shell 和 Node 脚本):
-
使用
ffmpeg
,我将每个样本减少到 500 毫秒、1000 毫秒和 2000 毫秒的mp3
(同时还消除了原件中的少量初始静音),这很有用,因为不同的应用程序会需要不同的持续时间。每个音符的样本现在分别为 9KB、17KB 和 33KB。 -
使用 Node,我将样本加载到缓冲区中,将它们转换为 base64,然后将它们捆绑到 one composite JSON file for each duration 中。这些文件为 1MB(500 毫秒)、2MB(1000 毫秒)和 3.9MB(2000 毫秒)。这消除了用户下载一堆 mp3 并找出如何让模块定位它们的需要。
-
这是我遇到麻烦的地方:用户应该能够选择她想要的三个样本中的多少,只导入那些,并将它们加载到音符数组中,这样每个都有一个
.play
方法。后一部分在 Notes object's.loadAudio
方法中工作正常。
问题是我的测试都拉入了所有三个样本,生成了 7MB 的文件。我认为这会奏效(在 ./lib/Audio.js 中):
const AUdio = {
500: require("../data/audio/audio_500.json"),1000: require("../data/audio/audio_1000.json"),2000: require("../data/audio/audio_2000.json")
}
const Piano_500 = { duration: 500,notes: AUdio[500] };
const Piano_1000 = { duration: 1000,notes: AUdio[1000] };
const Piano_2000 = { duration: 2000,notes: AUdio[2000] };
export { Piano_500,Piano_1000,Piano_2000 }
但是,我有 two tests,其中一个导入了所有三个,另一个只导入了 500ms 样本:
test_all.js
import { Notes } from '../lib/Notes';
import { Piano_500,Piano_2000 } from '../lib/Audio';
/* load samples into a `Notes` instance and export
export default notes;
test_500ms.js
import { Notes } from '../lib/Notes';
import { Piano_500 } from '../lib/Audio';
/* likewise */
export default notes;
这两个测试都会生成一个 7MB 的文件。理想情况下,第二个大约为 1MB,因为它只会加载 500 毫秒样本的 JSON 文件。
显然我没有完全理解 imports
和 exports
的工作原理。 (我不认为我是唯一的一个。)我猜这是因为上面的 ./lib/Audio.js
文件需要所有三个,即使它分别导出它们。如何正确编写像 Audio.js
这样的导出中间件,以便一个文件可以加载一个模块的所有部分,根据需要将它们分开,然后 export
这些部分用于按需 import
?
(我认为这是处理整个项目的愚蠢方式,而且 mp3 都应该根据需要加载,但这仍然是我应该理解的东西!)
解决方法
在普通的 node.js 中,一个模块被一次完全导入,无论导出中有多少个单独的入口点。将其分解以便可以独立加载较小的部分的唯一方法是将其分解为单独的模块,以便 API 的客户端可以仅加载他们想要加载的模块。
但是,要成功地保持模块负载更小,您必须确保您自己的模块不会每个都拉入很多其他东西或大部分其他东西。为了实现客户端只能成功加载他们真正想要的东西并且是高效和小负载的结果,那么你需要非常仔细的内部模块设计。这是一个代码共享(有很多不同的代码段都共享东西)往往会非常复杂地实现小的、部分加载的地方,因为 API 的使用者很容易加载一个模块,但是对于它来说在内部完成它的工作,它最终会引入您在内部共享的许多其他模块。这是可以做到的,但需要非常仔细的设计,并且需要能够准确衡量每次客户端导入的加载大小所达到的目标。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。