🔥【全网首篇】30分钟带你从0到1搭建基于Lynx的跨端开发环境

简介

Lynx 是继 React NativeFlutter 之后的一款现代跨端开发框架,近期刚由字节团队开源,其内部已使用多年,评价褒贬不一。

官网地址:lynxjs.org/

本文将基于官方提供的 快速上手 指引从 0 到 1 搭建一个跨端APP的本地开发环境,(敲重点⚠️)以及过程中所遇到的坑和对应的解决方案🔧

如果只对踩坑感兴趣的,可以直接跳到 本地构建 一节

让我们开始吧🛫

温馨提示

Lynx 开发环境目前暂时对 Windows 支持不好,使用 Windows 的开发者需要关注官方进一步的支持,详见:github.com/lynx-family...

系统环境准备

首先按照 lynx 官网要求,确认本地安装 Node.js 18 及以上版本。我本地是通过 nvm 安装的 v20.18.0

sh 复制代码
node --version
v20.18.0

项目创建

接着我们使用 Rspeedy 快速创建一个基于 Lync 的工程,它是专门为 Lynx 打造的构建工具

这里我选择使用 pnpm 作为包管理工具

sh 复制代码
pnpm create rspeedy@latest

创建流程非常简洁,只有三步

  1. 定义项目名称(使用默认名称 rspeedy 可直接按 Tab 键)
  2. 选择开发语言(TS/JS)
  3. 选择 linting/formating 工具(Biomi/ESLint/Prettier

注意:项目名和开发语言都有默认值,第三步的额外工具是可选项,需要使用空格键进行勾选

这里我选择 TS 和 biome

并且项目默认不会使用 git 初始化,项目初始化完成后控制台会提示可按需自行使用 git 初始化项目

sh 复制代码
◆  Create Rspeedy Project
│
◇  Project name or path
│  rspeedy-project
│
◇  Select language
│  TypeScript
│
◇  Select additional tools (Use <space> to select, <enter> to continue)
│  none
│
◇  Next steps ─────────────╮
│                          │
│  1. cd rspeedy-project   │
│  2. git init (optional)  │
│  3. pnpm install         │
│  4. pnpm run dev         │
│                          │
├──────────────────────────╯
│
└  All set, happy coding!

项目结构

初始的项目结构也非常简洁,有以下几部分

  • 源码目录 src
  • .gitignore(没初始化 git 但有 ignore 文件,稍微有点抽象)
  • lynx 配置文件 lynx.config.ts
  • package.json
  • 描述项目的 README.md
  • tsconfig.ts

以上为按照 VSCode 内展示的顺序描述,下附 tree 生成的目录结构

sh 复制代码
├── README.md
├── biome.json
├── lynx.config.ts
├── package.json
├── src
│   ├── App.css
│   ├── App.tsx
│   ├── assets
│   │   ├── arrow.png
│   │   ├── lynx-logo.png
│   │   └── react-logo.png
│   ├── index.tsx
│   └── rspeedy-env.d.ts
└── tsconfig.json

项目启动

首先,安装项目依赖

sh 复制代码
pnpm install
sh 复制代码
Downloading @biomejs/cli-darwin-arm64@1.9.4: 9.79 MB/9.79 MB, done
Downloading @lynx-js/tasm@0.0.5: 7.33 MB/7.33 MB, done
Downloading @rspack/binding-darwin-arm64@1.2.7: 18.28 MB/18.28 MB, done
 WARN  1 deprecated subdependencies found: acorn-import-assertions@1.9.0
Packages: +507
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 522, reused 0, downloaded 507, added 507, done

dependencies:
+ @lynx-js/react 0.105.1

devDependencies:
+ @biomejs/biome 1.9.4
+ @lynx-js/qrcode-rsbuild-plugin 0.3.4
+ @lynx-js/react-rsbuild-plugin 0.9.1
+ @lynx-js/rspeedy 0.8.3
+ @lynx-js/types 3.2.0
+ @types/react 18.3.18 (19.0.10 is available)
+ typescript 5.7.3 (5.8.2 is available)

╭ Warning ───────────────────────────────────────────────────────────────────────────────────╮
│                                                                                            │
│   Ignored build scripts: @biomejs/biome, core-js.                                          │
│   Run "pnpm approve-builds" to pick which dependencies should be allowed to run scripts.   │
│                                                                                            │
╰────────────────────────────────────────────────────────────────────────────────────────────╯

Done in 42.5s using pnpm v10.6.2
sh 复制代码
pnpm run dev
sh 复制代码
> rspeedy-project@1.0.0 dev /Users/wangxin/rspeedy-project
> rspeedy dev

  Rspeedy v0.8.3 (Rsbuild v1.2.15, Rspack v1.2.7)

info    port 3000 is in use, using port 3001.
start   build started...
ready   built in 1.12 s (lynx)
│
●  Scan with Lynx
│
◆  ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
│  █ ▄▄▄▄▄ █▀█ █▄   ▀██▄▄▀█▄██ ▄▄▄▄▄ █
│  █ █   █ █▀▀▀█ ▄▀ █▀█▄▄▄ █ █ █   █ █
│  █ █▄▄▄█ █▀ █▀▀██▄▄▄▄▄ █▀▄██ █▄▄▄█ █
│  █▄▄▄▄▄▄▄█▄▀ ▀▄█ █ █ ▀ ▀▄█▄█▄▄▄▄▄▄▄█
│  █  ▄  █▄▄ ▄▀▄▀▀▀▀█ ▀ ▄██ ▄ ▀ █▄█ ▀█
│  ██ ██ ▄▄▀██▄█▀ ▄  █▀█ ▀▄▀█▀█▄ █▀███
│  █ █▀ ▄ ▄▀▄ ▄█▄█▄▄▀▄█▀▀█▄  █▀ ▄▀█▀▀█
│  █ ▄▄█▀▄▄▄██▀ ▄█▀  ▄▄█▀ ▄█▀▄  ▀▄▀▄██
│  █ ▄ ▀  ▄ ▀▄▄▄▀▀▀▄ ▄▀ ▀█ ▀▀▀▀▀▄▀█ ▀█
│  █▄▄▄▀██▄▄ ▀▄█▀ ▄▄█▄▄█▀ ▀█ ▀█▄▄▄▀▄██
│  █▀██ ██▄ ▄█ █▄█▄▄ ▄█▀▀█▄▀▀▀▀▀▄▄▀ ▀█
│  █ █▄  █▄ █▀  ▄█▀ ▀▄ ▀▀▀▄█ █▄▀█▄ ▄██
│  █▄█▄███▄▄▀ █▄▀▀▀▄ ▄▀ ▀█ ▀ ▄▄▄ ▄██ █
│  █ ▄▄▄▄▄ █▄█▄█▀ ▄  ███  █▄ █▄█ ▄  ██
│  █ █   █ █ ▄▄█▄█▄█▄▄▀▀ ██▀▄▄▄▄ ▄▀▀ █
│  █ █▄▄▄█ █    ▄█▀▄▀██▀█▀▄▀▄▄  ▀█▀███
│  █▄▄▄▄▄▄▄█▄█▄▄█████▄████▄█▄█▄█▄██▄██
│  
│
◆  http://192.168.1.18:3001/main.lynx.bundle?fullscreen=true
│
◆  Usage
│   r  Switch entries
│   a  Switch schema
│   h  Help
│   q  Quit
└

注意,这里项目启动完成后不会生成直接可访问的链接,而是用于 Lynx Explorer(类似 Expo)的链接和二维码。

安装 Lynx Explorer

方式一:下载预编译二进制用模拟器打开

官网文档提供了 iOS 的预编译二进制文件,下载解压后拖入 Xcode 启动的模拟器即可

方式二:本地构建并连接真机安装

本地构建这种方式会遇到一些坑,下面重点讲一下这种方式会遇到的问题以及对应的解法

本地构建

准备系统环境

首先,按照 文档 准备本地编译 Lynx Explorer 的系统环境,Python3.9 及以上和 Ruby2.7 及以上

安装 Python3

但这并没有文档说的那么简单,以 M 系芯片的 MacOS 为例,要注意需要使用 Homebrew 安装 Python3 ,安装后使用 which python3 检查是否为 /opt/homebrew/bin/python3 而不是 usr/bin/python3,后者为 macOS 自带的 Python3,版本可能不符合要求。

安装 Ruby

ruby 的安装坑比较多,使用 RN 或 Flutter 准备过 iOS 环境的一定知道我在说什么。

而 ruby 大概就是用来安装后面 iOS 使用的 cocoapods

这里还是以我最终成功的方式为例,希望帮助大家少走一些弯路。

我是使用 rbenv 安装的 ruby 指定版本

这里注意⚠️ Lynx 文档中提到的 Ruby 版本是 >=2.7 即可,但现在 Ruby 的最新版是 3.4.2,最新版本的 Ruby 对基础库 BigDecimal 存在兼容问题,详见:github.com/ruby/bigdec...

因此需要使用 rbenv 安装最新版本的前一个版本 3.3.7,并且将其设置为全局的 ruby 版本

sh 复制代码
rbenv global 3.3.7

关于 Ruby 最新版本无法使用的问题我已经给 Lynx 提了 issue 并且得到了肯定的回复,他们也在尝试实现 ruby 环境隔离

安装基础依赖

安装 Xcode

这一步没什么说的,保持 Xcode 最新版本即可

安装 pyyaml

这一步需要用到 Python3 自带的 venv,这对没接触过 python 依赖管理的前端程序员(我也不例外)可能会踩一些坑

文档里写的是

sh 复制代码
# use the virtual environment to manage python environment
python3 -m venv venv
source venv/bin/activate
# install PyYAML package
pip3 install pyyaml

但是这一步要在哪里进行呢🤔

经过我实践得到的结论是:不重要

重要的是明白这一步的原理,python3 -m venv venv 是使用 python3 运行 venv 这个模块(-m 就是 module 的意思),其中第二个 venv 是指定 python 创建虚拟环境的目录名,所以理论上这个名字可以任意指定,只是这里选择使用 venv。

接着 source venv/bin/activate 是执行刚刚创建的 venv 里的可执行文件 activate 以激活 python 虚拟环境(python 虚拟环境是用来在指定目录安装依赖,并且不会污染全局的一种工具)

venv 激活后,一般会在当前 shell 环境前面显示当前所在的虚拟环境目录,比如当我创建的虚拟环境叫 my-venv,那我在 my-lynx 目录时的 shell 就会如下显示

sh 复制代码
(my-venv) ➜  my-lynx

这也意味着你可以开始使用这个虚拟环境安装依赖了

sh 复制代码
(my-venv) ➜  my-lynx pip3 install pyyaml
Collecting pyyaml
  Using cached PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl.metadata (2.1 kB)
Using cached PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl (171 kB)
Installing collected packages: pyyaml
Successfully installed pyyaml-6.0.2

[notice] A new release of pip is available: 25.0 -> 25.0.1
[notice] To update, run: pip install --upgrade pip

安装完成后我们可以使用 pip 的命令检查一下安装的依赖是否存在

sh 复制代码
(my-venv) ➜  my-lynx pip list pyyaml
Package Version
------- -------
pip     25.0
PyYAML  6.0.2
sh 复制代码
(my-venv) ➜  my-lynx pip show pyyaml
Name: PyYAML
Version: 6.0.2
Summary: YAML parser and emitter for Python
Home-page: https://pyyaml.org/
Author: Kirill Simonov
Author-email: xi@resolvent.net
License: MIT
Location: /Users/xxx/GitHub/my-lynx/my-venv/lib/python3.13/site-packages
Requires:
Required-by:

venv 会在执行 python3 -m venv venv 所在的目录创建虚拟环境目录,如果你不想在自己的目录下创建,也可以下载完 lynx 项目后在 lynx 所在目录创建。 但其实 venv 只是一个用于安装依赖的临时目录,你完全可以在 lynx 依赖安装完成后将其删除。

这样我们就准备好了本地构建 Lynx 的系统环境及依赖

下载 Lynx 源码

接下来,我们按照文档指示将 lynx 源码下载到本地

sh 复制代码
git clone https://github.com/lynx-family/lynx.git src/lynx

注意⚠️这里 lynx 推荐将 lynx 项目源码下载到指定的二级目录,这是因为 lynx 会在构建的过程中自动生成一系列其他目录,位置与 lynx 并列。为避免这些自动生成的目录污染你的文件夹,lynx 推荐在源码之上再增加一层父目录来统一管理 lynx 相关的目录。

这里的父目录可以任意指定,只是官方使用了 src,我这里使用了 my-lynx

sh 复制代码
git clone https://github.com/lynx-family/lynx.git my-lynx/lynx

安装 lynx 项目依赖

接着,我们进入到 lynx 源码根目录,如果你的 shell 识别到当前目录是一个 git 项目即表示你进到的正确的位置,如下

sh 复制代码
lynx git:(develop)

接着,我们会来到一个坑最多的环节,使用 hab 安装依赖。

hab 是 lynx 团队基于 Python 开发的一款项目依赖管理工具,它会识别 .habitat 目录和 DEPS 文件进行依赖解析,同时有一个同名的二进制文件用于执行安装依赖。

lynx 源码的子目录 tools 下有一个 hab 二进制文件,但它的 .habitat 和 DEPS 是在项目根目录,因此这里要注意一定要在项目根目录通过以下命令安装依赖,不可进入到 tools 目录去执行

sh 复制代码
tools/hab sync .

你以为这样就完了吗,好戏才刚刚开始呢🤦

lynx 是通过 hab 一整套管理整个项目的全部依赖

不同于 Flutter 是让你自己去准备 iOS 和安装的相关依赖及工具

这样虽然有好处,某种程度上将依赖管理统一维护起来,避免安装过程过于分散,不需要开发者到各个网站下自行寻找,而且对依赖的版本也可以做统一的管理。

但是因为要下载的东西非常之多,并且是在终端进行,这就非常考验各位开发者🪜(代理工具)的稳定性了

直接说结论:不要直接使用代理工具复制出来的的终端配置

sh 复制代码
export http_proxy=http://127.0.0.1:9098;export https_proxy=http://127.0.0.1:9098;export ALL_PROXY=socks5://127.0.0.1:16143

因为这个配置代理了 socks 请求,这会导致 hab 在安装依赖的过程中产生如下报错

sh 复制代码
ERROR ImportError: Using SOCKS proxy, but the 'socksio' package is not installed. Make sure to install httpx using `pip install httpx[socks]`

但也不能因噎废食不对终端进行代理,否则你在安装其他依赖时同样会失败,例如下面这种

sh 复制代码
ERROR HabitatException: failed to fetch dependency https://services.gradle.org/distributions/gradle-6.7.1-all.zip@https://services.gradle.org/distributions/gradle-6.7.1-all.zip to /Users/xxx/GitHub/lynx-root/src/lynx/platform/android/gradle/wrapper/gradle-6.7.1-all.zip

正确的代理方式是仅配置 http_proxy 和 https_proxy,这是我尝试多次后找到的最佳实践,我把过程记录在我提的另一个 issue 下面,感兴趣的可以去了解

github.com/lynx-family...

甚至后面还出现很多类似的 issue

如果这一步能够完成,那么距离本地构建 lynx 就非常之近了。

注意⚠️安装过程中不能有报错,否则任何依赖安装失败都可能导致无法启动 Lynx Explorer

正常的依赖安装完成应该展示如下内容

sh 复制代码
INFO Dependencies for /Users/xxx/GitHub/lynx-root/src/lynx are ready

并且你会发现和 lynx 同级出现了一些其他目录 build、buildtools 和 third_party,这些都是构建 lynx 必备的工具

启动 Lynx Explorer

接下来,我们就可以进入到 iOS 的 explorer 目录进行最后的配置了

sh 复制代码
cd explorer/darwin/ios/lynx_explorer
./bundle_install.sh

但这里又有一个坑,就是官方提供的脚本实际是用于同时初始化 iOS 和 安卓环境的,因此对于只想构建 iOS explorer 的小伙伴可能会被这步卡住,然后转头去把安卓的开发环境也准备好再回来。

关于这个问题,我也已经给他们提了 PR 等待回应

我本地是按照我 PR 中的修改方式临时绕过了对于安卓环境的检查,从而顺利构建 iOS 版的 Explorer

这一步成功的标识是终端展示如下内容,并且没有报错

sh 复制代码
-> Pod installation complete! There are 17 dependencies from the Podfile and 12 total pods installed.

这样,在 explorer/darwin/ios/lynx_explorer 目录下应该会新出现 LynxExplorer.xcodeproj 目录

Xcode 使用

最后一步,就是使用 Xcode 启动构建出来的 iOS Explorer,这一步对于没有 iOS 开发经验的开发者可能也会有些吃力(比如我)

但好在官方在 Troubleshooting 中提到了这里的一些注意事项:github.com/lynx-family...

这里我就提几个重要的点

首先使用 Xcode 打开刚刚构建好的 xcworkspace,打开后如下图

注意⚠️选择的 LynxExplorer.xcworkspace,而不是 LynxExplorer.xcodeproj,否则会构建失败

接着到设置项的账户(Accounts)菜单登录自己的 iCloud 账号,创建个人团队以及当前 Mac 设备的开发者证书

然后把 com.lynx.LynxExplorer 中间的 lynx 修改为自己的团队标识,否则设置中也会报警告

真机构建

最后,用数据线连接手机和 Mac,这里还需要开启 iPhone 的开发者模式并重启手机。然后在 Xcode 中选择构建目标为所连接的手机

这里还需要手机配置对于 LynxExplorer APP 的信任

点击构建,即可在真机上看到打开的 Lynx Explorer

这样我们就可以使用真机访问本地运行的 Lynx APP 了,也就是一开始我们在 项目启动 中得到的预览链接

sh 复制代码
http://192.168.1.18:3001/main.lynx.bundle?fullscreen=true

这里可以使用 Mac 和 iPhone 的跨设备剪切板功能,在 Mac 上复制链接,在 iPhone 上粘贴

如果顺利的话,应该可以在自己的手机上预览到本地运行 Lynx APP,然后修改 App.tsx 即可看到手机上实时展示热更新后到内容

完结撒花🎉

相关推荐
秋月华星41 分钟前
【flutter】TextField输入框工具栏文本为英文解决(不用安装插件版本
前端·javascript·flutter
千里码aicood1 小时前
[含文档+PPT+源码等]精品基于Python实现的校园小助手小程序的设计与实现
开发语言·前端·python
青红光硫化黑2 小时前
React基础之React.memo
前端·javascript·react.js
大麦大麦2 小时前
深入剖析 Sass:从基础到进阶的 CSS 预处理器应用指南
开发语言·前端·css·面试·rust·uni-app·sass
m0_616188493 小时前
Vue3 中 Computed 用法
前端·javascript·vue.js
六个点3 小时前
图片懒加载与预加载的实现
前端·javascript·面试
Moment4 小时前
前端 社招 面筋分享:前端两年都问些啥 ❓️❓️❓️
前端·javascript·面试
Moment4 小时前
一坤时学习 TS 中的装饰器,让你写 NestJS 不再手软 😏😏😏
前端·javascript·面试
子洋4 小时前
AnythingLLM + SearXNG 实现私有搜索引擎代理
前端·人工智能·后端