⚠️ For Your Infomation:本文所实践的方法非最优解,笔者也不建议使用 AST 自动生成 React Native 路由,因为 Babel 操作相对复杂且容易导致错误,笔者更建议使用模板字符串。本文主要目的是验证 AST 在自动路由生成方面的可行性,而非最佳实践指南。
在 React Native 中,无法使用 React Route
或 Wouter
这类基于浏览器环境的路由管理工具,因为 React Native 自身不运行在浏览器环境,所以没有浏览器的 DOM 或 BOM API。因此需要使用 React Navigation
使用系统级原生 API 创建与管理界面(在 Android 里为 Activity,在 iOS 为 UIView)
在使用 React Navigation
时,需要手动使用 Stack.Screen
声明每一个页面。它无法像 umi
或 next.js
这类框架,通过约定式路由或路由声明文件来自动生成路由表。这是因为 React Native 里的 JS 它不运行在 node.js
,只是一个很单纯的运行时环境。
import Home from './pages/home'
import Login from './pages/login'
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={Home}/>
<Stack.Screen name="Login" component={Login}/>
</Stack.Navigator>
那么这就意味着,在 React Native 无论编译时还是运行时,都无法做到自动导入,只能在 React Native 的 Metro( RN 专门的打包工具)启动前进行处理
以下内容将围绕以上问题,使用 AST 自动构建入口文件进行路由自动生成
您将在本文实践中,使用以下第三方代码:
https://github.com/isaacs/node-glob
@babel/plugin-transform-react-jsx
一般 React Native 项目中,都会规范好页面文件的路径与命名规范,具体视您项目的规范确定,在本文将使用 /pages/${page-name}/index
规范命名
本文将使用 npm 包 glob
,用于匹配文件。使用 glob
作为文件查找工具,是因为其支持通配符与类正则表达式,相比 fs
操作方式更为高效
glob(
path.resolve(__dirname, './pages/*/?(index|index.android|index.ios).tsx'),
(error, files) => {
if (error) {
return
}
}
)
根据以上命名规范,用于匹配的表达式为 './pages/*/?(index|index.android|index.ios).tsx'
,index.android
与 index.ios
是 React Native 根据构建目标选择不同拓展名的文件,具体可参考:
Platform Specific Code · React Native