miaoda-expo-devkit 0.1.1-beta.39 → 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/dist/metro.d.mts +19 -1
- package/dist/metro.d.ts +19 -1
- package/dist/metro.js +25 -2
- package/dist/metro.mjs +24 -2
- package/dist/rules/no-duplicate-expo-router-url.js +16 -14
- package/dist/rules/no-expo-video-compat.js +2041 -0
- package/dist/rules/no-invalid-tabs-screen.js +16 -14
- package/dist/rules/no-missing-css-import.js +13 -11
- package/dist/rules/no-undeclared-expo-plugin.js +12 -11
- package/dist/rules/no-unregistered-dynamic-tab-route.js +19 -17
- package/dist/rules/no-unused-expo-plugin.js +13 -12
- package/dist/stubs/expo-file-system-stub.js +214 -0
- package/dist/stubs/expo-media-library-stub.js +21 -22
- package/oxlint-config.json +3 -1
- package/package.json +4 -1
package/dist/metro.d.mts
CHANGED
|
@@ -119,6 +119,7 @@ declare function withRouteEndpoint(config: MetroConfig, options: RouteEndpointOp
|
|
|
119
119
|
* withExpoNotificationsStub — Android:expo-notifications → stub(Expo Go no-op,Dev Build 透传)
|
|
120
120
|
* withExpoMediaLibraryStub — Web / Expo Go:expo-media-library → stub(弹 Alert 提示,Dev Build 透传)
|
|
121
121
|
* withExpoCalendarStub — Web / Expo Go:expo-calendar → stub(弹 Alert 提示,Dev Build 透传)
|
|
122
|
+
* withExpoFileSystemStub — Web:expo-file-system/legacy → stub(弹 Dialog 提示,原生透传)
|
|
122
123
|
* withEntryInjection — 在 expo-router 启动前注入脚本(仅 __DEV__)
|
|
123
124
|
* withDevStubs — 替换 Sentry DSN / 屏蔽 LogBox(仅 __DEV__)
|
|
124
125
|
* withRouteEndpoint — 添加 /__routes 端点(仅 __DEV__)
|
|
@@ -295,6 +296,23 @@ declare function withExpoMediaLibraryStub(config: MetroConfig): MetroConfig;
|
|
|
295
296
|
*/
|
|
296
297
|
declare function withExpoCalendarStub(config: MetroConfig): MetroConfig;
|
|
297
298
|
|
|
299
|
+
/**
|
|
300
|
+
* withExpoFileSystemStub — Web 端将 expo-file-system/legacy 替换为 stub
|
|
301
|
+
*
|
|
302
|
+
* expo-file-system 的文件 API 在 Web 端不可用(底层 shim 方法均缺失)。
|
|
303
|
+
* stub 在运行时通过 Platform.OS 判断:
|
|
304
|
+
* - Web:no-op(核心 API 弹 Dialog 提示,不崩溃)
|
|
305
|
+
* - Expo Go / Development Build(原生):透传真实 expo-file-system/legacy,功能完全正常
|
|
306
|
+
*
|
|
307
|
+
* 注意:此 wrapper 拦截 expo-file-system/legacy 子路径,不拦截新版 expo-file-system(File API)。
|
|
308
|
+
*/
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* @param config Metro config 对象
|
|
312
|
+
* @returns 注入 resolveRequest 后的新 Metro config
|
|
313
|
+
*/
|
|
314
|
+
declare function withExpoFileSystemStub(config: MetroConfig): MetroConfig;
|
|
315
|
+
|
|
298
316
|
/**
|
|
299
317
|
* 将 Metro transformer 的 minifier 切换为 esbuild。
|
|
300
318
|
*
|
|
@@ -320,4 +338,4 @@ declare function withEsbuildMinify(config: MetroConfig): MetroConfig;
|
|
|
320
338
|
|
|
321
339
|
declare function withWasmSupport(config: MetroConfig): MetroConfig;
|
|
322
340
|
|
|
323
|
-
export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
|
|
341
|
+
export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoFileSystemStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
|
package/dist/metro.d.ts
CHANGED
|
@@ -119,6 +119,7 @@ declare function withRouteEndpoint(config: MetroConfig, options: RouteEndpointOp
|
|
|
119
119
|
* withExpoNotificationsStub — Android:expo-notifications → stub(Expo Go no-op,Dev Build 透传)
|
|
120
120
|
* withExpoMediaLibraryStub — Web / Expo Go:expo-media-library → stub(弹 Alert 提示,Dev Build 透传)
|
|
121
121
|
* withExpoCalendarStub — Web / Expo Go:expo-calendar → stub(弹 Alert 提示,Dev Build 透传)
|
|
122
|
+
* withExpoFileSystemStub — Web:expo-file-system/legacy → stub(弹 Dialog 提示,原生透传)
|
|
122
123
|
* withEntryInjection — 在 expo-router 启动前注入脚本(仅 __DEV__)
|
|
123
124
|
* withDevStubs — 替换 Sentry DSN / 屏蔽 LogBox(仅 __DEV__)
|
|
124
125
|
* withRouteEndpoint — 添加 /__routes 端点(仅 __DEV__)
|
|
@@ -295,6 +296,23 @@ declare function withExpoMediaLibraryStub(config: MetroConfig): MetroConfig;
|
|
|
295
296
|
*/
|
|
296
297
|
declare function withExpoCalendarStub(config: MetroConfig): MetroConfig;
|
|
297
298
|
|
|
299
|
+
/**
|
|
300
|
+
* withExpoFileSystemStub — Web 端将 expo-file-system/legacy 替换为 stub
|
|
301
|
+
*
|
|
302
|
+
* expo-file-system 的文件 API 在 Web 端不可用(底层 shim 方法均缺失)。
|
|
303
|
+
* stub 在运行时通过 Platform.OS 判断:
|
|
304
|
+
* - Web:no-op(核心 API 弹 Dialog 提示,不崩溃)
|
|
305
|
+
* - Expo Go / Development Build(原生):透传真实 expo-file-system/legacy,功能完全正常
|
|
306
|
+
*
|
|
307
|
+
* 注意:此 wrapper 拦截 expo-file-system/legacy 子路径,不拦截新版 expo-file-system(File API)。
|
|
308
|
+
*/
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* @param config Metro config 对象
|
|
312
|
+
* @returns 注入 resolveRequest 后的新 Metro config
|
|
313
|
+
*/
|
|
314
|
+
declare function withExpoFileSystemStub(config: MetroConfig): MetroConfig;
|
|
315
|
+
|
|
298
316
|
/**
|
|
299
317
|
* 将 Metro transformer 的 minifier 切换为 esbuild。
|
|
300
318
|
*
|
|
@@ -320,4 +338,4 @@ declare function withEsbuildMinify(config: MetroConfig): MetroConfig;
|
|
|
320
338
|
|
|
321
339
|
declare function withWasmSupport(config: MetroConfig): MetroConfig;
|
|
322
340
|
|
|
323
|
-
export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
|
|
341
|
+
export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoFileSystemStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
|
package/dist/metro.js
CHANGED
|
@@ -37,6 +37,7 @@ __export(metro_exports, {
|
|
|
37
37
|
withEntryInjection: () => withEntryInjection,
|
|
38
38
|
withEsbuildMinify: () => withEsbuildMinify,
|
|
39
39
|
withExpoCalendarStub: () => withExpoCalendarStub,
|
|
40
|
+
withExpoFileSystemStub: () => withExpoFileSystemStub,
|
|
40
41
|
withExpoMediaLibraryStub: () => withExpoMediaLibraryStub,
|
|
41
42
|
withExpoNotificationsStub: () => withExpoNotificationsStub,
|
|
42
43
|
withLucideResolver: () => withLucideResolver,
|
|
@@ -286,7 +287,7 @@ function withCssInterop(config) {
|
|
|
286
287
|
}
|
|
287
288
|
|
|
288
289
|
// src/metro/withDevkit.ts
|
|
289
|
-
var
|
|
290
|
+
var import_path12 = __toESM(require("path"));
|
|
290
291
|
|
|
291
292
|
// src/metro/withEsbuildMinify.ts
|
|
292
293
|
function withEsbuildMinify(config) {
|
|
@@ -405,6 +406,26 @@ function withExpoCalendarStub(config) {
|
|
|
405
406
|
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
406
407
|
}
|
|
407
408
|
|
|
409
|
+
// src/metro/withExpoFileSystemStub.ts
|
|
410
|
+
var import_path11 = __toESM(require("path"));
|
|
411
|
+
var EXPO_FILE_SYSTEM_STUB_FILENAME = "expo-file-system-stub.js";
|
|
412
|
+
var EXPO_FILE_SYSTEM_STUB_PATH = import_path11.default.resolve(
|
|
413
|
+
__dirname,
|
|
414
|
+
"stubs",
|
|
415
|
+
EXPO_FILE_SYSTEM_STUB_FILENAME
|
|
416
|
+
);
|
|
417
|
+
function withExpoFileSystemStub(config) {
|
|
418
|
+
const upstream = config.resolver?.resolveRequest ?? null;
|
|
419
|
+
const resolveRequest = (context, moduleName, platform) => {
|
|
420
|
+
if (moduleName === "expo-file-system/legacy" && !context.originModulePath.includes(EXPO_FILE_SYSTEM_STUB_FILENAME)) {
|
|
421
|
+
return { filePath: EXPO_FILE_SYSTEM_STUB_PATH, type: "sourceFile" };
|
|
422
|
+
}
|
|
423
|
+
if (upstream) return upstream(context, moduleName, platform);
|
|
424
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
425
|
+
};
|
|
426
|
+
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
427
|
+
}
|
|
428
|
+
|
|
408
429
|
// src/metro/withWasmSupport.ts
|
|
409
430
|
function withWasmSupport(config) {
|
|
410
431
|
const existing = config.resolver?.assetExts ?? [];
|
|
@@ -430,10 +451,11 @@ function withDevkit(config, options = {}) {
|
|
|
430
451
|
config = withExpoNotificationsStub(config);
|
|
431
452
|
config = withExpoMediaLibraryStub(config);
|
|
432
453
|
config = withExpoCalendarStub(config);
|
|
454
|
+
config = withExpoFileSystemStub(config);
|
|
433
455
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
434
456
|
config = withEntryInjection(config);
|
|
435
457
|
config = withDevStubs(config);
|
|
436
|
-
config = withRouteEndpoint(config, { appDir:
|
|
458
|
+
config = withRouteEndpoint(config, { appDir: import_path12.default.join(projectRoot, "src", "app") });
|
|
437
459
|
}
|
|
438
460
|
return withNativeWind(config, { input, inlineRem: 16 });
|
|
439
461
|
}
|
|
@@ -454,6 +476,7 @@ try {
|
|
|
454
476
|
withEntryInjection,
|
|
455
477
|
withEsbuildMinify,
|
|
456
478
|
withExpoCalendarStub,
|
|
479
|
+
withExpoFileSystemStub,
|
|
457
480
|
withExpoMediaLibraryStub,
|
|
458
481
|
withExpoNotificationsStub,
|
|
459
482
|
withLucideResolver,
|
package/dist/metro.mjs
CHANGED
|
@@ -244,7 +244,7 @@ function withCssInterop(config) {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
// src/metro/withDevkit.ts
|
|
247
|
-
import
|
|
247
|
+
import path12 from "path";
|
|
248
248
|
|
|
249
249
|
// src/metro/withEsbuildMinify.ts
|
|
250
250
|
function withEsbuildMinify(config) {
|
|
@@ -363,6 +363,26 @@ function withExpoCalendarStub(config) {
|
|
|
363
363
|
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
+
// src/metro/withExpoFileSystemStub.ts
|
|
367
|
+
import path11 from "path";
|
|
368
|
+
var EXPO_FILE_SYSTEM_STUB_FILENAME = "expo-file-system-stub.js";
|
|
369
|
+
var EXPO_FILE_SYSTEM_STUB_PATH = path11.resolve(
|
|
370
|
+
__dirname,
|
|
371
|
+
"stubs",
|
|
372
|
+
EXPO_FILE_SYSTEM_STUB_FILENAME
|
|
373
|
+
);
|
|
374
|
+
function withExpoFileSystemStub(config) {
|
|
375
|
+
const upstream = config.resolver?.resolveRequest ?? null;
|
|
376
|
+
const resolveRequest = (context, moduleName, platform) => {
|
|
377
|
+
if (moduleName === "expo-file-system/legacy" && !context.originModulePath.includes(EXPO_FILE_SYSTEM_STUB_FILENAME)) {
|
|
378
|
+
return { filePath: EXPO_FILE_SYSTEM_STUB_PATH, type: "sourceFile" };
|
|
379
|
+
}
|
|
380
|
+
if (upstream) return upstream(context, moduleName, platform);
|
|
381
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
382
|
+
};
|
|
383
|
+
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
384
|
+
}
|
|
385
|
+
|
|
366
386
|
// src/metro/withWasmSupport.ts
|
|
367
387
|
function withWasmSupport(config) {
|
|
368
388
|
const existing = config.resolver?.assetExts ?? [];
|
|
@@ -388,10 +408,11 @@ function withDevkit(config, options = {}) {
|
|
|
388
408
|
config = withExpoNotificationsStub(config);
|
|
389
409
|
config = withExpoMediaLibraryStub(config);
|
|
390
410
|
config = withExpoCalendarStub(config);
|
|
411
|
+
config = withExpoFileSystemStub(config);
|
|
391
412
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
392
413
|
config = withEntryInjection(config);
|
|
393
414
|
config = withDevStubs(config);
|
|
394
|
-
config = withRouteEndpoint(config, { appDir:
|
|
415
|
+
config = withRouteEndpoint(config, { appDir: path12.join(projectRoot, "src", "app") });
|
|
395
416
|
}
|
|
396
417
|
return withNativeWind(config, { input, inlineRem: 16 });
|
|
397
418
|
}
|
|
@@ -411,6 +432,7 @@ export {
|
|
|
411
432
|
withEntryInjection,
|
|
412
433
|
withEsbuildMinify,
|
|
413
434
|
withExpoCalendarStub,
|
|
435
|
+
withExpoFileSystemStub,
|
|
414
436
|
withExpoMediaLibraryStub,
|
|
415
437
|
withExpoNotificationsStub,
|
|
416
438
|
withLucideResolver,
|
|
@@ -34,10 +34,20 @@ __export(no_duplicate_expo_router_url_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(no_duplicate_expo_router_url_exports);
|
|
36
36
|
var import_node_fs = __toESM(require("fs"));
|
|
37
|
+
var import_node_path2 = __toESM(require("path"));
|
|
38
|
+
|
|
39
|
+
// src/rules/utils.ts
|
|
37
40
|
var import_node_path = __toESM(require("path"));
|
|
41
|
+
var import_package_up = require("package-up");
|
|
42
|
+
function findProjectRoot(startPath) {
|
|
43
|
+
const pkgPath = (0, import_package_up.packageUpSync)({ cwd: import_node_path.default.dirname(startPath) });
|
|
44
|
+
return pkgPath ? import_node_path.default.dirname(pkgPath) : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/rules/no-duplicate-expo-router-url.ts
|
|
38
48
|
var ROUTE_EXTENSIONS = /* @__PURE__ */ new Set([".tsx", ".ts", ".jsx", ".js"]);
|
|
39
49
|
function fileToUrl(relPath) {
|
|
40
|
-
const ext =
|
|
50
|
+
const ext = import_node_path2.default.extname(relPath);
|
|
41
51
|
if (!ROUTE_EXTENSIONS.has(ext)) return null;
|
|
42
52
|
const normalized = relPath.replace(/\\/g, "/");
|
|
43
53
|
let p = normalized.slice(0, -ext.length);
|
|
@@ -50,17 +60,9 @@ function fileToUrl(relPath) {
|
|
|
50
60
|
if (p.endsWith("/index")) return "/" + p.slice(0, -6);
|
|
51
61
|
return "/" + p;
|
|
52
62
|
}
|
|
53
|
-
function findProjectRoot(startPath) {
|
|
54
|
-
let dir = import_node_path.default.dirname(startPath);
|
|
55
|
-
while (dir !== import_node_path.default.dirname(dir)) {
|
|
56
|
-
if (import_node_fs.default.existsSync(import_node_path.default.join(dir, "package.json"))) return dir;
|
|
57
|
-
dir = import_node_path.default.dirname(dir);
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
63
|
function getRouterRoot(projectRoot) {
|
|
62
64
|
try {
|
|
63
|
-
const raw = JSON.parse(import_node_fs.default.readFileSync(
|
|
65
|
+
const raw = JSON.parse(import_node_fs.default.readFileSync(import_node_path2.default.join(projectRoot, "app.json"), "utf-8"));
|
|
64
66
|
return raw?.expo?.router?.root ?? ".";
|
|
65
67
|
} catch {
|
|
66
68
|
return ".";
|
|
@@ -72,11 +74,11 @@ function buildUrlMap(appDir) {
|
|
|
72
74
|
const urlMap = /* @__PURE__ */ new Map();
|
|
73
75
|
function scanDir(dir) {
|
|
74
76
|
for (const entry of import_node_fs.default.readdirSync(dir, { withFileTypes: true })) {
|
|
75
|
-
const fullPath =
|
|
77
|
+
const fullPath = import_node_path2.default.join(dir, entry.name);
|
|
76
78
|
if (entry.isDirectory()) {
|
|
77
79
|
scanDir(fullPath);
|
|
78
80
|
} else if (entry.isFile()) {
|
|
79
|
-
const rel =
|
|
81
|
+
const rel = import_node_path2.default.relative(appDir, fullPath);
|
|
80
82
|
const url = fileToUrl(rel);
|
|
81
83
|
if (url !== null) {
|
|
82
84
|
const existing = urlMap.get(url) ?? [];
|
|
@@ -107,8 +109,8 @@ var noDuplicateExpoRouterUrlRule = {
|
|
|
107
109
|
const projectRoot = findProjectRoot(context.filename);
|
|
108
110
|
if (!projectRoot) return;
|
|
109
111
|
const routerRoot = getRouterRoot(projectRoot);
|
|
110
|
-
const appDir =
|
|
111
|
-
const rel =
|
|
112
|
+
const appDir = import_node_path2.default.join(projectRoot, routerRoot, "app");
|
|
113
|
+
const rel = import_node_path2.default.relative(appDir, context.filename).replace(/\\/g, "/");
|
|
112
114
|
if (rel.startsWith("..")) return;
|
|
113
115
|
const url = fileToUrl(rel);
|
|
114
116
|
if (url === null) return;
|