miaoda-expo-devkit 0.1.1-beta.4 → 0.1.1-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -7
- package/biome-config.json +24 -1
- package/dist/babel/plugin-jsx-source.d.ts +2 -0
- package/dist/babel/plugin-jsx-source.js +12 -3
- package/dist/babel/plugin-lucide-react-native.d.ts +31 -0
- package/dist/babel/plugin-lucide-react-native.js +14790 -0
- package/dist/babel/preset.d.ts +8 -0
- package/dist/babel/preset.js +7 -5
- package/dist/cli/lint.js +25 -11
- package/dist/metro.d.mts +294 -71
- package/dist/metro.d.ts +294 -71
- package/dist/metro.js +360 -66
- package/dist/metro.mjs +354 -66
- package/dist/rules/no-duplicate-expo-router-url.js +17 -15
- package/dist/rules/no-expo-video-compat.js +2041 -0
- package/dist/rules/no-invalid-tabs-screen.js +193 -0
- package/dist/rules/no-missing-css-import.js +100 -0
- package/dist/rules/no-pressable-without-on-press.js +77 -0
- package/dist/rules/no-undeclared-expo-plugin.js +16 -11
- package/dist/rules/no-unregistered-dynamic-tab-route.js +183 -0
- package/dist/rules/no-unused-expo-plugin.js +163 -0
- package/dist/stubs/expo-blur-stub.js +29 -0
- package/dist/stubs/expo-calendar-stub.js +353 -0
- package/dist/stubs/expo-camera-stub.js +28 -0
- package/dist/stubs/expo-file-system-stub.js +214 -0
- package/dist/stubs/expo-image-stub.js +28 -0
- package/dist/stubs/expo-linear-gradient-stub.js +28 -0
- package/dist/stubs/expo-media-library-stub.js +141 -0
- package/dist/stubs/expo-notifications-stub.js +177 -0
- package/dist/stubs/lgui-control.js +80 -7
- package/dist/stubs/web-stub-dialog.js +168 -0
- package/oxlint-config.json +27 -1
- package/package.json +53 -28
- package/pnpm-config.json +1 -6
- package/tsconfig-base.json +7 -0
package/README.md
CHANGED
|
@@ -7,6 +7,9 @@ Expo / React Native 开发环境工具集,通过 Metro 构建层注入以下
|
|
|
7
7
|
- **Bundle 首部注入** — 在 expo-router 初始化之前执行自定义脚本
|
|
8
8
|
- **HMR postMessage 控制** — 通过 `window.postMessage` 在运行时启动或停止 Fast Refresh
|
|
9
9
|
- **LogBox 屏蔽** — web 平台禁用 Expo 全屏错误遮罩
|
|
10
|
+
- **expo-notifications stub** — Expo Go(Android)中提供 no-op 实现,核心 API 调用时弹出带参数校验的调试 Alert,Dev Build 透传真实模块
|
|
11
|
+
- **expo-media-library stub** — Expo Go / Web 中提供 no-op 实现,`saveToLibraryAsync`、`createAssetAsync`、权限请求等 API 调用时弹出 Alert 提示,Dev Build 原生环境透传真实模块
|
|
12
|
+
- **expo-calendar stub** — Expo Go / Web 中提供 no-op 实现,`getEventsAsync`、`createEventAsync`、`getCalendarsAsync`、权限请求等核心 API 调用时弹出 Alert 提示并校验参数,Dev Build 原生环境透传真实模块
|
|
10
13
|
|
|
11
14
|
## 安装
|
|
12
15
|
|
|
@@ -32,16 +35,16 @@ pnpm install
|
|
|
32
35
|
```js
|
|
33
36
|
// metro.config.js
|
|
34
37
|
const { getDefaultConfig } = require('expo/metro-config');
|
|
35
|
-
const {
|
|
38
|
+
const { withDevkit } = require('miaoda-expo-devkit/metro');
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
module.exports = withEntryInjection(withDevStubs(config));
|
|
40
|
+
module.exports = withDevkit(getDefaultConfig(__dirname));
|
|
39
41
|
```
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
`withDevkit` 已内置所有 wrapper(含 expo-notifications、expo-media-library、expo-calendar stub),无需手动叠加。也可单独使用各 wrapper:
|
|
42
44
|
|
|
43
45
|
```js
|
|
44
|
-
|
|
46
|
+
const { withDevStubs, withEntryInjection, withExpoMediaLibraryStub, withExpoCalendarStub } = require('miaoda-expo-devkit/metro');
|
|
47
|
+
module.exports = withExpoCalendarStub(withExpoMediaLibraryStub(withEntryInjection(withDevStubs(config))));
|
|
45
48
|
```
|
|
46
49
|
|
|
47
50
|
### Sentry 初始化
|
|
@@ -225,12 +228,27 @@ expect(onError).toHaveBeenCalledWith(
|
|
|
225
228
|
|
|
226
229
|
```
|
|
227
230
|
metro.config.js
|
|
228
|
-
└─
|
|
231
|
+
└─ withDevkit(config)
|
|
229
232
|
│
|
|
230
233
|
├─ withDevStubs → resolver.resolveRequest
|
|
231
234
|
│ ├─ @sentry/react-native → dist/stubs/sentry-react-native-stub.js (全平台)
|
|
232
235
|
│ └─ @expo/log-box → dist/stubs/no-op-logbox.js (仅 web)
|
|
233
236
|
│
|
|
237
|
+
├─ withExpoNotificationsStub → resolver.resolveRequest
|
|
238
|
+
│ └─ expo-notifications → dist/stubs/expo-notifications-stub.js (仅 Android)
|
|
239
|
+
│ ├─ Expo Go:no-op + 调试 Alert(含参数校验)
|
|
240
|
+
│ └─ Dev Build:透传真实 expo-notifications
|
|
241
|
+
│
|
|
242
|
+
├─ withExpoMediaLibraryStub → resolver.resolveRequest
|
|
243
|
+
│ └─ expo-media-library → dist/stubs/expo-media-library-stub.js (全平台)
|
|
244
|
+
│ ├─ Expo Go / Web:no-op + Alert 提示(不崩溃)
|
|
245
|
+
│ └─ Dev Build(原生):透传真实 expo-media-library
|
|
246
|
+
│
|
|
247
|
+
├─ withExpoCalendarStub → resolver.resolveRequest
|
|
248
|
+
│ └─ expo-calendar → dist/stubs/expo-calendar-stub.js (全平台)
|
|
249
|
+
│ ├─ Expo Go / Web:no-op + Alert 提示 + 参数校验(不崩溃)
|
|
250
|
+
│ └─ Dev Build(原生):透传真实 expo-calendar
|
|
251
|
+
│
|
|
234
252
|
└─ withEntryInjection → resolver.resolveRequest
|
|
235
253
|
└─ expo-router/entry-classic → dist/stubs/expo-router-entry-stub.js
|
|
236
254
|
├─ require('./entry-inject') ← 注入脚本(bundle 首部执行)
|
|
@@ -262,10 +280,14 @@ sentry-react-native-stub.js
|
|
|
262
280
|
| 子路径 | 文件 | 内容 |
|
|
263
281
|
|---|---|---|
|
|
264
282
|
| `.` | `dist/index.js` | `SentryCapture`、`MetroSymbolicator`、全部类型 |
|
|
265
|
-
| `./metro` | `dist/metro.js` | `withDevStubs`、`withEntryInjection` |
|
|
283
|
+
| `./metro` | `dist/metro.js` | `withDevkit`、`withDevStubs`、`withEntryInjection`、`withExpoNotificationsStub`、`withExpoMediaLibraryStub`、`withExpoCalendarStub` 等 |
|
|
266
284
|
| `./babel-plugin-jsx-source` | `dist/babel/plugin-jsx-source.js` | Babel 插件:为 JSX 注入 source 信息 |
|
|
285
|
+
| `./babel-preset` | `dist/babel/preset.js` | Babel Preset:集成 jsx-source 和 lucide 插件 |
|
|
267
286
|
| `./sentry-react-native-stub` | `dist/stubs/sentry-react-native-stub.js` | `@sentry/react-native` 模块替换 stub |
|
|
268
287
|
| `./no-op-logbox` | `dist/stubs/no-op-logbox.js` | LogBox no-op stub |
|
|
288
|
+
| `./expo-notifications-stub` | `dist/stubs/expo-notifications-stub.js` | `expo-notifications` Expo Go Android stub |
|
|
289
|
+
| `./expo-media-library-stub` | `dist/stubs/expo-media-library-stub.js` | `expo-media-library` Expo Go / Web stub |
|
|
290
|
+
| `./expo-calendar-stub` | `dist/stubs/expo-calendar-stub.js` | `expo-calendar` Expo Go / Web stub |
|
|
269
291
|
|
|
270
292
|
---
|
|
271
293
|
|
|
@@ -388,6 +410,91 @@ LogBox no-op stub,用于 web 平台禁用 Expo 全屏错误遮罩。
|
|
|
388
410
|
|
|
389
411
|
---
|
|
390
412
|
|
|
413
|
+
### expo-notifications-stub.js
|
|
414
|
+
|
|
415
|
+
`expo-notifications` 模块替换 stub,由 `withExpoNotificationsStub()` 在 Metro 层注入(**仅 Android 平台**)。
|
|
416
|
+
|
|
417
|
+
**背景:** Expo SDK 53 起,`expo-notifications` 的 Android native module 已从 Expo Go 中移除,直接 import 会在 Expo Go 启动时崩溃。
|
|
418
|
+
|
|
419
|
+
**运行时行为:**
|
|
420
|
+
- **Expo Go(Android)**:提供 no-op 实现,`requestPermissionsAsync`、`setNotificationChannelAsync`、`scheduleNotificationAsync` 等核心 API 调用时弹出带参数校验的调试 Alert
|
|
421
|
+
- **Development Build(Android)**:透传真实 `expo-notifications`,功能完全正常
|
|
422
|
+
- **iOS(任意)**:不经过此 stub,直接使用真实 `expo-notifications`
|
|
423
|
+
|
|
424
|
+
**手动验证:** 在 `devkit-e2e` App 中扫码进入「Notification Stub 验证」页面,逐按钮触发并对照期望结果。
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
### expo-media-library-stub.js
|
|
429
|
+
|
|
430
|
+
`expo-media-library` 模块替换 stub,由 `withExpoMediaLibraryStub()` 在 Metro 层注入(**全平台**)。
|
|
431
|
+
|
|
432
|
+
**背景:** `expo-media-library` 依赖原生相册 API,在 Expo Go 和 Web 环境中不可用,调用 `saveToLibraryAsync` 等 API 会直接崩溃。
|
|
433
|
+
|
|
434
|
+
**运行时行为:**
|
|
435
|
+
- **Expo Go / Web**:提供 no-op 实现,以下 API 调用时弹出 Alert 提示(不崩溃):
|
|
436
|
+
- `usePermissions()` — 返回 `{ status: 'undetermined', granted: false }`,`requestPermission()` 弹 Alert
|
|
437
|
+
- `requestPermissionsAsync()` / `getPermissionsAsync()` — 前者弹 Alert,后者静默返回 denied
|
|
438
|
+
- `saveToLibraryAsync(uri)` — 弹 Alert 显示操作和 URI(超 60 字符自动截断)
|
|
439
|
+
- `createAssetAsync(uri)` — 弹 Alert 并返回合法的伪资产对象
|
|
440
|
+
- 其他未知 API — Proxy 兜底,静默返回 `undefined`;以 `PermissionsAsync` 结尾的 API 返回 denied 结构
|
|
441
|
+
- **Development Build(原生)**:透传真实 `expo-media-library`,功能完全正常
|
|
442
|
+
|
|
443
|
+
**Alert 消息格式:**
|
|
444
|
+
```
|
|
445
|
+
保存到相册
|
|
446
|
+
Expo Go 扫码预览不支持访问手机相册
|
|
447
|
+
操作: 图片: file:///tmp/test.jpg
|
|
448
|
+
发布为正式 App 后可正常使用
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**手动验证:** 在 `devkit-e2e` App 中扫码进入「Media Library Stub 验证」页面,逐按钮触发并对照期望结果。
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
### expo-calendar-stub.js
|
|
456
|
+
|
|
457
|
+
`expo-calendar` 模块替换 stub,由 `withExpoCalendarStub()` 在 Metro 层注入(**全平台**)。
|
|
458
|
+
|
|
459
|
+
**背景:** `expo-calendar` 依赖原生系统日历 API,在 Expo Go 和 Web 环境中不可用,调用 `getEventsAsync` 等 API 会直接崩溃。
|
|
460
|
+
|
|
461
|
+
**运行时行为:**
|
|
462
|
+
- **Expo Go / Web**:提供 no-op 实现,以下 API 调用时弹出 Alert / Dialog 提示(不崩溃):
|
|
463
|
+
- `useCalendarPermissions()` / `useRemindersPermissions()` — 初始返回 `undetermined`,`requestPermission()` 弹 Alert
|
|
464
|
+
- `requestCalendarPermissionsAsync()` / `requestRemindersPermissionsAsync()` — 弹 Alert 提示,返回 denied
|
|
465
|
+
- `getCalendarPermissionsAsync()` / `getRemindersPermissionsAsync()` — 静默返回 denied
|
|
466
|
+
- `getCalendarsAsync(entityType?)` — 弹 Alert 显示查询类型,返回空数组
|
|
467
|
+
- `createCalendarAsync(details)` — 弹 Alert 含名称和颜色,校验 `details.title` 非空
|
|
468
|
+
- `updateCalendarAsync(id, details)` / `deleteCalendarAsync(id)` — 弹 Alert 含日历 ID,校验 ID 格式
|
|
469
|
+
- `getEventsAsync(calendarIds, startDate, endDate)` — 弹 Alert 含时间范围,校验 calendarIds 非空及日期合法性,返回空数组
|
|
470
|
+
- `createEventAsync(calendarId, eventData)` — 弹 Alert 含标题和时间,Android 下校验 startDate/endDate
|
|
471
|
+
- `updateEventAsync(id, details)` / `deleteEventAsync(id)` — 弹 Alert 含事件 ID,校验 ID 格式
|
|
472
|
+
- 其他未知 API — Proxy 兜底,静默返回 `undefined`;以 `PermissionsAsync` 结尾的 API 返回 denied 结构
|
|
473
|
+
- **Development Build(原生)**:透传真实 `expo-calendar`,功能完全正常
|
|
474
|
+
|
|
475
|
+
**枚举常量**(stub & Dev Build 均可用):
|
|
476
|
+
`EntityTypes`、`Frequency`、`Availability`、`CalendarType`、`EventStatus`、`SourceType`、
|
|
477
|
+
`AttendeeRole`、`AttendeeStatus`、`AttendeeType`、`AlarmMethod`、`EventAccessLevel`、
|
|
478
|
+
`CalendarAccessLevel`、`ReminderStatus`、`DayOfTheWeek`、`MonthOfTheYear`
|
|
479
|
+
|
|
480
|
+
**Alert 消息格式(合规示例):**
|
|
481
|
+
```
|
|
482
|
+
创建日历事件
|
|
483
|
+
秒哒扫码预览不支持访问手机日历
|
|
484
|
+
|
|
485
|
+
日历 ID: cal1
|
|
486
|
+
标题: 团队会议
|
|
487
|
+
开始: 2025/1/1 10:00:00
|
|
488
|
+
结束: 2025/1/1 11:00:00
|
|
489
|
+
|
|
490
|
+
✅ 参数合规
|
|
491
|
+
发布为正式 App 后可正常使用
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
**手动验证:** 在 `devkit-e2e` App 中扫码进入「Calendar Stub 验证」页面,逐按钮触发并对照期望结果。
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
391
498
|
## Babel 插件:jsx-source
|
|
392
499
|
|
|
393
500
|
`babel-plugin-jsx-source` 为 JSX 元素注入 source 属性(文件路径、行列号),用于开发调试。通过 `dataSet` 对象注入,这是 React Web 可识别的数据通道。
|
|
@@ -434,3 +541,81 @@ module.exports = {
|
|
|
434
541
|
|---|---|---|---|
|
|
435
542
|
| `rootDir` | `string` | - | 项目根目录,用于计算相对路径。不提供则使用绝对路径 |
|
|
436
543
|
| `excludePaths` | `string[]` | `[]` | 跳过注入的路径模式列表(相对于 rootDir 的路径片段) |
|
|
544
|
+
|
|
545
|
+
---
|
|
546
|
+
|
|
547
|
+
## Babel 插件:lucide-react-native
|
|
548
|
+
|
|
549
|
+
Metro 没有 tree-shaking,直接写 `import { Star } from "lucide-react-native"` 会把整个图标库(约 1500 个图标)打进 bundle。`babel-plugin-lucide-react-native` 在编译阶段将具名导入改写为直接按文件导入,彻底规避这个问题。
|
|
550
|
+
|
|
551
|
+
**转换效果:**
|
|
552
|
+
|
|
553
|
+
```ts
|
|
554
|
+
// 转换前
|
|
555
|
+
import { Star, BookOpen } from "lucide-react-native";
|
|
556
|
+
|
|
557
|
+
// 转换后(CJS,默认)
|
|
558
|
+
import _Star from "lucide-react-native/dist/cjs/icons/star";
|
|
559
|
+
import _BookOpen from "lucide-react-native/dist/cjs/icons/book-open";
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### 配置
|
|
563
|
+
|
|
564
|
+
推荐通过内置 Preset 一次性启用所有 Babel 插件:
|
|
565
|
+
|
|
566
|
+
```js
|
|
567
|
+
// babel.config.js
|
|
568
|
+
module.exports = {
|
|
569
|
+
presets: [['miaoda-expo-devkit/babel-preset', { excludePaths: ['src/components/ui'] }]],
|
|
570
|
+
};
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
也可以单独使用:
|
|
574
|
+
|
|
575
|
+
```js
|
|
576
|
+
module.exports = {
|
|
577
|
+
plugins: [['miaoda-expo-devkit/babel-plugin-lucide-react-native']],
|
|
578
|
+
};
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### 选项
|
|
582
|
+
|
|
583
|
+
| 选项 | 类型 | 默认值 | 说明 |
|
|
584
|
+
|---|---|---|---|
|
|
585
|
+
| `useES` | `boolean` | `false` | 使用 ESM 格式(`dist/esm/icons/`)而非默认的 CJS |
|
|
586
|
+
|
|
587
|
+
### 支持的写法
|
|
588
|
+
|
|
589
|
+
插件可识别所有常见的图标引用写法:
|
|
590
|
+
|
|
591
|
+
```ts
|
|
592
|
+
import { BookOpen, Star, Crown } from "lucide-react-native";
|
|
593
|
+
|
|
594
|
+
// JSX 直接使用
|
|
595
|
+
<BookOpen size={24} />
|
|
596
|
+
|
|
597
|
+
// 赋值给变量
|
|
598
|
+
const icon = BookOpen;
|
|
599
|
+
|
|
600
|
+
// 对象 value
|
|
601
|
+
const ITEMS = [{ icon: BookOpen }, { icon: Star }];
|
|
602
|
+
|
|
603
|
+
// 计算属性 key
|
|
604
|
+
const map = { [BookOpen]: 'read' };
|
|
605
|
+
|
|
606
|
+
// 数组、三元、函数参数
|
|
607
|
+
const list = [BookOpen, Star];
|
|
608
|
+
const active = flag ? BookOpen : Star;
|
|
609
|
+
renderIcon(Crown);
|
|
610
|
+
|
|
611
|
+
// 导入别名
|
|
612
|
+
import { BookOpen as ReadIcon } from "lucide-react-native";
|
|
613
|
+
<ReadIcon />
|
|
614
|
+
|
|
615
|
+
// re-export
|
|
616
|
+
export { Star, BookOpen as ReadIcon } from "lucide-react-native";
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### 版本兼容性
|
|
620
|
+
|
|
621
|
+
插件在运行时探测 `lucide-react-native` 的实际目录结构,自动适配新旧版本的路径差异(`>= 1.9` 新增 `icons/` 子目录;旧版 `1.8.x` 图标直接位于 `dist/cjs/`),lucide 升级时无需修改配置。
|
package/biome-config.json
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"vcs": {
|
|
3
|
+
"enabled": true,
|
|
4
|
+
"clientKind": "git",
|
|
5
|
+
"useIgnoreFile": true
|
|
6
|
+
},
|
|
7
|
+
"files": {
|
|
8
|
+
"includes": [
|
|
9
|
+
"src/**/*.{js,jsx,ts,tsx,css,scss}",
|
|
10
|
+
"tailwind.config.js"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
2
13
|
"linter": {
|
|
3
14
|
"enabled": true,
|
|
4
15
|
"rules": {
|
|
@@ -10,5 +21,17 @@
|
|
|
10
21
|
},
|
|
11
22
|
"formatter": {
|
|
12
23
|
"enabled": false
|
|
13
|
-
}
|
|
24
|
+
},
|
|
25
|
+
"overrides": [
|
|
26
|
+
{
|
|
27
|
+
"includes": ["tailwind.config.js"],
|
|
28
|
+
"linter": {
|
|
29
|
+
"rules": {
|
|
30
|
+
"style": {
|
|
31
|
+
"noCommonJs": "off"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
14
37
|
}
|
|
@@ -14,8 +14,10 @@ import { types, PluginObj } from '@babel/core';
|
|
|
14
14
|
*
|
|
15
15
|
* 对于纯文本节点:
|
|
16
16
|
* <div>hello world</div>
|
|
17
|
+
* <div>{"hello world"}</div>
|
|
17
18
|
* 转换后:
|
|
18
19
|
* <div dataSet={{"mdId": "path/to/file.tsx:10:4", "componentContent": "{\"text\":\"hello world\"}"}}>hello world</div>
|
|
20
|
+
* <div dataSet={{"mdId": "path/to/file.tsx:11:4", "componentContent": "{\"text\":\"hello world\"}"}}>{"hello world"}</div>
|
|
19
21
|
*
|
|
20
22
|
* 用法(babel.config.js):
|
|
21
23
|
*
|
|
@@ -69,9 +69,18 @@ function getTextNodeContent(t, path) {
|
|
|
69
69
|
const children = parent.children;
|
|
70
70
|
if (children.length !== 1) return null;
|
|
71
71
|
const child = children[0];
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
if (t.isJSXText(child)) {
|
|
73
|
+
const text = child.value.trim();
|
|
74
|
+
return text || null;
|
|
75
|
+
}
|
|
76
|
+
if (t.isJSXExpressionContainer(child) && t.isStringLiteral(child.expression)) {
|
|
77
|
+
const text = child.expression.value.trim();
|
|
78
|
+
return text || null;
|
|
79
|
+
}
|
|
80
|
+
if (t.isJSXExpressionContainer(child) && t.isNumericLiteral(child.expression)) {
|
|
81
|
+
return String(child.expression.value);
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
75
84
|
}
|
|
76
85
|
function shouldSkipElement(t, name) {
|
|
77
86
|
if (t.isJSXIdentifier(name)) {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import babelCore from '@babel/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* babel-plugin-lucide-react-native
|
|
5
|
+
*
|
|
6
|
+
* 将 lucide-react-native 的具名导入转换为按图标文件直接导入,绕过 Metro
|
|
7
|
+
* 缺乏 tree-shaking 的问题,避免将整个图标库打进 bundle。
|
|
8
|
+
*
|
|
9
|
+
* 转换示意:
|
|
10
|
+
* import { Star, BookHeart } from "lucide-react-native"
|
|
11
|
+
* →
|
|
12
|
+
* import _Star from "lucide-react-native/dist/cjs/icons/star"
|
|
13
|
+
* import _BookHeart from "lucide-react-native/dist/cjs/icons/book-heart"
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
type Core = typeof babelCore;
|
|
17
|
+
interface Config extends babelCore.PluginPass {
|
|
18
|
+
opts: {
|
|
19
|
+
/** 使用 ESM 格式(dist/esm)。默认 false,使用 CJS(dist/cjs)。 */
|
|
20
|
+
useES?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* lucide-react-native 包根目录的绝对路径(含 package.json 的那一层)。
|
|
23
|
+
* 不传时通过 require.resolve 自动定位,适用于生产场景。
|
|
24
|
+
* 测试时可传入特定版本的路径,验证不同版本的兼容性。
|
|
25
|
+
*/
|
|
26
|
+
lucidePkgRoot?: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
declare function lucideReactNativePlugin({ types: t }: Core): babelCore.PluginObj<Config>;
|
|
30
|
+
|
|
31
|
+
export { lucideReactNativePlugin as default };
|