You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter插件中加载Emscripten生成的JS库时遇到异常

解决Flutter Web插件中动态加载Csound脚本的顺序问题

我之前处理过类似的Flutter Web插件脚本加载问题,给你几个针对性的解决方案和思路:

1. 手动控制脚本加载顺序,避免异步冲突

你当前的代码是同时添加两个脚本,即使加了defer,动态脚本的加载顺序也可能因为文件大小、网络速度等因素出现偏差。最好的方式是等CsoundObj.js完全加载并初始化后,再加载CsoundDart.js,可以通过监听onLoad事件实现:

// 先加载CsoundObj.js
final csoundObjScript = html.ScriptElement()
  ..src = "assets/packages/csounddart/assets/CsoundObj.js"
  ..type = "text/javascript";

// 监听CsoundObj.js加载完成事件
csoundObjScript.onLoad.listen((_) {
  // 加载完成后再添加CsoundDart.js
  final csoundDartScript = html.ScriptElement()
    ..src = "assets/packages/csounddart/assets/CsoundDart.js"
    ..type = "text/javascript";
  html.document.body?.append(csoundDartScript);
});

html.document.body?.append(csoundObjScript);

这种方式能确保CsoundDart.js运行时,CsoundObj已经存在于全局作用域中。

2. 用Flutter插件官方的脚本加载器

Flutter Web插件提供了专门的registrar.loader来处理脚本加载,它能更好地适配插件上下文,并且天然支持异步顺序加载:

import 'package:flutter_web_plugins/flutter_web_plugins.dart';

void registerCsoundDartPlugin(Registrar registrar) {
  // 先加载CsoundObj.js,等待加载完成
  registrar.loader.loadScript(Uri.parse('packages/csounddart/assets/CsoundObj.js')).then((_) {
    // 再加载CsoundDart.js
    registrar.loader.loadScript(Uri.parse('packages/csounddart/assets/CsoundDart.js')).then((_) {
      // 在这里初始化你的插件核心逻辑
    });
  });
}

这种方式比手动操作DOM更符合Flutter插件的规范,也能避免很多作用域或加载时机的问题。

3. 考虑Emscripten脚本的特殊性

CsoundObj.js是Emscripten生成的,这类脚本通常不会在加载完成后立刻暴露全局对象,而是要等运行时初始化完成。你可以检查脚本中是否有Module.onRuntimeInitialized这类回调(Emscripten的标准回调),如果有的话,需要等这个回调触发后再加载CsoundDart.js:

csoundObjScript.onLoad.listen((_) {
  // 等待Emscripten模块初始化完成
  if (html.window.hasProperty('Module')) {
    final module = html.window['Module'];
    module['onRuntimeInitialized'] = () {
      // 此时CsoundObj应该已成功注册到全局
      final csoundDartScript = html.ScriptElement()
        ..src = "assets/packages/csounddart/assets/CsoundDart.js"
        ..type = "text/javascript";
      html.document.body?.append(csoundDartScript);
    };
  }
});

4. 验证Assets路径和配置

最后别忘了检查pubspec.yaml中的Assets配置是否正确,确保两个脚本都被正确打包:

flutter:
  assets:
    - packages/csounddart/assets/CsoundObj.js
    - packages/csounddart/assets/CsoundDart.js

同时可以打开浏览器开发者工具的Network标签,确认两个脚本的HTTP状态码是200,没有加载失败的情况。

内容的提问来源于stack exchange,提问作者Philiste

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 03:48:11