Flutter Web调用JS函数如何避免移动端构建失败?
在Flutter跨平台项目中调用JS函数并适配移动端构建的解决方案
直接导入dart:js会导致移动端构建失败,因为该库仅Web环境可用,且Flutter原生不支持简单的条件导入语句。以下是两种无需手动注释代码的适配方案:
方案一:条件导入+Stub文件适配
通过创建平台专属的Stub文件,让移动端构建时加载空实现,Web端加载真实的dart:js库。
步骤1:创建Stub文件
在项目中新建empty_js_stub.dart,内容如下:
// 移动端空实现,模拟dart:js的context结构 final context = _StubJsContext(); class _StubJsContext { dynamic callMethod(String methodName, [List<dynamic>? arguments]) { print("提示:JS函数调用仅支持Web平台"); return null; } }
步骤2:修改Widget代码
使用条件导入语法,让Web端导入dart:js,移动端导入Stub文件:
import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; // 条件导入:Web环境用dart:js,其他环境用Stub文件 import 'dart:js' as js if (dart.library.io) 'empty_js_stub.dart'; class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return ElevatedButton( onPressed: () { if (kIsWeb) { // Web环境下调用真实JS函数 js.context.callMethod('myFunction', ['arg1', 'arg2']); final result = js.context.callMethod('myFunction2'); print(result); } else { // 移动端执行替代逻辑 print("当前平台不支持JS调用"); } }, child: const Text('Invoke JavaScript'), ); } }
方案二:使用package:js官方包(更规范的跨平台适配)
官方提供的package:js库支持更优雅的JS交互,配合条件导入和平台判断,同样能适配多端:
步骤1:添加依赖
在pubspec.yaml中添加:
dependencies: js: ^0.6.7
步骤2:定义JS函数绑定
创建js_bindings.dart文件,使用条件导入:
import 'package:js/js.dart' if (dart.library.io) 'js_bindings_stub.dart'; // Web环境下绑定JS函数 @JS() external void myFunction(String arg1, String arg2); @JS() external dynamic myFunction2();
步骤3:创建Stub文件js_bindings_stub.dart
// 移动端空实现 void myFunction(String arg1, String arg2) { print("提示:myFunction仅支持Web平台"); } dynamic myFunction2() { print("提示:myFunction2仅支持Web平台"); return null; }
步骤4:修改Widget代码
import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'js_bindings.dart'; class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return ElevatedButton( onPressed: () { if (kIsWeb) { myFunction('arg1', 'arg2'); final result = myFunction2(); print(result); } else { // 移动端执行替代逻辑 myFunction('arg1', 'arg2'); // 会调用Stub中的提示逻辑 } }, child: const Text('Invoke JavaScript'), ); } }
两种方案都能实现无需手动注释代码,自动适配Web和移动端构建。方案一适合简单场景,方案二更适合有大量JS交互的项目,代码结构更清晰。
内容的提问来源于stack exchange,提问作者David Somekh
相关产品推荐
相关产品推荐

