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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:12:28