目标 我是一个 JavaScript 库的作者,该库可以通过 AMD 或 ESM 在各种运行时环境(浏览器、Node.js、开发服务器)中使用。我的库需要使用它包含的文件生成 WebWorkers 和 AudioWorklets。该库检测它在哪个上下文中运行并为执行上下文设置所需的内容。
只要用户(我的库的用户 = 集成商)不将 WebPack 之类的捆绑程序带入游戏,这就可以正常工作。要生成 WebWorker 和 AudioWorklet,我需要包含我的库的文件的 URL,并且我需要确保调用我的库的全局初始化例程。
我希望尽可能多地在我的库中完成繁重的工作,而不是要求用户只为使用我的库进行非常专业的自定义设置。将这项工作交给他们通常会立即适得其反,人们会打开问题寻求帮助,将我的库集成到他们的项目中。
问题 1:我建议我的用户确保将我的库放入自己的块中。用户可以根据自己的设置来设置块,只要其他库不会对工作人员造成任何麻烦或副作用。尤其是像 React、Angular 和 Vue.js 这样的现代 Web 框架是这里典型的问题儿童,但人们也试图将我的库与 jQuery 和 Bootstrap 捆绑在一起。所有这些库在包含在 Workers/Worklets 中时都会导致运行时错误。
分块通常使用一些 WebPack 配置完成,例如:
config.optimization.splitChunks.cacheGroups.alphatab = {
chunks: 'all',
name: 'chunk-mylib',
priority: config.optimization.splitChunks.cacheGroups.defaultVendors.priority + 10,
test: /.*node_modules.*mylib.*/
};
mylib 现在有一个大问题:生成的绝对 URL 是什么,chunk-mylib.js
因为它现在是我的库的准入口点,现在捆绑和代码拆分到位:
document.currentScript
通常指向某个入口点,例如 anapp.js
而不是块。__webpack_public_path__
指向用户在 webpack 配置中设置的任何内容。__webpack_get_script_filename__
如果块名称已知,则可以使用,但我还没有找到一种方法来获取包含我的库的块的名称。import.meta.url
指向我的图书馆file://
原件的一些绝对网址。.mjs
new URL(import.meta.url, import.meta.url)
导致 WebPack 生成.mjs
带有一些哈希的附加文件。这个额外的文件是不需要的,并且生成的文件还.mjs
包含一些额外的代码,破坏了它在浏览器中的使用。
我已经在考虑创建一个自定义 WebPack 插件,它可以解析我的库包含的块,以便我可以在运行时使用它。我希望尽可能多地使用内置功能。
问题 2:假设问题 1 已解决,我现在可以使用正确的文件生成一个新的 WebWorker 和 AudioWorklet。但是由于我的库被包装到一个 WebPack 模块中,我的初始化代码将不会被执行。我的库只存在于一个“块”中,而不是一个entry
,而且我不知道这种拆分将允许 mylib 在浏览器加载块后运行一些代码。
在这里,我很无知。也许块不是为此目的的正确拆分方式。也许需要一些其他设置我还不知道它可能吗?
也许这也可以通过自定义 WebPack 插件来完成。
问题的视觉表示:使用建议的分块规则,我们得到如块所示的输出。问题 1 是红色部分(如何获取此 URL),问题 2 是橙色部分(如何确保在后台 worker/worklet 启动时调用我的启动逻辑)
实际项目我想分享我的实际项目,以便更好地了解我的用例。我说的是我的项目alphaTab,一个音乐符号渲染和播放库。在浏览器 UI 线程 (app.js) 上,人们将组件集成到 UI 中,并获得一个 API 对象来与组件交互。一个 WebWorker 进行音乐表的布局和渲染,第二个 WebWorker 合成音频样本以供播放,AudioWorklet 将缓冲的样本发送到音频上下文进行播放。