Flutter跨iOS/Android/Web端执行JavaScript代码的实现方案
三端兼容的Flutter JS执行实现方案
flutter_js仅支持移动端,Web端可直接复用浏览器原生JS执行能力,通过一层抽象屏蔽平台差异,即可在Flutter 2.10.3版本下实现iOS/Android/Web三端统一逻辑。
依赖配置
在pubspec.yaml中添加所需依赖:
dependencies: flutter: sdk: flutter flutter_js: ^0.5.0+6 js: ^0.6.4
统一抽象层封装
先定义通用的JS运行时抽象,屏蔽平台实现差异:
import 'package:flutter/foundation.dart'; abstract class JsRuntime { static JsRuntime? _instance; static JsRuntime get instance { _instance ??= kIsWeb ? WebJsRuntime() : MobileJsRuntime(); return _instance!; } String evaluate(String jsCode); }
移动端(iOS/Android)实现
复用原有flutter_js的逻辑即可:
import 'package:flutter_js/flutter_js.dart'; class MobileJsRuntime extends JsRuntime { late final JavascriptRuntime _runtime = getJavascriptRuntime(); @override String evaluate(String jsCode) { return _runtime.evaluate(jsCode).stringResult; } }
Web端实现
直接调用浏览器原生JS执行能力,无需额外插件:
import 'dart:js_util' as js_util; import 'dart:js' as js; class WebJsRuntime extends JsRuntime { @override String evaluate(String jsCode) { final dynamic res = js_util.callMethod(js.context, 'eval', [jsCode]); return res.toString(); } }
业务调用替换
原有代码直接替换为统一抽象层调用,入参和返回逻辑和之前完全一致:
String jsResult = JsRuntime.instance.evaluate(""" if (typeof MyClass == 'undefined') { var MyClass = class { constructor(id) { this.id = id; } getId() { return this.id; } } } var obj = new MyClass(1); var jsonStringified = JSON.stringify(obj); var value = Math.trunc(Math.random() * 100).toString(); JSON.stringify({ "object": jsonStringified, "expression": value}); """);
注意事项
- Web端默认在当前页面全局JS上下文执行代码,如果需要避免全局变量污染,可以把待执行代码包裹在立即执行函数中运行;如果需要执行不可信JS,建议替换为沙箱iframe的执行逻辑隔离风险
- 待执行JS的最终返回值需要是可直接转为字符串的基础类型,和flutter_js的使用要求保持一致即可
- Flutter 2.10.3的tree shaking机制会自动根据平台剔除未用到的代码,不会出现移动端打包引入Web端库导致的编译错误
内容的提问来源于stack exchange,提问作者sosnus
相关产品推荐
相关产品推荐

