miaoda-expo-devkit 0.1.1-beta.17 → 0.1.1-beta.18
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/cli/lint.js +2 -0
- package/dist/metro.d.mts +7 -7
- package/dist/metro.d.ts +7 -7
- package/dist/metro.js +15 -10
- package/dist/metro.mjs +15 -10
- package/dist/rules/no-duplicate-expo-router-url.js +1 -1
- package/dist/stubs/expo-notifications-stub.js +9 -3
- package/package.json +9 -3
- package/tsconfig-base.json +7 -0
package/dist/cli/lint.js
CHANGED
|
@@ -18,4 +18,6 @@ var biome = (0, import_node_child_process.spawnSync)("biome", ["lint", "--config
|
|
|
18
18
|
stdio: "inherit"
|
|
19
19
|
});
|
|
20
20
|
if ((biome.status ?? 1) !== 0) failed = true;
|
|
21
|
+
var tsc = (0, import_node_child_process.spawnSync)("tsc", ["--noEmit"], { stdio: "inherit" });
|
|
22
|
+
if ((tsc.status ?? 1) !== 0) failed = true;
|
|
21
23
|
process.exit(failed ? 1 : 0);
|
package/dist/metro.d.mts
CHANGED
|
@@ -132,12 +132,13 @@ declare function withRouteEndpoint(config: MetroConfig, options: RouteEndpointOp
|
|
|
132
132
|
* 将模板 metro.config.js 所需的所有 devkit wrapper 封装为单个函数调用,
|
|
133
133
|
* 消除模板侧的 boilerplate。内部按固定顺序依次应用:
|
|
134
134
|
*
|
|
135
|
-
* withWorkspaceNodeModules
|
|
136
|
-
* withCssInterop
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
135
|
+
* withWorkspaceNodeModules — 修复沙箱中 node_modules 不在 projectRoot 内的问题
|
|
136
|
+
* withCssInterop — 为 expo-image / expo-camera 注入 NativeWind cssInterop
|
|
137
|
+
* withExpoNotificationsStub — Android:expo-notifications → stub(Expo Go no-op,Dev Build 透传)
|
|
138
|
+
* withEntryInjection — 在 expo-router 启动前注入脚本(仅 __DEV__)
|
|
139
|
+
* withDevStubs — 替换 Sentry DSN / 屏蔽 LogBox(仅 __DEV__)
|
|
140
|
+
* withRouteEndpoint — 添加 /__routes 端点(仅 __DEV__)
|
|
141
|
+
* withNativeWind — NativeWind 支持(含缓存路径修复)
|
|
141
142
|
*
|
|
142
143
|
* 用法(metro.config.js):
|
|
143
144
|
* const { getDefaultConfig } = require('expo/metro-config');
|
|
@@ -169,7 +170,6 @@ declare function withDevkit(config: MetroConfig, options?: DevkitOptions): Metro
|
|
|
169
170
|
* 注入行为:
|
|
170
171
|
* 1. web 平台:@expo/log-box 及 ErrorOverlayWebControls → no-op-logbox stub(屏蔽全屏错误遮罩)
|
|
171
172
|
* 2. 所有平台:@sentry/react-native → sentry-react-native-stub(替换 DSN,注入内置捕获器)
|
|
172
|
-
* 3. Android 平台:expo-notifications → expo-notifications-stub(Expo Go 时 no-op + Alert,Development Build 时透传)
|
|
173
173
|
*
|
|
174
174
|
* 自动保留并调用已有的 resolveRequest,支持与其他 Metro 配置链式组合。
|
|
175
175
|
*
|
package/dist/metro.d.ts
CHANGED
|
@@ -132,12 +132,13 @@ declare function withRouteEndpoint(config: MetroConfig, options: RouteEndpointOp
|
|
|
132
132
|
* 将模板 metro.config.js 所需的所有 devkit wrapper 封装为单个函数调用,
|
|
133
133
|
* 消除模板侧的 boilerplate。内部按固定顺序依次应用:
|
|
134
134
|
*
|
|
135
|
-
* withWorkspaceNodeModules
|
|
136
|
-
* withCssInterop
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
135
|
+
* withWorkspaceNodeModules — 修复沙箱中 node_modules 不在 projectRoot 内的问题
|
|
136
|
+
* withCssInterop — 为 expo-image / expo-camera 注入 NativeWind cssInterop
|
|
137
|
+
* withExpoNotificationsStub — Android:expo-notifications → stub(Expo Go no-op,Dev Build 透传)
|
|
138
|
+
* withEntryInjection — 在 expo-router 启动前注入脚本(仅 __DEV__)
|
|
139
|
+
* withDevStubs — 替换 Sentry DSN / 屏蔽 LogBox(仅 __DEV__)
|
|
140
|
+
* withRouteEndpoint — 添加 /__routes 端点(仅 __DEV__)
|
|
141
|
+
* withNativeWind — NativeWind 支持(含缓存路径修复)
|
|
141
142
|
*
|
|
142
143
|
* 用法(metro.config.js):
|
|
143
144
|
* const { getDefaultConfig } = require('expo/metro-config');
|
|
@@ -169,7 +170,6 @@ declare function withDevkit(config: MetroConfig, options?: DevkitOptions): Metro
|
|
|
169
170
|
* 注入行为:
|
|
170
171
|
* 1. web 平台:@expo/log-box 及 ErrorOverlayWebControls → no-op-logbox stub(屏蔽全屏错误遮罩)
|
|
171
172
|
* 2. 所有平台:@sentry/react-native → sentry-react-native-stub(替换 DSN,注入内置捕获器)
|
|
172
|
-
* 3. Android 平台:expo-notifications → expo-notifications-stub(Expo Go 时 no-op + Alert,Development Build 时透传)
|
|
173
173
|
*
|
|
174
174
|
* 自动保留并调用已有的 resolveRequest,支持与其他 Metro 配置链式组合。
|
|
175
175
|
*
|
package/dist/metro.js
CHANGED
|
@@ -80,14 +80,8 @@ function withNativeWind(config, options) {
|
|
|
80
80
|
// src/metro/withDevStubs.ts
|
|
81
81
|
var import_path2 = __toESM(require("path"));
|
|
82
82
|
var SENTRY_STUB_FILENAME = "sentry-react-native-stub.js";
|
|
83
|
-
var EXPO_NOTIFICATIONS_STUB_FILENAME = "expo-notifications-stub.js";
|
|
84
83
|
var SENTRY_STUB_PATH = import_path2.default.resolve(__dirname, "stubs", SENTRY_STUB_FILENAME);
|
|
85
84
|
var NO_OP_LOGBOX_STUB_PATH = import_path2.default.resolve(__dirname, "stubs", "no-op-logbox.js");
|
|
86
|
-
var EXPO_NOTIFICATIONS_STUB_PATH = import_path2.default.resolve(
|
|
87
|
-
__dirname,
|
|
88
|
-
"stubs",
|
|
89
|
-
EXPO_NOTIFICATIONS_STUB_FILENAME
|
|
90
|
-
);
|
|
91
85
|
function withDevStubs(config) {
|
|
92
86
|
const upstream = config.resolver?.resolveRequest ?? null;
|
|
93
87
|
const resolveRequest = (context, moduleName, platform) => {
|
|
@@ -99,9 +93,6 @@ function withDevStubs(config) {
|
|
|
99
93
|
if (moduleName === "@sentry/react-native" && !context.originModulePath.includes(SENTRY_STUB_FILENAME)) {
|
|
100
94
|
return { filePath: SENTRY_STUB_PATH, type: "sourceFile" };
|
|
101
95
|
}
|
|
102
|
-
if (platform === "android" && moduleName === "expo-notifications" && !context.originModulePath.includes(EXPO_NOTIFICATIONS_STUB_FILENAME)) {
|
|
103
|
-
return { filePath: EXPO_NOTIFICATIONS_STUB_PATH, type: "sourceFile" };
|
|
104
|
-
}
|
|
105
96
|
if (upstream) {
|
|
106
97
|
return upstream(context, moduleName, platform);
|
|
107
98
|
}
|
|
@@ -308,13 +299,27 @@ function withEsbuildMinify(config) {
|
|
|
308
299
|
}
|
|
309
300
|
|
|
310
301
|
// src/metro/withDevkit.ts
|
|
302
|
+
var EXPO_NOTIFICATIONS_STUB_FILENAME = "expo-notifications-stub.js";
|
|
303
|
+
var EXPO_NOTIFICATIONS_STUB_PATH = import_path7.default.resolve(__dirname, "stubs", EXPO_NOTIFICATIONS_STUB_FILENAME);
|
|
304
|
+
function withExpoNotificationsStub(config) {
|
|
305
|
+
const upstream = config.resolver?.resolveRequest ?? null;
|
|
306
|
+
const resolveRequest = (context, moduleName, platform) => {
|
|
307
|
+
if (platform === "android" && moduleName === "expo-notifications" && !context.originModulePath.includes(EXPO_NOTIFICATIONS_STUB_FILENAME)) {
|
|
308
|
+
return { filePath: EXPO_NOTIFICATIONS_STUB_PATH, type: "sourceFile" };
|
|
309
|
+
}
|
|
310
|
+
if (upstream) return upstream(context, moduleName, platform);
|
|
311
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
312
|
+
};
|
|
313
|
+
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
314
|
+
}
|
|
311
315
|
function withDevkit(config, options = {}) {
|
|
312
316
|
const projectRoot = config.projectRoot ?? process.cwd();
|
|
313
317
|
const { input = "./src/global.css" } = options;
|
|
314
318
|
config = withWorkspaceNodeModules(config);
|
|
315
319
|
config = withCssInterop(config);
|
|
316
320
|
config = withEsbuildMinify(config);
|
|
317
|
-
|
|
321
|
+
config = withExpoNotificationsStub(config);
|
|
322
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
318
323
|
config = withEntryInjection(config);
|
|
319
324
|
config = withDevStubs(config);
|
|
320
325
|
config = withRouteEndpoint(config, { appDir: import_path7.default.join(projectRoot, "src", "app") });
|
package/dist/metro.mjs
CHANGED
|
@@ -43,14 +43,8 @@ function withNativeWind(config, options) {
|
|
|
43
43
|
// src/metro/withDevStubs.ts
|
|
44
44
|
import path2 from "path";
|
|
45
45
|
var SENTRY_STUB_FILENAME = "sentry-react-native-stub.js";
|
|
46
|
-
var EXPO_NOTIFICATIONS_STUB_FILENAME = "expo-notifications-stub.js";
|
|
47
46
|
var SENTRY_STUB_PATH = path2.resolve(__dirname, "stubs", SENTRY_STUB_FILENAME);
|
|
48
47
|
var NO_OP_LOGBOX_STUB_PATH = path2.resolve(__dirname, "stubs", "no-op-logbox.js");
|
|
49
|
-
var EXPO_NOTIFICATIONS_STUB_PATH = path2.resolve(
|
|
50
|
-
__dirname,
|
|
51
|
-
"stubs",
|
|
52
|
-
EXPO_NOTIFICATIONS_STUB_FILENAME
|
|
53
|
-
);
|
|
54
48
|
function withDevStubs(config) {
|
|
55
49
|
const upstream = config.resolver?.resolveRequest ?? null;
|
|
56
50
|
const resolveRequest = (context, moduleName, platform) => {
|
|
@@ -62,9 +56,6 @@ function withDevStubs(config) {
|
|
|
62
56
|
if (moduleName === "@sentry/react-native" && !context.originModulePath.includes(SENTRY_STUB_FILENAME)) {
|
|
63
57
|
return { filePath: SENTRY_STUB_PATH, type: "sourceFile" };
|
|
64
58
|
}
|
|
65
|
-
if (platform === "android" && moduleName === "expo-notifications" && !context.originModulePath.includes(EXPO_NOTIFICATIONS_STUB_FILENAME)) {
|
|
66
|
-
return { filePath: EXPO_NOTIFICATIONS_STUB_PATH, type: "sourceFile" };
|
|
67
|
-
}
|
|
68
59
|
if (upstream) {
|
|
69
60
|
return upstream(context, moduleName, platform);
|
|
70
61
|
}
|
|
@@ -271,13 +262,27 @@ function withEsbuildMinify(config) {
|
|
|
271
262
|
}
|
|
272
263
|
|
|
273
264
|
// src/metro/withDevkit.ts
|
|
265
|
+
var EXPO_NOTIFICATIONS_STUB_FILENAME = "expo-notifications-stub.js";
|
|
266
|
+
var EXPO_NOTIFICATIONS_STUB_PATH = path7.resolve(__dirname, "stubs", EXPO_NOTIFICATIONS_STUB_FILENAME);
|
|
267
|
+
function withExpoNotificationsStub(config) {
|
|
268
|
+
const upstream = config.resolver?.resolveRequest ?? null;
|
|
269
|
+
const resolveRequest = (context, moduleName, platform) => {
|
|
270
|
+
if (platform === "android" && moduleName === "expo-notifications" && !context.originModulePath.includes(EXPO_NOTIFICATIONS_STUB_FILENAME)) {
|
|
271
|
+
return { filePath: EXPO_NOTIFICATIONS_STUB_PATH, type: "sourceFile" };
|
|
272
|
+
}
|
|
273
|
+
if (upstream) return upstream(context, moduleName, platform);
|
|
274
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
275
|
+
};
|
|
276
|
+
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
277
|
+
}
|
|
274
278
|
function withDevkit(config, options = {}) {
|
|
275
279
|
const projectRoot = config.projectRoot ?? process.cwd();
|
|
276
280
|
const { input = "./src/global.css" } = options;
|
|
277
281
|
config = withWorkspaceNodeModules(config);
|
|
278
282
|
config = withCssInterop(config);
|
|
279
283
|
config = withEsbuildMinify(config);
|
|
280
|
-
|
|
284
|
+
config = withExpoNotificationsStub(config);
|
|
285
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
281
286
|
config = withEntryInjection(config);
|
|
282
287
|
config = withDevStubs(config);
|
|
283
288
|
config = withRouteEndpoint(config, { appDir: path7.join(projectRoot, "src", "app") });
|
|
@@ -103,7 +103,7 @@ var noDuplicateExpoRouterUrlRule = {
|
|
|
103
103
|
},
|
|
104
104
|
create(context) {
|
|
105
105
|
return {
|
|
106
|
-
Program(
|
|
106
|
+
Program() {
|
|
107
107
|
const projectRoot = findProjectRoot(context.filename);
|
|
108
108
|
if (!projectRoot) return;
|
|
109
109
|
const routerRoot = getRouterRoot(projectRoot);
|
|
@@ -9,19 +9,24 @@ if (!(0, import_expo.isRunningInExpoGo)()) {
|
|
|
9
9
|
if (_alertShown) return;
|
|
10
10
|
_alertShown = true;
|
|
11
11
|
import_react_native.Alert.alert(
|
|
12
|
-
"\u901A\u77E5
|
|
13
|
-
"
|
|
12
|
+
"\u79D2\u54D2\u901A\u77E5",
|
|
13
|
+
"\u53D7Android\u5E73\u53F0\u9650\u5236, \u626B\u7801\u4F53\u9A8C\u4E0D\u652F\u6301\u672C\u5730\u901A\u77E5\u3002\n\n \u6682\u65F6\u65E0\u6CD5\u5B8C\u6574\u9A8C\u8BC1\u6B64\u529F\u80FD",
|
|
14
14
|
[{ text: "\u77E5\u9053\u4E86" }]
|
|
15
15
|
);
|
|
16
16
|
};
|
|
17
|
-
const
|
|
17
|
+
const DENIED_PERMISSION = { status: "denied", granted: false, canAskAgain: false, expires: "never" };
|
|
18
|
+
const noopPermission = async () => {
|
|
18
19
|
showAlert();
|
|
20
|
+
return DENIED_PERMISSION;
|
|
19
21
|
};
|
|
20
22
|
const noopListener = () => {
|
|
21
23
|
showAlert();
|
|
22
24
|
return { remove: () => {
|
|
23
25
|
} };
|
|
24
26
|
};
|
|
27
|
+
const noop = async () => {
|
|
28
|
+
showAlert();
|
|
29
|
+
};
|
|
25
30
|
const enums = {
|
|
26
31
|
AndroidNotificationPriority: {
|
|
27
32
|
MIN: "min",
|
|
@@ -43,6 +48,7 @@ if (!(0, import_expo.isRunningInExpoGo)()) {
|
|
|
43
48
|
module.exports = new Proxy(enums, {
|
|
44
49
|
get(target, key) {
|
|
45
50
|
if (key in target) return target[key];
|
|
51
|
+
if (key.endsWith("PermissionsAsync")) return noopPermission;
|
|
46
52
|
if (key.endsWith("Listener")) return noopListener;
|
|
47
53
|
return noop;
|
|
48
54
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "miaoda-expo-devkit",
|
|
3
|
-
"version": "0.1.1-beta.
|
|
3
|
+
"version": "0.1.1-beta.18",
|
|
4
4
|
"description": "Expo 应用开发工具集:Sentry DSN 替换 stub、错误/网络捕获、Metro 符号化",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -48,13 +48,15 @@
|
|
|
48
48
|
"./rules/no-duplicate-expo-router-url": "./dist/rules/no-duplicate-expo-router-url.js",
|
|
49
49
|
"./rules/no-missing-css-import": "./dist/rules/no-missing-css-import.js",
|
|
50
50
|
"./biome": "./biome-config.json",
|
|
51
|
-
"./oxlint": "./oxlint-config.json"
|
|
51
|
+
"./oxlint": "./oxlint-config.json",
|
|
52
|
+
"./tsconfig-base": "./tsconfig-base.json"
|
|
52
53
|
},
|
|
53
54
|
"files": [
|
|
54
55
|
"dist",
|
|
55
56
|
"biome-config.json",
|
|
56
57
|
"oxlint-config.json",
|
|
57
58
|
"pnpm-config.json",
|
|
59
|
+
"tsconfig-base.json",
|
|
58
60
|
"!dist/**/*.map"
|
|
59
61
|
],
|
|
60
62
|
"scripts": {
|
|
@@ -83,7 +85,8 @@
|
|
|
83
85
|
"metro-resolver": ">=0.80.0",
|
|
84
86
|
"nativewind": ">=4.0.0",
|
|
85
87
|
"react-native": ">=0.79.0",
|
|
86
|
-
"react-native-css-interop": ">=0.2.0"
|
|
88
|
+
"react-native-css-interop": ">=0.2.0",
|
|
89
|
+
"typescript": ">=5.0.0"
|
|
87
90
|
},
|
|
88
91
|
"peerDependenciesMeta": {
|
|
89
92
|
"@sentry/core": {
|
|
@@ -106,6 +109,9 @@
|
|
|
106
109
|
},
|
|
107
110
|
"react-native-css-interop": {
|
|
108
111
|
"optional": true
|
|
112
|
+
},
|
|
113
|
+
"typescript": {
|
|
114
|
+
"optional": true
|
|
109
115
|
}
|
|
110
116
|
},
|
|
111
117
|
"publishConfig": {
|