Web与移动端同代码库如何使用dart:js/dart:html?需用条件导入吗?
跨端兼容
dart:js编译报错解决方案 问题本质是dart:js是Dart Web专属的核心库,移动端(iOS/Android)的Dart SDK里没有这个库,只要代码里直接import了这个库,编译移动端时就会直接报错,运行期判断(比如kIsWeb)解决不了编译期的导入检查问题,必须用Dart原生支持的条件导入特性,在编译阶段根据目标平台选择性加载对应代码。
具体实现步骤
- 拆分平台专属实现文件
首先把Web端和移动端的逻辑拆成两个独立文件,两个文件里的方法签名保持完全一致:
- Web端实现:命名为
js_bridge_web.dart,可以安全引入Web专属库,只在Web编译时被加载import 'dart:js' as js; void redirectToStripe(String sessionId) { // 注意callMethod第二个参数需要传数组,直接传单个字符串会被拆成字符数组传给JS js.context.callMethod('redirectToStripe', [sessionId]); } - 移动端实现:命名为
js_bridge_mobile.dart,禁止引入任何Web专属库,可根据业务需求写移动端的对应逻辑,不需要的话可以做空实现void redirectToStripe(String sessionId) { // 这里写移动端的Stripe跳转逻辑,比如通过MethodChannel唤起原生Stripe SDK // 无对应需求可以直接留空或者打印日志 print('非Web环境,不执行JS跳转逻辑'); }
- 拆分平台专属实现文件
- 编写通用桥接文件
新建js_bridge.dart,这是业务代码里唯一需要导入的文件,通过条件导入语法自动匹配当前编译平台的实现:
// 核心:默认导入移动端实现,检测到是Web编译环境时自动替换成Web端实现 export 'js_bridge_mobile.dart' if (dart.library.js) 'js_bridge_web.dart';- 编写通用桥接文件
- 替换原有业务调用逻辑
删掉原来代码里直接导入dart:js的部分,所有业务场景只需要导入通用桥接文件,直接调用同名方法即可:
// 业务文件里只导入这个通用桥接,不用管平台差异 import 'js_bridge.dart'; // 业务里直接调用即可,编译Web时用Web的实现,编译移动端时用移动端的实现 void doPay(String sessionId) { redirectToStripe(sessionId); }- 替换原有业务调用逻辑
避坑说明
不要尝试用
kIsWeb做判断包裹调用逻辑,import是编译期执行的语法,只要文件顶部写了import 'dart:js',哪怕运行时永远不会走到这段逻辑,编译移动端时依然会因为找不到库直接报错,只有条件导入是编译期选择性加载代码,能从根源解决问题。所有Web专属依赖(包括
dart:js、dart:html、flutter_web_plugins等)都只能放在Web专属实现文件里,不能出现在通用逻辑、移动端实现文件中。
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

