miaoda-expo-devkit 0.1.1-beta.23 → 0.1.1-beta.25

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 CHANGED
@@ -264,6 +264,7 @@ sentry-react-native-stub.js
264
264
  | `.` | `dist/index.js` | `SentryCapture`、`MetroSymbolicator`、全部类型 |
265
265
  | `./metro` | `dist/metro.js` | `withDevStubs`、`withEntryInjection` |
266
266
  | `./babel-plugin-jsx-source` | `dist/babel/plugin-jsx-source.js` | Babel 插件:为 JSX 注入 source 信息 |
267
+ | `./babel-preset` | `dist/babel/preset.js` | Babel Preset:集成 jsx-source 和 lucide 插件 |
267
268
  | `./sentry-react-native-stub` | `dist/stubs/sentry-react-native-stub.js` | `@sentry/react-native` 模块替换 stub |
268
269
  | `./no-op-logbox` | `dist/stubs/no-op-logbox.js` | LogBox no-op stub |
269
270
 
@@ -434,3 +435,81 @@ module.exports = {
434
435
  |---|---|---|---|
435
436
  | `rootDir` | `string` | - | 项目根目录,用于计算相对路径。不提供则使用绝对路径 |
436
437
  | `excludePaths` | `string[]` | `[]` | 跳过注入的路径模式列表(相对于 rootDir 的路径片段) |
438
+
439
+ ---
440
+
441
+ ## Babel 插件:lucide-react-native
442
+
443
+ Metro 没有 tree-shaking,直接写 `import { Star } from "lucide-react-native"` 会把整个图标库(约 1500 个图标)打进 bundle。`babel-plugin-lucide-react-native` 在编译阶段将具名导入改写为直接按文件导入,彻底规避这个问题。
444
+
445
+ **转换效果:**
446
+
447
+ ```ts
448
+ // 转换前
449
+ import { Star, BookOpen } from "lucide-react-native";
450
+
451
+ // 转换后(CJS,默认)
452
+ import _Star from "lucide-react-native/dist/cjs/icons/star";
453
+ import _BookOpen from "lucide-react-native/dist/cjs/icons/book-open";
454
+ ```
455
+
456
+ ### 配置
457
+
458
+ 推荐通过内置 Preset 一次性启用所有 Babel 插件:
459
+
460
+ ```js
461
+ // babel.config.js
462
+ module.exports = {
463
+ presets: [['miaoda-expo-devkit/babel-preset', { excludePaths: ['src/components/ui'] }]],
464
+ };
465
+ ```
466
+
467
+ 也可以单独使用:
468
+
469
+ ```js
470
+ module.exports = {
471
+ plugins: [['miaoda-expo-devkit/babel-plugin-lucide-react-native']],
472
+ };
473
+ ```
474
+
475
+ ### 选项
476
+
477
+ | 选项 | 类型 | 默认值 | 说明 |
478
+ |---|---|---|---|
479
+ | `useES` | `boolean` | `false` | 使用 ESM 格式(`dist/esm/icons/`)而非默认的 CJS |
480
+
481
+ ### 支持的写法
482
+
483
+ 插件可识别所有常见的图标引用写法:
484
+
485
+ ```ts
486
+ import { BookOpen, Star, Crown } from "lucide-react-native";
487
+
488
+ // JSX 直接使用
489
+ <BookOpen size={24} />
490
+
491
+ // 赋值给变量
492
+ const icon = BookOpen;
493
+
494
+ // 对象 value
495
+ const ITEMS = [{ icon: BookOpen }, { icon: Star }];
496
+
497
+ // 计算属性 key
498
+ const map = { [BookOpen]: 'read' };
499
+
500
+ // 数组、三元、函数参数
501
+ const list = [BookOpen, Star];
502
+ const active = flag ? BookOpen : Star;
503
+ renderIcon(Crown);
504
+
505
+ // 导入别名
506
+ import { BookOpen as ReadIcon } from "lucide-react-native";
507
+ <ReadIcon />
508
+
509
+ // re-export
510
+ export { Star, BookOpen as ReadIcon } from "lucide-react-native";
511
+ ```
512
+
513
+ ### 版本兼容性
514
+
515
+ 插件在运行时探测 `lucide-react-native` 的实际目录结构,自动适配新旧版本的路径差异(`>= 1.9` 新增 `icons/` 子目录;旧版 `1.8.x` 图标直接位于 `dist/cjs/`),lucide 升级时无需修改配置。
@@ -14679,8 +14679,10 @@ function resolveModule(useES, name) {
14679
14679
  `lucide icon ${name} was not a known icon. Please check the icon name is correct.`
14680
14680
  );
14681
14681
  }
14682
- function isSpecialTypes(t, node) {
14683
- return t.isMemberExpression(node) || t.isProperty(node);
14682
+ function isSpecialTypes(t, node, currentNode) {
14683
+ if (t.isMemberExpression(node)) return true;
14684
+ if (t.isProperty(node) && !node.computed && node.key === currentNode) return true;
14685
+ return false;
14684
14686
  }
14685
14687
  function lucideReactNativePlugin({ types: t }) {
14686
14688
  let selectedIcons = /* @__PURE__ */ Object.create(null);
@@ -14701,7 +14703,7 @@ function lucideReactNativePlugin({ types: t }) {
14701
14703
  function replaceIconRef(nodePath, useES, makeNode) {
14702
14704
  const localName = nodePath.node.name;
14703
14705
  const iconImportedName = specifiedLocal4Imported[localName];
14704
- if (!iconImportedName || !matchesLucideIcon(nodePath, localName) || isSpecialTypes(t, nodePath.parent)) return;
14706
+ if (!iconImportedName || !matchesLucideIcon(nodePath, localName) || isSpecialTypes(t, nodePath.parent, nodePath.node)) return;
14705
14707
  const newNode = importMethod(useES, iconImportedName, nodePath, localName);
14706
14708
  nodePath.replaceWith(makeNode(newNode.name, nodePath.node));
14707
14709
  }
package/dist/metro.js CHANGED
@@ -284,6 +284,7 @@ function withCssInterop(config) {
284
284
  }
285
285
 
286
286
  // src/metro/withDevkit.ts
287
+ var import_fs3 = __toESM(require("fs"));
287
288
  var import_path7 = __toESM(require("path"));
288
289
 
289
290
  // src/metro/withEsbuildMinify.ts
@@ -300,11 +301,34 @@ function withEsbuildMinify(config) {
300
301
  }
301
302
 
302
303
  // src/metro/withDevkit.ts
304
+ var LUCIDE_PKG = "lucide-react-native";
305
+ var LUCIDE_DIST_PREFIX = `${LUCIDE_PKG}/dist/`;
306
+ var lucidePkgRoot = null;
307
+ function getLucidePkgRoot() {
308
+ if (lucidePkgRoot) return lucidePkgRoot;
309
+ let dir = import_path7.default.dirname(require.resolve(LUCIDE_PKG));
310
+ while (true) {
311
+ const pkgJson = import_path7.default.join(dir, "package.json");
312
+ if (import_fs3.default.existsSync(pkgJson)) {
313
+ const { name } = require(pkgJson);
314
+ if (name === LUCIDE_PKG) {
315
+ lucidePkgRoot = dir;
316
+ return dir;
317
+ }
318
+ }
319
+ const parent = import_path7.default.dirname(dir);
320
+ if (parent === dir) throw new Error(`[withLucideResolver] Cannot locate package root for "${LUCIDE_PKG}"`);
321
+ dir = parent;
322
+ }
323
+ }
303
324
  function withLucideResolver(config) {
304
325
  const upstream = config.resolver?.resolveRequest ?? null;
305
326
  const resolveRequest = (context, moduleName, platform) => {
306
- if (moduleName.startsWith("lucide-react-native/dist/")) {
307
- return { filePath: require.resolve(moduleName), type: "sourceFile" };
327
+ if (moduleName.startsWith(LUCIDE_DIST_PREFIX)) {
328
+ const subpath = moduleName.slice(LUCIDE_PKG.length + 1);
329
+ const ext = subpath.startsWith("dist/esm/") ? ".mjs" : ".js";
330
+ const filePath = import_path7.default.join(getLucidePkgRoot(), subpath + ext);
331
+ return { filePath, type: "sourceFile" };
308
332
  }
309
333
  if (upstream) return upstream(context, moduleName, platform);
310
334
  return context.resolveRequest(context, moduleName, platform);
package/dist/metro.mjs CHANGED
@@ -246,6 +246,7 @@ function withCssInterop(config) {
246
246
  }
247
247
 
248
248
  // src/metro/withDevkit.ts
249
+ import fs3 from "fs";
249
250
  import path7 from "path";
250
251
 
251
252
  // src/metro/withEsbuildMinify.ts
@@ -262,11 +263,34 @@ function withEsbuildMinify(config) {
262
263
  }
263
264
 
264
265
  // src/metro/withDevkit.ts
266
+ var LUCIDE_PKG = "lucide-react-native";
267
+ var LUCIDE_DIST_PREFIX = `${LUCIDE_PKG}/dist/`;
268
+ var lucidePkgRoot = null;
269
+ function getLucidePkgRoot() {
270
+ if (lucidePkgRoot) return lucidePkgRoot;
271
+ let dir = path7.dirname(__require.resolve(LUCIDE_PKG));
272
+ while (true) {
273
+ const pkgJson = path7.join(dir, "package.json");
274
+ if (fs3.existsSync(pkgJson)) {
275
+ const { name } = __require(pkgJson);
276
+ if (name === LUCIDE_PKG) {
277
+ lucidePkgRoot = dir;
278
+ return dir;
279
+ }
280
+ }
281
+ const parent = path7.dirname(dir);
282
+ if (parent === dir) throw new Error(`[withLucideResolver] Cannot locate package root for "${LUCIDE_PKG}"`);
283
+ dir = parent;
284
+ }
285
+ }
265
286
  function withLucideResolver(config) {
266
287
  const upstream = config.resolver?.resolveRequest ?? null;
267
288
  const resolveRequest = (context, moduleName, platform) => {
268
- if (moduleName.startsWith("lucide-react-native/dist/")) {
269
- return { filePath: __require.resolve(moduleName), type: "sourceFile" };
289
+ if (moduleName.startsWith(LUCIDE_DIST_PREFIX)) {
290
+ const subpath = moduleName.slice(LUCIDE_PKG.length + 1);
291
+ const ext = subpath.startsWith("dist/esm/") ? ".mjs" : ".js";
292
+ const filePath = path7.join(getLucidePkgRoot(), subpath + ext);
293
+ return { filePath, type: "sourceFile" };
270
294
  }
271
295
  if (upstream) return upstream(context, moduleName, platform);
272
296
  return context.resolveRequest(context, moduleName, platform);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "miaoda-expo-devkit",
3
- "version": "0.1.1-beta.23",
3
+ "version": "0.1.1-beta.25",
4
4
  "description": "Expo 应用开发工具集:Sentry DSN 替换 stub、错误/网络捕获、Metro 符号化",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",