Javascript 在节点模块中,如何以部分形式导出模块,以便可以根据需要以部分形式导入

Javascript 在节点模块中,如何以部分形式导出模块,以便可以根据需要以部分形式导入,javascript,node.js,import,export,node-modules,Javascript,Node.js,Import,Export,Node Modules,这是一个很难向谷歌表达的相当简单的问题:我有一个节点模块,我想将其分块导出,这样就可以根据用户需要的数量分块导入,这对文件大小有很大影响 我的小模块叫做,它导出一个88长度的简单对象数组,描述钢琴上的每个键 在上面,我下载了爱荷华大学电子音乐工作室,每个都是~10MB AIFF 文件。(这些不包括在repo中,但可以通过shell脚本下载——请参阅。然后执行以下转换(也可以作为repo中的shell和节点脚本提供): 使用ffmpeg,我将每个样本压缩为500ms、1000ms和2000ms

这是一个很难向谷歌表达的相当简单的问题:我有一个节点模块,我想将其分块导出,这样就可以根据用户需要的数量分块导入,这对文件大小有很大影响

我的小模块叫做,它导出一个88长度的简单对象数组,描述钢琴上的每个键

在上面,我下载了爱荷华大学电子音乐工作室,每个都是~10MB <代码> AIFF 文件。(这些不包括在repo中,但可以通过shell脚本下载——请参阅。然后执行以下转换(也可以作为repo中的shell和节点脚本提供):

  • 使用
    ffmpeg
    ,我将每个样本压缩为500ms、1000ms和2000ms的
    mp3
    (同时也消除了原稿中的一个小的初始静音),这很有用,因为不同的应用程序需要不同的持续时间。每个音符的样本现在分别为9KB、17KB和33KB

  • 使用Node,我将样本加载到一个缓冲区,将其转换为base64,并将其绑定到。这些文件的大小分别为1MB(500ms)、2MB(1000ms)和3.9MB(2000ms)。这样,用户无需下载大量MP3,也无需了解如何让模块找到它们

  • 这就是我遇到的问题:用户应该能够选择她想要的三个示例中的多少,只导入这些示例,然后将它们加载到notes数组中,这样每个示例都有一个
    .play
    方法。后一部分在
    .loadAudio
    方法中工作正常

问题是,我的测试都在拉取所有三个样本,生成7MB文件。我认为这会起作用(在:

但是,我有,其中一个导入所有三个,其中一个只导入500毫秒样本:

test_all.js 测试_500ms.js 这两个测试都会产生一个7MB的文件。理想情况下,第二个测试大约是1MB,因为它只会加载500ms样本的JSON文件

显然,我没有完全掌握
导入
导出
的工作原理。(我不认为我是唯一一个。)我的猜测是,这是因为上面的
/lib/Audio.js
文件需要这三个部分,即使它分别导出它们。
如何正确地编写导出中间件,如
Audio.js
,以便一个文件可以加载模块的所有部分,根据需要将它们分割,然后
导出这些部分是否根据需要导入


(我愿意接受这样的观点,即这是处理整个项目的一种愚蠢的方式,应该根据需要加载所有MP3,但这仍然是我应该理解的!)

在plain node.js中,无论导出中有多少个单独的入口点,模块都是一次完全导入的。分解模块以使较小的部分可以独立加载的唯一方法是将其分解为单独的模块,这样API的客户端就可以加载他们想要加载的模块


但是,要成功地保持模块负载较小,您必须确保您自己的模块不会每个都引入大量其他内容或您自己的大部分其他内容。要实现这样一个结果,即客户端只能成功加载他们真正需要的内容,并且这是一个高效且小的负载,则需要非常小心的internal模块设计。这是一个代码共享的地方(有很多不同的代码片段,所有的东西都共享)往往会使实现小的、部分的加载变得非常复杂,因为API的使用者很容易只加载一个模块,但如果要在内部执行其工作,它最终会引入许多您在内部共享的其他模块。这是可以做到的,但需要非常仔细的设计和精确测量功能每个客户端导入的加载大小都达到了。

这意味着什么:“这两个测试都会生成一个7MB的文件。”?什么文件?您具体测量的是什么?测试/构建中的文件是运行
npm run test
的产物,其中一个应该比其他有趣的文件小得多。请参考“plain Node.js”我的测试实际上使用的是一个普通配置的外部Web包构建,因此理想情况下会有一些树震动,但我从来没有完全理解(甚至大部分理解)它是如何工作的。这有关系吗?@ChrisWilson-是的,我使用了术语“普通节点”明确地说,因为绑定器可以尝试隔离它们构建的世界中的部分代码,但是你没有把这部分内容作为问题的一部分,所以我避免讨论它。但是,如果这是一个API,那么必须由API的用户进行正确的绑定,以便只对它们需要的部分进行筛选。对于或者是因为只有他们的环境指定了他们在使用什么和不使用什么。明白——无论如何,我想在plain Node.js中理解这一点。我将音频中间件分为三个文件,它可以正常工作。似乎应该有更好的解决方案,但我认为这是目前最好的方法?@ChrisWilson-这是正确的t、 如果终端应用程序没有支持树震动功能的捆绑程序,那么使代码的子部分可加载的唯一方法就是将其分解为单独的模块文件,并在其中单独导出,确保模块文件可以独立运行,而无需提取其他代码。
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 }
import { Notes } from '../lib/Notes';
import { Piano_500, Piano_1000, Piano_2000 } from '../lib/Audio';

/* load samples into a `Notes` instance and export
export default notes;
import { Notes } from '../lib/Notes';
import { Piano_500 } from '../lib/Audio';

/* likewise */ 
export default notes;