news 2026/9/14 15:13:29

Flipper Zero JavaScript 应用脚手架:使用 create-fz-app 快速创建与运行 JS App

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flipper Zero JavaScript 应用脚手架:使用 create-fz-app 快速创建与运行 JS App

Flipper Zero JavaScript 应用脚手架:使用 create-fz-app 快速创建与运行 JS App

【免费下载链接】flipperzero-firmwareFlipper Zero firmware source code项目地址: https://gitcode.com/GitHub_Trending/fl/flipperzero-firmware

导读

本指南围绕 Flipper Zero 官方 JavaScript SDK 的脚手架工具@flipperdevices/create-fz-app展开,介绍如何在本地用一条命令交互式生成一个完整的 JS 应用工程、通过npm start一键完成编译、上传与在真机上运行。读完本文,你将掌握 Flipper Zero JS App 从"空目录"到"屏幕弹出 Hello 对话框"的完整开发闭环,并理解脚手架背后的模板结构、fz-sdk.config.json5配置语义以及 SDK 的构建与串口上传原理。

一、脚手架工具是什么

create-fz-app是 Flipper Zero 官方发布在 npm 上的交互式脚手架包(包名@flipperdevices/create-fz-app),用于在本地生成一个可运行的 JavaScript 应用工程,目标运行环境是 Flipper Zero 设备内置的 JS 解释器(mjs)。该包与@flipperdevices/fz-sdk(官方类型声明与构建/上传工具链)配套使用,两者的源码均位于本仓库的 applications/system/js_app/packages/ 目录下。

从源码看,脚手架的核心逻辑非常轻量(create-fz-app/index.js):通过prompts交互式收集用户输入,然后把内置的template/模板目录复制到目标文件夹,用项目名替换模板中的<app_name>占位符,最后调用所选包管理器执行依赖安装。包本身依赖极少,仅promptsreplace-in-file(见 package.json),这意味着它只负责"生成工程",真正的编译与上传由模板中引入的fz-sdk完成。

二、快速开始:三分钟创建并运行第一个应用

2.1 创建工程

在任意空目录下执行官方推荐命令:

npx @flipperdevices/create-fz-app@latest

npx会自动从 npm 拉取最新版脚手架并启动交互式向导,期间会依次询问三个问题:

  1. 项目名称(默认my-flip-app):生成后即作为目录名;
  2. 包管理器选择npm/pnpm/yarn三选一;
  3. 确认创建(默认确认)。

确认后,工具会复制模板文件、将模板内所有<app_name>占位符替换为你的项目名(对应源码中的replaceInFileSync({ files:${name}/**/*, from: /<app_name>/g, to: name })),然后自动执行pnpm install/npm install/yarn install安装依赖。若目标目录已存在同名文件或目录,向导会额外询问是否继续覆盖(源码中通过fs.rmSync(name, { recursive: true, force: true })实现删除重建,因此请谨慎操作)。

2.2 运行到 Flipper Zero

进入生成的项目目录并启动:

cd my-flip-app npm start

如果你在创建时选择了pnpmyarn,完全可以使用pnpm start/yarn start代替npm start,三个包管理器对工具链完全等价。

npm start实际执行的是模板 package.json 中定义的两步流水线:

"build": "tsc && node node_modules/@flipperdevices/fz-sdk/sdk.js build", "start": "npm run build && node node_modules/@flipperdevices/fz-sdk/sdk.js upload"

即:先用 TypeScript 编译器检查并产出 JS,再调用fz-sdkbuild命令打包,最后用upload命令把产物通过串口写入 Flipper Zero 并立即运行

2.3 运行前提

  • 需要 Node.js 环境(脚手架与 SDK 均为 Node 工具链);
  • Flipper Zero 需通过 USB 连接到电脑,并处于命令行模式(CLI 会话),以便upload通过串口交互;
  • 首次使用时会通过串口在设备上创建/ext/apps/Scripts/目录存放脚本(详见下文配置与上传原理)。

三、生成的工程模板剖析

脚手架内置的模板文件位于仓库的 applications/system/js_app/packages/create-fz-app/template/ 目录,生成后的工程包含四个关键文件。理解它们,就等于掌握了 Flipper Zero JS App 的最小工程结构。

3.1fz-sdk.config.json5:构建与上传配置

这是整个工程的枢纽配置,使用 JSON5 语法(支持注释),包含buildupload两大段:

{ build: { // 编译产物的输出路径 output: "dist/<app_name>.js", // 是否压缩以减小文件体积(以牺牲可读性和错误信息清晰度为代价) minify: false, // 若已通读文档、确认可自行处理版本检查,可设为 false enforceSdkVersion: true, }, upload: { // 上传来源文件;若构建后无额外处理,应与 build.output 一致 input: "dist/<app_name>.js", // 上传到设备上的目标路径 output: "/ext/apps/Scripts/<app_name>.js", }, }

各配置项说明(对应 fz-sdk.config.json5 模板源码):

配置项含义默认行为
build.output打包产物路径,同时是upload.input的默认来源dist/<app_name>.js
build.minify是否启用 esbuild 压缩输出false,保留可读性与错误信息
build.enforceSdkVersion是否在产物头部注入 SDK 版本兼容性检查true,强烈建议保持开启
upload.output脚本在设备上的存放位置/ext/apps/Scripts/<app_name>.js

其中enforceSdkVersion对应 fz-sdk/sdk.js 中的实现:构建时会读取 SDK 自身版本号,并在产物最前面注入一行checkSdkCompatibility(major, minor);,由设备端 JS 运行时在执行脚本时校验 SDK 兼容性,避免因 API 变更导致运行期崩溃。

3.2index.ts:开箱即用的示例应用

模板自带一个可直接运行的对话框示例(template/index.ts),演示了 Flipper Zero JS App 的标准骨架:

// import modules // caution: `eventLoop` HAS to be imported before `gui`, and `gui` HAS to be // imported before any `gui` submodules. import * as eventLoop from "@flipperdevices/fz-sdk/event_loop"; import * as gui from "@flipperdevices/fz-sdk/gui"; import * as dialog from "@flipperdevices/fz-sdk/gui/dialog"; // a common pattern is to declare all the views that your app uses on one object const views = { dialog: dialog.makeWith({ header: "Hello from <app_name>", text: "Check out index.ts and\nchange something :)", center: "Gonna do that!", }), }; // stop app on center button press eventLoop.subscribe(views.dialog.input, (_sub, button, eventLoop) => { if (button === "center") eventLoop.stop(); }, eventLoop); // stop app on back button press eventLoop.subscribe(gui.viewDispatcher.navigation, (_sub, _item, eventLoop) => { eventLoop.stop(); }, eventLoop); // run app gui.viewDispatcher.switchTo(views.dialog); eventLoop.run();

这个示例刻意展示了三条重要约定:

  1. 导入顺序有强约束eventLoop必须先于gui导入,gui必须先于任何gui子模块导入——这是 fz-sdk 类型声明中的硬性要求,破坏顺序会导致运行时错误;
  2. 事件循环驱动:所有交互都通过eventLoop.subscribe订阅视图输入事件完成,中心键与返回键都会停止事件循环从而退出应用;
  3. 视图管理器gui.viewDispatcher.switchTo()负责切换当前显示的视图。

@flipperdevices/fz-sdk的完整类型声明位于仓库 applications/system/js_app/packages/fz-sdk/,覆盖gui(dialog、submenu、text_input、widget、byte_input 等十余种视图)、event_loopflippergpiostorageserialbadusbmathnotification等模块,是开发时最重要的类型参考。

3.3package.jsontsconfig.json

  • package.json:声明@flipperdevices/fz-sdk(^1.0)与typescript(^5.6.3)两个开发依赖,以及上文提到的build/start脚本;
  • tsconfig.json:面向 Flipper Zero JS 运行时的编译配置,target: "ES2015"noLib: true(不使用 Node 类型库)、types: [],并把 SDK 的global.d.ts显式纳入编译,保证设备端全局 API 的类型可用。设备端的 JS 解释器仅支持受限的 ECMAScript 子集,因此工具链在打包时会主动"禁用"大量现代语法特性(见下文),开发者应尽量编写 ES5/ES2015 风格的代码。

四、SDK 构建与上传的底层原理

npm start调用的sdk.js位于 applications/system/js_app/packages/fz-sdk/sdk.js,这是理解整个工具链的关键文件。

4.1build:面向嵌入式运行时的 esbuild 打包

build命令基于 esbuild 完成三件事:

  1. ./dist/index.js(即 tsc 的编译产物)为入口,按tsconfig.json配置打包成单个 CommonJS 文件,输出到config.output
  2. 通过external: ["@flipperdevices/fz-sdk/*"]把 SDK 模块声明为外部依赖——SDK 不打包进产物,而是由设备端运行时按需解析(这也是为什么 import 顺序如此重要);
  3. 最关键的是supported配置:显式将arrowasync-awaitclasstemplate-literaloptional-chainnullish-coalescingdestructuringfor-of等数十项现代语法特性全部设为false,仅保留const-and-let。这意味着任何依赖现代 JS 语法的代码都会在构建阶段被拒绝,从源头保证产物与 Flipper Zero 内置解释器的语法能力兼容。

打包完成后,脚本会在产物头部拼接let exports = {};,并根据enforceSdkVersion注入版本检查调用,最终写回输出文件。

4.2upload:串口发现、写入与启动

upload命令实现了一条完整的"写盘-运行"链路:

  1. 发现设备:通过SerialPort.list()枚举串口,优先按serialNumberflip_前缀识别 Flipper Zero;针对部分 Windows 驱动不报告序列号的情况,回退到按 STM32 VCP 的VID 0483 : PID 5740匹配。若同时连接多台设备,会弹出选择框;
  2. 建立连接:以230400波特率打开串口,等待 CLI 提示符>:出现;
  3. 写入脚本:依次执行storage remove清除旧文件、storage write_chunk <path> <size>声明写入块大小、随后发送文件内容,等待写入完成;
  4. 启动应用:执行js <path>命令启动脚本,实时转发设备输出到终端,并在脚本退出(出现Script done!)后自动结束进程。

这条链路意味着你甚至可以把生成的dist/*.js手动复制到设备/ext/apps/Scripts/目录后自行运行,upload只是把这个过程自动化了。

五、版本兼容性约定

脚手架配套的fz-sdk包遵循一套明确的版本语义(见 fz-sdk/README.md):包版本号的 major.minor 与其所面向的 Flipper Zero JS SDK 版本一致,并遵循 semver。例如,用 SDK 版本0.1.0编译的应用,兼容0.11.0(不含1.0)之间的 SDK 版本。

每个 API 的版本历史记录在其 JSDoc 注释中。SDK 强烈建议开发者根据场景组合使用sdkCompatibilityStatusisSdkCompatibleassertSdkCompatibility等运行时 API 做兼容性检查——这也是模板默认开启enforceSdkVersion的原因:把版本检查内联进产物,确保设备端与工具链版本匹配时应用才允许运行,将兼容性问题提前暴露在启动阶段。

六、下一步:深入 JS 开发

脚手架生成的工程是探索 Flipper Zero JS API 的最佳起点。本仓库的 documentation/js/ 目录提供了完整的模块级参考,包括:

  • js_developing_apps_using_js_sdk.md:基于 JS SDK 开发应用的总体流程;
  • js_event_loop.md 与 js_gui.md:事件循环与 GUI 视图体系;
  • js_gui__dialog.md、js_gui__submenu.md、js_gui__widget.md 等:各视图组件的独立用法说明;
  • js_storage.md、js_gpio.md、js_serial.md:文件系统、GPIO、串口等硬件能力访问。

结合 fz-sdk 的类型声明(IDE 中可直接获得智能提示),你可以从模板的对话框示例出发,逐步替换为菜单、文本输入、文件浏览器等更复杂的界面,构建真正可用的设备端工具应用。

【免费下载链接】flipperzero-firmwareFlipper Zero firmware source code项目地址: https://gitcode.com/GitHub_Trending/fl/flipperzero-firmware

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 15:12:22

FPGA实现多路MIPI CSI相机同步接入主控方案

1. 项目概述&#xff1a;为什么多相机接入主控成了机器视觉产线的“卡脖子”环节 在工厂自动化质检线上&#xff0c;我见过太多这样的场景&#xff1a;一台玻璃盖板检测设备&#xff0c;需要同时用4个2000万像素的工业相机从不同角度拍同一块面板&#xff1b;一条锂电池极片缺陷…

作者头像 李华
网站建设 2026/9/14 15:12:16

C# WinForm上位机实现CAN总线收发与ECU仿真器通信实例

简介&#xff1a;资源为基于C# WinForm开发的昂科威ECU仿真器&#xff0c;面向汽车电子开发者与测试人员&#xff0c;通过兼容周立功USB-CAN II设备实现CAN报文的实时接收、发送及ECU行为模拟&#xff0c;可用于车载网络调试、协议解析、上位机通信验证和教学演示。压缩包共35个…

作者头像 李华
网站建设 2026/9/14 15:11:30

MiGPT:零基础将小爱音箱改造成AI语音助手

MiGPT&#xff1a;零基础将小爱音箱改造成AI语音助手 【免费下载链接】mi-gpt &#x1f3e0; 将小爱音箱接入 ChatGPT 和豆包&#xff0c;改造成你的专属语音助手。 项目地址: https://gitcode.com/GitHub_Trending/mi/mi-gpt MiGPT 是一个开源项目&#xff0c;把小爱音…

作者头像 李华
网站建设 2026/9/14 15:11:23

二叉树中序遍历:递归、迭代与Morris算法详解

1. 二叉树中序遍历的核心概念中序遍历&#xff08;Inorder Traversal&#xff09;是二叉树遍历中最基础也最重要的方式之一。它的遍历顺序遵循"左子树-根节点-右子树"的原则&#xff0c;这种遍历方式特别适合需要按照节点值大小顺序输出的场景。在二叉搜索树&#xf…

作者头像 李华
网站建设 2026/9/14 15:10:00

Go2rtc 模块体系详解:协议、格式与编解码能力矩阵

Go2rtc 模块体系详解&#xff1a;协议、格式与编解码能力矩阵 【免费下载链接】go2rtc Ultimate camera streaming application 项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc 本篇基于 go2rtc 仓库中的 internal/README.md 文档展开&#xff0c;系统讲解 g…

作者头像 李华
网站建设 2026/9/14 15:08:08

MediaPipe+Unity:手部面部关键点实时驱动虚拟角色

简介&#xff1a;基于Python与MediaPipe实现手部、面部实时识别&#xff0c;并驱动Unity端虚拟人物运动的完整项目源码&#xff0c;面向计算机相关专业正在筹备毕业设计、课程设计或期末大作业的学生&#xff0c;也适合希望从零上手视觉驱动Unity项目的实战学习者。项目经导师指…

作者头像 李华