MXFlutter 框架分为两部分,上层是 TypeScript 开发的 MXFlutter 前端框架,用于支撑使用TS来开发App,底层是Flutter开发的 MXFlutter Flutter Plugin,用于UI渲染。
接入三部曲:
- 第一步 在你的 Flutter 工程里引入 mxflutter flutter plugin。
- 第二步 用 mxflutter cli 工具新建一个 TypeScript 的 mxflutter 工程。 开发完成之后编译输出JS Bundle文件。
- 第三步 把 TS 工程编译的bundle-xxx.js 放置在你的Flutter工程制定目录下,然后就可以调用 mxflutter 提供的接口打开 TS 页面了。
下面详细介绍接入步骤
可以参考这个两个工程示例
- 接入示例工程1 示例工程
- 接入示例工程2 awesome_mxflutter
因为mxflutter在快速迭代,推荐 fork 主库 https://github.com/tencent/mxflutter.git 来接入,方便自己修改和定期从主库的更新。
将下面内容添加到你 Flutter 工程的pubspec.yaml文件中:
dependencies:
mxflutter:
git:
url: https://github.com/tencent/mxflutter.git
在 pubspec.yaml 文件同级目录下创建 mxflutter_js_bundle 文件夹,用于存放 TS 工程生成的JS bundle文件。
在 pubspec.yaml 文件中引入 mxflutter_js_bundle JS Bundle资源,如果不配置的话,mxflutter_js_bundle 不会被打包进入 App.apk或App.ipa,
flutter:
assets:
- mxflutter_js_bundle/
完成后目录结构应该是这样的
my_flutter/
├── lib/
│ └── main.dart
└── pubspec.yaml
└── mxflutter_js_bundle/
调用 flutter pub get 应该可以正确安装 mxflutter plugin
$ flutter pub get
首先新建一个放置 TS 工程的文件夹, 可以把 MXFlutter TS 工程放在你的 Flutter 工程中,例如在 pubspec.yaml文件同级目录下新建 mxflutter-ts-proj 文件夹,(TS工程也可以放在其他地方,与 Flutter 工程用不同的 git 仓库管理,可以根据业务规模灵活处理)。
完成后目录结构是这样的
my_flutter/
├── lib/
│ └── main.dart
└── pubspec.yaml
└── mxflutter-ts-proj/
└── mxflutter_js_bundle/
安装 mxflutter 的cli工具
$ npm install @mxflutter/mxflutter-toolchain@0.9.0 -g
先切换到放置 TS 工程的 mxflutter-ts-proj 为当前目录
$ cd mxflutter-ts-proj/
通过 mxflutter create 命令根据提示新建 TS 工程。
$ mxflutter create
假如我们要创建工程名字叫 mxflutter-homepage ,根据提示填写好对应内容,其中第二项 “请输入flutter项目放置mxflutter_js_bundle的路径” 是设置 TS 工程编译的JS Bundle输出的地方,通过相对路径指向前面在 Flutter 工程中创建好的 mxflutter_js_bundle,如果 TS 工程和此示例一样放置在 Flutter 工程中,就可以用相对路径指定。
$ mxflutter create
$ ? 请输入项目名字 :mxflutter-homepage
$ ? 请输入flutter项目放置mxflutter_js_bundle的路径 : ../mxflutter_js_bundle/
$ ? 请输入你的名字 xsoap
$ ? 请输入你的邮箱 mxflutter@qq.com
完成后的目录结构
my_flutter/
├── lib/
│ └── main.dart
└── pubspec.yaml
└── mxflutter-ts-proj/
│ └── mxflutter-homepage/
│ └── src/
│ └── index.ts
└── mxflutter_js_bundle/
到此如果一切顺利已经配置好了所有内容,新建的 TS 工程里index.ts有经典的 Flutter 初始工程 Counter 完整代码, 下面我们尝试运行起来,打开 TS Counter页面。
先切换到刚新建的 TS 工程 mxflutter-homepage 为当前目录,使用 npm install 安装依赖。
$ cd mxflutter-homepage/
$ npm install #安装依赖
如果有错误发生,可以根据错误提示排除错误,如果安装成功,解下来就可以使用 npm run build 命令构建 JS Bundle
$ npm run build
如果一切顺利,在 mxflutter_js_bundle/mxflutter-homepage 文件夹就能看到有 bundle-mxflutter-homepage.js 输出。
完成后的目录结构
my_flutter/
├── lib/
│ └── main.dart
└── pubspec.yaml
└── mxflutter-ts-proj/
│ └── mxflutter-homepage/
│ └── src/
│ └── index.ts
└── mxflutter_js_bundle/
│ └── mxflutter-homepage/
│ └── bundle-mxflutter-homepage.js
在iOS下模拟器Debug模式下,bundle-mxflutter-homepage.js 放到 mxflutter_js_bundle/mxflutter-homepage 目录,按照下面 [开发调试] 小节的内容,配置好debugJSBundlePath路径,就可以运行调试了。
检查bundle-mxflutter-homepage.js 是不是在这个目录
my_flutter/
├── lib/
│ └── main.dart
└── pubspec.yaml
└── mxflutter-ts-proj/
│ └── mxflutter-homepage/
│ └── src/
│ └── index.ts
└── mxflutter_js_bundle/
│ └── mxflutter-homepage/
│ └── bundle-mxflutter-homepage.js
在 Android 运行或者要发布,需要打包成bizBundle.zip,打包方式如下。
例如:有两个业务文件 mxflutter-homepage/bundle-mxflutter-homepage.js 和 example2/bundle-example2.js,选中mxflutter-homepage和example2这两个文件夹,右键压缩为 “归档.zip”, 修改名称为 bizBundle.zip。特别注意不要有文件夹嵌套,压缩包里不要多加入一层bizBundle的文件夹。
在 main.dart 文件中,调用 MXJSFlutter.runJSApp() 初始化MXFlutter,runJSApp 函数如果不传任何参数,默认会运行 mxflutter_js_bundle 目录下的JS Bundle 文件。
//mxflutter
import 'package:mxflutter/mxflutter.dart';
void main() {
//-------1. 启动 MXFlutter---------
// 拷贝业务bundle到动态更新目录,准备好JS代码
// demo为了演示是每次启动拷贝到js bundle的更新目录,一般只有第一次或版本升级需要拷贝。
// 业务可以根据自身需求,来判断是否拷贝。此部分逻辑可以写在Dart侧,也可以写在Native侧
String jsBundlePath = await _copyBizBundelZipToMXPath();
if (jsBundlePath != null) {
// 启动 MXFlutter,加载JS库。
MXJSFlutter.runJSApp(jsAppPath: jsBundlePath);
}
}
注意:因为涉及到文件的拷贝,因此在 android 环境中,需在 AndroidManifest.xml 文件添加如下配置。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
在合适时机,比如用户点击按钮时,打开MXFlutter页面
onTap: () {
//-------2. 打开MXFlutter页面------
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MXJSPageWidget(
jsWidgetName: "mxflutter-homepage")));
}
如果一切顺利,你可以看到 Flutter 的经典页面了
可以把 MXJSPageWidget 当作普通的Flutter Widget,放到任何的地方,其中jsWidgetName: "mxflutter-homepage" 参数,会指示 MXFlutter 框架加载 mxflutter_js_bundle 目录下哪个 JS Bundle 文件。并且会被传递到 index.ts 代码,用来区分打开哪个 TS 页面。
对应代码在 mxflutter-homepage TS工程 src/index.ts 文件最下方。MyApp 可以换成任意 Widget
mxflutter.regist({
name: 'mxflutter-homepage',
RootWidget: MyApp,
});
- 在 Safari 偏好设置-高级选项中,勾选"在菜单栏中显示"开发"菜单"
- XCode运行MXFlutter模拟器,在Safari的"开发"菜单中选择MXFlutter模拟器
- Safari浏览器tab栏选择:”开发” -> 选择你的模拟器名字,打开Web Inspector界面后,即可调试JavaScript
- Android手机上面运行MXFlutter
- 安装Chrome浏览器,在地址栏中输入:"chrome://inspect/#devices"
- 在Chrome浏览器页面的Remote Target中可以看到"MXFlutter",点击inspect
- 打开Web Inspector界面后,即可调试JavaScript
npm run build 命令可以单次构建 JS Bundle,在开发调试过程中,不是非常方便, 可以通过执行 npm run dev 命令监控源码变化,当你修改了源码时,会立即实时输出 bundle 包到您需要的位置 ( mxflutter 终端项目的 js 资源目录 )
npm run dev
在使用iOS 模拟器调试时,MXJSFlutter.runJSApp()可以设置 debugJSBundlePath 参数,推荐设置成 TS 代码的输出目录,这样TS代码实时更新生效。
// 开发调试,为了方便验证,可以自己指定目录,只能用于iOS模拟器下。
var debugJSBundlePath =
'/Volumes/Data/Work/RFlutter/MXFlutter/example/mxflutter_js_bundle';
MXJSFlutter.runJSApp(debugJSBundlePath: debugJSBundlePath);
mxflutter cli 打包支持生产模式 bundle 的构建,并可以兼容低版本 jscore ( ios 9 - 10 )
npm run build:production # 发布版本的构建
npm run build:es5 # es版本兼容构建 主要针对 ios 9 - 10