miaoda-expo-devkit 0.1.1-beta.2 → 0.1.1-beta.21

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.js CHANGED
@@ -27,66 +27,59 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
- // src/metro.ts
30
+ // src/metro/index.ts
31
31
  var metro_exports = {};
32
32
  __export(metro_exports, {
33
+ patchNativeWindCachePath: () => patchNativeWindCachePath,
34
+ withCssInterop: () => withCssInterop,
33
35
  withDevStubs: () => withDevStubs,
36
+ withDevkit: () => withDevkit,
34
37
  withEntryInjection: () => withEntryInjection,
38
+ withEsbuildMinify: () => withEsbuildMinify,
39
+ withExpoNotificationsStub: () => withExpoNotificationsStub,
40
+ withNativeWind: () => withNativeWind,
35
41
  withRouteEndpoint: () => withRouteEndpoint,
36
42
  withWorkspaceNodeModules: () => withWorkspaceNodeModules
37
43
  });
38
44
  module.exports = __toCommonJS(metro_exports);
39
- var import_connect = __toESM(require("connect"));
40
- var import_fs2 = __toESM(require("fs"));
41
- var import_path2 = __toESM(require("path"));
42
45
 
43
- // src/routes.ts
44
- var import_fs = __toESM(require("fs"));
46
+ // src/metro/withNativeWind.ts
45
47
  var import_path = __toESM(require("path"));
46
- var ROUTE_EXT = /\.(tsx|ts|jsx|js)$/;
47
- function getRoutes(appDir) {
48
- const routes = [];
49
- function scan(dir, prefix) {
50
- let entries;
51
- try {
52
- entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
53
- } catch {
54
- return;
55
- }
56
- for (const entry of entries) {
57
- const fullPath = import_path.default.join(dir, entry.name);
58
- if (entry.isDirectory()) {
59
- const isGroup = /^\(.*\)$/.test(entry.name);
60
- const nextPrefix = isGroup ? prefix : `${prefix}/${entry.name}`;
61
- scan(fullPath, nextPrefix);
62
- } else if (ROUTE_EXT.test(entry.name)) {
63
- const baseName = entry.name.replace(ROUTE_EXT, "");
64
- if (baseName === "_layout") continue;
65
- const segment = baseName === "index" ? "" : `/${baseName}`;
66
- const routePath = `${prefix}${segment}` || "/";
67
- const isDynamic = /\[.*\]/.test(baseName);
68
- routes.push({
69
- title: routePath,
70
- pageId: routePath,
71
- pageName: routePath,
72
- visible: !isDynamic,
73
- path: import_path.default.relative(appDir, fullPath)
74
- });
75
- }
48
+ function patchNativeWindCachePath(options = {}) {
49
+ const projectRoot = process.cwd();
50
+ const ourCacheDir = import_path.default.resolve(projectRoot, options.cacheDir ?? ".native-wind-cache");
51
+ const nativewindPkgDir = import_path.default.dirname(require.resolve("react-native-css-interop/package.json"));
52
+ const nativewindCacheDir = import_path.default.resolve(nativewindPkgDir, ".cache");
53
+ const moduleId = require.resolve("react-native-css-interop/dist/metro");
54
+ delete require.cache[moduleId];
55
+ let intercepted = false;
56
+ const originalResolve = import_path.default.resolve;
57
+ import_path.default.resolve = ((...args) => {
58
+ const result = originalResolve(...args);
59
+ if (result === nativewindCacheDir) {
60
+ intercepted = true;
61
+ return ourCacheDir;
76
62
  }
63
+ return result;
64
+ });
65
+ try {
66
+ require(moduleId);
67
+ } finally {
68
+ import_path.default.resolve = originalResolve;
69
+ }
70
+ if (!intercepted) {
71
+ throw new Error(
72
+ "patchNativeWindCachePath: patch \u672A\u751F\u6548\u2014\u2014react-native-css-interop \u53EF\u80FD\u5DF2\u4E0D\u518D\u901A\u8FC7 path.resolve \u8BA1\u7B97\u7F13\u5B58\u8DEF\u5F84\u3002\u5347\u7EA7\u8BE5\u4F9D\u8D56\u540E\u8BF7\u68C0\u67E5 dist/metro/index.js \u4E2D\u7684\u5B9E\u73B0\u3002"
73
+ );
77
74
  }
78
- scan(appDir, "");
79
- return { routes };
80
75
  }
81
- function createRouteHandler(appDir) {
82
- return (_req, res) => {
83
- const routeTree = getRoutes(appDir);
84
- res.writeHead(200, { "Content-Type": "application/json" });
85
- res.end(JSON.stringify(routeTree, null, 2));
86
- };
76
+ function withNativeWind(config, options) {
77
+ const { withNativeWind: nwWithNativeWind } = require("nativewind/metro");
78
+ return nwWithNativeWind(config, options);
87
79
  }
88
80
 
89
- // src/metro.ts
81
+ // src/metro/withDevStubs.ts
82
+ var import_path2 = __toESM(require("path"));
90
83
  var SENTRY_STUB_FILENAME = "sentry-react-native-stub.js";
91
84
  var SENTRY_STUB_PATH = import_path2.default.resolve(__dirname, "stubs", SENTRY_STUB_FILENAME);
92
85
  var NO_OP_LOGBOX_STUB_PATH = import_path2.default.resolve(__dirname, "stubs", "no-op-logbox.js");
@@ -114,7 +107,10 @@ function withDevStubs(config) {
114
107
  }
115
108
  };
116
109
  }
117
- var EXPO_ROUTER_ENTRY_STUB_PATH = import_path2.default.resolve(__dirname, "stubs", "expo-router-entry-stub.js");
110
+
111
+ // src/metro/withEntryInjection.ts
112
+ var import_path3 = __toESM(require("path"));
113
+ var EXPO_ROUTER_ENTRY_STUB_PATH = import_path3.default.resolve(__dirname, "stubs", "expo-router-entry-stub.js");
118
114
  var EXPO_ROUTER_ENTRY_STUB_FILENAME = "expo-router-entry-stub.js";
119
115
  function withEntryInjection(config, options) {
120
116
  void options;
@@ -136,13 +132,63 @@ function withEntryInjection(config, options) {
136
132
  }
137
133
  };
138
134
  }
135
+
136
+ // src/metro/withRouteEndpoint.ts
137
+ var import_connect = __toESM(require("connect"));
138
+
139
+ // src/routes.ts
140
+ var import_fs = __toESM(require("fs"));
141
+ var import_path4 = __toESM(require("path"));
142
+ var ROUTE_EXT = /\.(tsx|ts|jsx|js)$/;
143
+ function getRoutes(appDir, rootDir) {
144
+ const routes = [];
145
+ function scan(dir, prefix) {
146
+ let entries;
147
+ try {
148
+ entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
149
+ } catch {
150
+ return;
151
+ }
152
+ for (const entry of entries) {
153
+ const fullPath = import_path4.default.join(dir, entry.name);
154
+ if (entry.isDirectory()) {
155
+ const isGroup = /^\(.*\)$/.test(entry.name);
156
+ const nextPrefix = isGroup ? prefix : `${prefix}/${entry.name}`;
157
+ scan(fullPath, nextPrefix);
158
+ } else if (ROUTE_EXT.test(entry.name)) {
159
+ const baseName = entry.name.replace(ROUTE_EXT, "");
160
+ if (baseName === "_layout" || /\[.*\]/.test(baseName)) continue;
161
+ const segment = baseName === "index" ? "" : `/${baseName}`;
162
+ const routePath = `${prefix}${segment}` || "/";
163
+ routes.push({
164
+ title: routePath.replace(/^\//, "") || "/",
165
+ pageId: routePath,
166
+ pageName: routePath,
167
+ path: import_path4.default.relative(rootDir, fullPath)
168
+ });
169
+ }
170
+ }
171
+ }
172
+ scan(appDir, "");
173
+ return { data: routes };
174
+ }
175
+ function createRouteHandler(appDir, rootDir) {
176
+ return (_req, res) => {
177
+ const routeTree = getRoutes(appDir, rootDir);
178
+ res.writeHead(200, { "Content-Type": "application/json" });
179
+ res.end(JSON.stringify(routeTree, null, 2));
180
+ };
181
+ }
182
+
183
+ // src/metro/withRouteEndpoint.ts
139
184
  var DEFAULT_ROUTE_ENDPOINT = "/__routes";
140
185
  function withRouteEndpoint(config, options) {
141
186
  const { appDir, endpoint = DEFAULT_ROUTE_ENDPOINT } = options;
187
+ const rootDir = config.projectRoot ?? process.cwd();
142
188
  const upstream = config.server?.enhanceMiddleware ?? null;
143
189
  const enhanceMiddleware = (middleware, metroServer) => {
144
190
  const enhanced = upstream ? upstream(middleware, metroServer) : middleware;
145
- return (0, import_connect.default)().use(enhanced).use(endpoint, createRouteHandler(appDir));
191
+ return (0, import_connect.default)().use(enhanced).use(endpoint, createRouteHandler(appDir, rootDir));
146
192
  };
147
193
  return {
148
194
  ...config,
@@ -152,41 +198,153 @@ function withRouteEndpoint(config, options) {
152
198
  }
153
199
  };
154
200
  }
155
- function withWorkspaceNodeModules(config) {
156
- const projectRoot = config.projectRoot ?? process.cwd();
157
- if (import_fs2.default.existsSync(import_path2.default.join(projectRoot, "node_modules"))) {
158
- return config;
159
- }
160
- let dir = import_path2.default.dirname(projectRoot);
161
- let found = null;
201
+
202
+ // src/metro/withWorkspaceNodeModules.ts
203
+ var import_fs2 = __toESM(require("fs"));
204
+ var import_path5 = __toESM(require("path"));
205
+ function findAncestorNodeModulesDir(projectRoot) {
206
+ let dir = import_path5.default.dirname(projectRoot);
162
207
  while (true) {
163
- const candidate = import_path2.default.join(dir, "node_modules");
164
- if (import_fs2.default.existsSync(candidate)) {
165
- found = candidate;
166
- break;
167
- }
168
- const parent = import_path2.default.dirname(dir);
208
+ const candidate = import_path5.default.join(dir, "node_modules");
209
+ if (import_fs2.default.existsSync(candidate)) return candidate;
210
+ const parent = import_path5.default.dirname(dir);
169
211
  if (parent === dir) break;
170
212
  dir = parent;
171
213
  }
172
- if (!found) {
173
- return config;
214
+ return null;
215
+ }
216
+ function resolveExternalPnpmStore(nodeModulesDir) {
217
+ const pnpmDir = import_path5.default.join(nodeModulesDir, ".pnpm");
218
+ try {
219
+ const realPnpmDir = import_fs2.default.realpathSync(pnpmDir);
220
+ const realNmDir = import_path5.default.dirname(realPnpmDir);
221
+ if (realNmDir !== nodeModulesDir) {
222
+ return realNmDir;
223
+ }
224
+ } catch {
225
+ }
226
+ return null;
227
+ }
228
+ function withWorkspaceNodeModules(config) {
229
+ const projectRoot = config.projectRoot ?? process.cwd();
230
+ const found = findAncestorNodeModulesDir(projectRoot);
231
+ if (!found) return config;
232
+ const foldersToAdd = [found];
233
+ const externalStore = resolveExternalPnpmStore(found);
234
+ if (externalStore) {
235
+ foldersToAdd.push(externalStore);
174
236
  }
175
- const existingWatchFolders = config.watchFolders ?? [];
176
- const existingNodeModulesPaths = config.resolver?.nodeModulesPaths ?? [];
177
237
  return {
178
238
  ...config,
179
- watchFolders: [...existingWatchFolders, found],
239
+ watchFolders: [...config.watchFolders ?? [], ...foldersToAdd],
240
+ resolver: {
241
+ ...config.resolver,
242
+ nodeModulesPaths: [...config.resolver?.nodeModulesPaths ?? [], ...foldersToAdd]
243
+ }
244
+ };
245
+ }
246
+
247
+ // src/metro/withCssInterop.ts
248
+ var import_path6 = __toESM(require("path"));
249
+ var EXPO_IMAGE_STUB_FILENAME = "expo-image-stub.js";
250
+ var EXPO_IMAGE_STUB_PATH = import_path6.default.resolve(__dirname, "stubs", EXPO_IMAGE_STUB_FILENAME);
251
+ var EXPO_CAMERA_STUB_FILENAME = "expo-camera-stub.js";
252
+ var EXPO_CAMERA_STUB_PATH = import_path6.default.resolve(__dirname, "stubs", EXPO_CAMERA_STUB_FILENAME);
253
+ var EXPO_LINEAR_GRADIENT_STUB_FILENAME = "expo-linear-gradient-stub.js";
254
+ var EXPO_LINEAR_GRADIENT_STUB_PATH = import_path6.default.resolve(__dirname, "stubs", EXPO_LINEAR_GRADIENT_STUB_FILENAME);
255
+ var EXPO_BLUR_STUB_FILENAME = "expo-blur-stub.js";
256
+ var EXPO_BLUR_STUB_PATH = import_path6.default.resolve(__dirname, "stubs", EXPO_BLUR_STUB_FILENAME);
257
+ function withCssInterop(config) {
258
+ const upstream = config.resolver?.resolveRequest ?? null;
259
+ const resolveRequest = (context, moduleName, platform) => {
260
+ if (moduleName === "expo-image" && !context.originModulePath.includes(EXPO_IMAGE_STUB_FILENAME)) {
261
+ return { filePath: EXPO_IMAGE_STUB_PATH, type: "sourceFile" };
262
+ }
263
+ if (moduleName === "expo-camera" && !context.originModulePath.includes(EXPO_CAMERA_STUB_FILENAME)) {
264
+ return { filePath: EXPO_CAMERA_STUB_PATH, type: "sourceFile" };
265
+ }
266
+ if (moduleName === "expo-linear-gradient" && !context.originModulePath.includes(EXPO_LINEAR_GRADIENT_STUB_FILENAME)) {
267
+ return { filePath: EXPO_LINEAR_GRADIENT_STUB_PATH, type: "sourceFile" };
268
+ }
269
+ if (moduleName === "expo-blur" && !context.originModulePath.includes(EXPO_BLUR_STUB_FILENAME)) {
270
+ return { filePath: EXPO_BLUR_STUB_PATH, type: "sourceFile" };
271
+ }
272
+ if (upstream) {
273
+ return upstream(context, moduleName, platform);
274
+ }
275
+ return context.resolveRequest(context, moduleName, platform);
276
+ };
277
+ return {
278
+ ...config,
180
279
  resolver: {
181
280
  ...config.resolver,
182
- nodeModulesPaths: [...existingNodeModulesPaths, found]
281
+ resolveRequest
183
282
  }
184
283
  };
185
284
  }
285
+
286
+ // src/metro/withDevkit.ts
287
+ var import_path7 = __toESM(require("path"));
288
+
289
+ // src/metro/withEsbuildMinify.ts
290
+ function withEsbuildMinify(config) {
291
+ return {
292
+ ...config,
293
+ transformer: {
294
+ ...config.transformer,
295
+ minifierPath: require.resolve("metro-minify-esbuild"),
296
+ // 清空 terser 默认选项,esbuild 用自己的默认压缩配置
297
+ minifierConfig: {}
298
+ }
299
+ };
300
+ }
301
+
302
+ // src/metro/withDevkit.ts
303
+ var EXPO_NOTIFICATIONS_STUB_FILENAME = "expo-notifications-stub.js";
304
+ var EXPO_NOTIFICATIONS_STUB_PATH = import_path7.default.resolve(__dirname, "stubs", EXPO_NOTIFICATIONS_STUB_FILENAME);
305
+ function withExpoNotificationsStub(config) {
306
+ const upstream = config.resolver?.resolveRequest ?? null;
307
+ const resolveRequest = (context, moduleName, platform) => {
308
+ if (platform === "android" && moduleName === "expo-notifications" && !context.originModulePath.includes(EXPO_NOTIFICATIONS_STUB_FILENAME)) {
309
+ return { filePath: EXPO_NOTIFICATIONS_STUB_PATH, type: "sourceFile" };
310
+ }
311
+ if (upstream) return upstream(context, moduleName, platform);
312
+ return context.resolveRequest(context, moduleName, platform);
313
+ };
314
+ return { ...config, resolver: { ...config.resolver, resolveRequest } };
315
+ }
316
+ function withDevkit(config, options = {}) {
317
+ const projectRoot = config.projectRoot ?? process.cwd();
318
+ const { input = "./src/global.css" } = options;
319
+ config = withWorkspaceNodeModules(config);
320
+ config = withCssInterop(config);
321
+ config = withEsbuildMinify(config);
322
+ config = withExpoNotificationsStub(config);
323
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
324
+ config = withEntryInjection(config);
325
+ config = withDevStubs(config);
326
+ config = withRouteEndpoint(config, { appDir: import_path7.default.join(projectRoot, "src", "app") });
327
+ }
328
+ return withNativeWind(config, { input, inlineRem: 16 });
329
+ }
330
+
331
+ // src/metro/index.ts
332
+ try {
333
+ require.resolve("react-native-css-interop/package.json");
334
+ patchNativeWindCachePath();
335
+ } catch (e) {
336
+ if (e.code !== "MODULE_NOT_FOUND") throw e;
337
+ }
186
338
  // Annotate the CommonJS export names for ESM import in node:
187
339
  0 && (module.exports = {
340
+ patchNativeWindCachePath,
341
+ withCssInterop,
188
342
  withDevStubs,
343
+ withDevkit,
189
344
  withEntryInjection,
345
+ withEsbuildMinify,
346
+ withExpoNotificationsStub,
347
+ withNativeWind,
190
348
  withRouteEndpoint,
191
349
  withWorkspaceNodeModules
192
350
  });