miaoda-expo-devkit 0.1.1-beta.6 → 0.1.1-beta.8
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 +18 -20
- package/dist/metro.d.ts +18 -20
- package/dist/metro.js +15 -45
- package/dist/metro.mjs +15 -45
- package/package.json +1 -1
package/dist/metro.d.mts
CHANGED
|
@@ -189,24 +189,22 @@ declare function withDevStubs(config: MetroConfig): MetroConfig;
|
|
|
189
189
|
/**
|
|
190
190
|
* withWorkspaceNodeModules — 修复沙箱中 node_modules 不在 projectRoot 内时的模块解析问题
|
|
191
191
|
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
* node_modules
|
|
207
|
-
*
|
|
208
|
-
* 2. 若未找到,通过 require.resolve 定位当前包所在的 node_modules 根目录
|
|
209
|
-
* (适用于 node_modules 位于完全不同路径的情况)。
|
|
192
|
+
* 适用场景:node_modules 位于 projectRoot 的祖先目录(如 /workspace/node_modules),
|
|
193
|
+
* 而 projectRoot 自身的 node_modules 为空目录或不存在。
|
|
194
|
+
*
|
|
195
|
+
* 问题:
|
|
196
|
+
* 1. Metro 只监听 projectRoot,祖先目录的 node_modules 不在 watchFolders 内,
|
|
197
|
+
* 导致模块无法被 file map 索引。
|
|
198
|
+
* 2. pnpm 的 .pnpm 目录可能是指向外部路径的 symlink
|
|
199
|
+
* (如 /workspace/node_modules/.pnpm → /data/expo/node_modules/.pnpm)。
|
|
200
|
+
* Metro 跟随 symlink 后,将文件以真实路径(/data/expo/...)存入 file map,
|
|
201
|
+
* HTML 入口的 bundle URL 也随之变为 /data/expo/...bundle。
|
|
202
|
+
* 若 /data/expo/node_modules/ 不在 watchFolders,Metro HTTP server 会返回 404。
|
|
203
|
+
*
|
|
204
|
+
* 修复:
|
|
205
|
+
* 1. 将祖先目录的 node_modules 加入 watchFolders 和 resolver.nodeModulesPaths。
|
|
206
|
+
* 2. 若该 node_modules 下的 .pnpm 是指向外部路径的 symlink,
|
|
207
|
+
* 同样将外部真实路径加入 watchFolders 和 resolver.nodeModulesPaths。
|
|
210
208
|
*
|
|
211
209
|
* 用法(metro.config.js):
|
|
212
210
|
* const { withWorkspaceNodeModules } = require('miaoda-expo-devkit/metro');
|
|
@@ -214,10 +212,10 @@ declare function withDevStubs(config: MetroConfig): MetroConfig;
|
|
|
214
212
|
*/
|
|
215
213
|
|
|
216
214
|
/**
|
|
217
|
-
* 修复沙箱环境中 node_modules
|
|
215
|
+
* 修复沙箱环境中 node_modules 位于祖先目录时,Metro 模块解析和 bundle 请求失败的问题。
|
|
218
216
|
*
|
|
219
217
|
* @param config Metro config 对象(来自 getDefaultConfig)
|
|
220
|
-
* @returns 修正 watchFolders、nodeModulesPaths
|
|
218
|
+
* @returns 修正 watchFolders、nodeModulesPaths 后的新 Metro config
|
|
221
219
|
*/
|
|
222
220
|
declare function withWorkspaceNodeModules(config: MetroConfig): MetroConfig;
|
|
223
221
|
|
package/dist/metro.d.ts
CHANGED
|
@@ -189,24 +189,22 @@ declare function withDevStubs(config: MetroConfig): MetroConfig;
|
|
|
189
189
|
/**
|
|
190
190
|
* withWorkspaceNodeModules — 修复沙箱中 node_modules 不在 projectRoot 内时的模块解析问题
|
|
191
191
|
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
* node_modules
|
|
207
|
-
*
|
|
208
|
-
* 2. 若未找到,通过 require.resolve 定位当前包所在的 node_modules 根目录
|
|
209
|
-
* (适用于 node_modules 位于完全不同路径的情况)。
|
|
192
|
+
* 适用场景:node_modules 位于 projectRoot 的祖先目录(如 /workspace/node_modules),
|
|
193
|
+
* 而 projectRoot 自身的 node_modules 为空目录或不存在。
|
|
194
|
+
*
|
|
195
|
+
* 问题:
|
|
196
|
+
* 1. Metro 只监听 projectRoot,祖先目录的 node_modules 不在 watchFolders 内,
|
|
197
|
+
* 导致模块无法被 file map 索引。
|
|
198
|
+
* 2. pnpm 的 .pnpm 目录可能是指向外部路径的 symlink
|
|
199
|
+
* (如 /workspace/node_modules/.pnpm → /data/expo/node_modules/.pnpm)。
|
|
200
|
+
* Metro 跟随 symlink 后,将文件以真实路径(/data/expo/...)存入 file map,
|
|
201
|
+
* HTML 入口的 bundle URL 也随之变为 /data/expo/...bundle。
|
|
202
|
+
* 若 /data/expo/node_modules/ 不在 watchFolders,Metro HTTP server 会返回 404。
|
|
203
|
+
*
|
|
204
|
+
* 修复:
|
|
205
|
+
* 1. 将祖先目录的 node_modules 加入 watchFolders 和 resolver.nodeModulesPaths。
|
|
206
|
+
* 2. 若该 node_modules 下的 .pnpm 是指向外部路径的 symlink,
|
|
207
|
+
* 同样将外部真实路径加入 watchFolders 和 resolver.nodeModulesPaths。
|
|
210
208
|
*
|
|
211
209
|
* 用法(metro.config.js):
|
|
212
210
|
* const { withWorkspaceNodeModules } = require('miaoda-expo-devkit/metro');
|
|
@@ -214,10 +212,10 @@ declare function withDevStubs(config: MetroConfig): MetroConfig;
|
|
|
214
212
|
*/
|
|
215
213
|
|
|
216
214
|
/**
|
|
217
|
-
* 修复沙箱环境中 node_modules
|
|
215
|
+
* 修复沙箱环境中 node_modules 位于祖先目录时,Metro 模块解析和 bundle 请求失败的问题。
|
|
218
216
|
*
|
|
219
217
|
* @param config Metro config 对象(来自 getDefaultConfig)
|
|
220
|
-
* @returns 修正 watchFolders、nodeModulesPaths
|
|
218
|
+
* @returns 修正 watchFolders、nodeModulesPaths 后的新 Metro config
|
|
221
219
|
*/
|
|
222
220
|
declare function withWorkspaceNodeModules(config: MetroConfig): MetroConfig;
|
|
223
221
|
|
package/dist/metro.js
CHANGED
|
@@ -202,7 +202,7 @@ function withRouteEndpoint(config, options) {
|
|
|
202
202
|
// src/metro/withWorkspaceNodeModules.ts
|
|
203
203
|
var import_fs2 = __toESM(require("fs"));
|
|
204
204
|
var import_path5 = __toESM(require("path"));
|
|
205
|
-
function findAncestorNodeModulesDir(projectRoot
|
|
205
|
+
function findAncestorNodeModulesDir(projectRoot) {
|
|
206
206
|
let dir = import_path5.default.dirname(projectRoot);
|
|
207
207
|
while (true) {
|
|
208
208
|
const candidate = import_path5.default.join(dir, "node_modules");
|
|
@@ -211,15 +211,15 @@ function findAncestorNodeModulesDir(projectRoot, resolvePackage = require.resolv
|
|
|
211
211
|
if (parent === dir) break;
|
|
212
212
|
dir = parent;
|
|
213
213
|
}
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
function resolveExternalPnpmStore(nodeModulesDir) {
|
|
217
|
+
const pnpmDir = import_path5.default.join(nodeModulesDir, ".pnpm");
|
|
214
218
|
try {
|
|
215
|
-
const
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const candidate = parts.slice(0, nmIndex + 1).join(import_path5.default.sep) || import_path5.default.sep;
|
|
220
|
-
if (import_fs2.default.existsSync(candidate) && candidate !== import_path5.default.join(projectRoot, "node_modules")) {
|
|
221
|
-
return candidate;
|
|
222
|
-
}
|
|
219
|
+
const realPnpmDir = import_fs2.default.realpathSync(pnpmDir);
|
|
220
|
+
const realNmDir = import_path5.default.dirname(realPnpmDir);
|
|
221
|
+
if (realNmDir !== nodeModulesDir) {
|
|
222
|
+
return realNmDir;
|
|
223
223
|
}
|
|
224
224
|
} catch {
|
|
225
225
|
}
|
|
@@ -227,49 +227,19 @@ function findAncestorNodeModulesDir(projectRoot, resolvePackage = require.resolv
|
|
|
227
227
|
}
|
|
228
228
|
function withWorkspaceNodeModules(config) {
|
|
229
229
|
const projectRoot = config.projectRoot ?? process.cwd();
|
|
230
|
-
if (import_fs2.default.existsSync(import_path5.default.join(projectRoot, "node_modules"))) {
|
|
231
|
-
return config;
|
|
232
|
-
}
|
|
233
230
|
const found = findAncestorNodeModulesDir(projectRoot);
|
|
234
231
|
if (!found) return config;
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const isExternalPath = !projectRoot.startsWith(foundParentWithSep);
|
|
240
|
-
if (!isExternalPath) {
|
|
241
|
-
return {
|
|
242
|
-
...config,
|
|
243
|
-
watchFolders: [...existingWatchFolders, found],
|
|
244
|
-
resolver: {
|
|
245
|
-
...config.resolver,
|
|
246
|
-
nodeModulesPaths: [...existingNodeModulesPaths, found]
|
|
247
|
-
}
|
|
248
|
-
};
|
|
232
|
+
const foldersToAdd = [found];
|
|
233
|
+
const externalStore = resolveExternalPnpmStore(found);
|
|
234
|
+
if (externalStore) {
|
|
235
|
+
foldersToAdd.push(externalStore);
|
|
249
236
|
}
|
|
250
|
-
const upstream = config.resolver?.resolveRequest ?? null;
|
|
251
|
-
const foundRelativePrefix = found.slice(1) + import_path5.default.sep;
|
|
252
|
-
const resolveRequest = (context, moduleName, platform) => {
|
|
253
|
-
if (moduleName.startsWith("./") && moduleName.slice(2).startsWith(foundRelativePrefix)) {
|
|
254
|
-
const absolutePath = import_path5.default.sep + moduleName.slice(2);
|
|
255
|
-
const extsToTry = ["", ".js", ".ts", ".tsx", ".jsx", ".json"];
|
|
256
|
-
for (const ext of extsToTry) {
|
|
257
|
-
const candidate = absolutePath + ext;
|
|
258
|
-
if (import_fs2.default.existsSync(candidate)) {
|
|
259
|
-
return { filePath: candidate, type: "sourceFile" };
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
if (upstream) return upstream(context, moduleName, platform);
|
|
264
|
-
return context.resolveRequest(context, moduleName, platform);
|
|
265
|
-
};
|
|
266
237
|
return {
|
|
267
238
|
...config,
|
|
268
|
-
watchFolders: [...
|
|
239
|
+
watchFolders: [...config.watchFolders ?? [], ...foldersToAdd],
|
|
269
240
|
resolver: {
|
|
270
241
|
...config.resolver,
|
|
271
|
-
nodeModulesPaths: [...
|
|
272
|
-
resolveRequest
|
|
242
|
+
nodeModulesPaths: [...config.resolver?.nodeModulesPaths ?? [], ...foldersToAdd]
|
|
273
243
|
}
|
|
274
244
|
};
|
|
275
245
|
}
|
package/dist/metro.mjs
CHANGED
|
@@ -166,7 +166,7 @@ function withRouteEndpoint(config, options) {
|
|
|
166
166
|
// src/metro/withWorkspaceNodeModules.ts
|
|
167
167
|
import fs2 from "fs";
|
|
168
168
|
import path5 from "path";
|
|
169
|
-
function findAncestorNodeModulesDir(projectRoot
|
|
169
|
+
function findAncestorNodeModulesDir(projectRoot) {
|
|
170
170
|
let dir = path5.dirname(projectRoot);
|
|
171
171
|
while (true) {
|
|
172
172
|
const candidate = path5.join(dir, "node_modules");
|
|
@@ -175,15 +175,15 @@ function findAncestorNodeModulesDir(projectRoot, resolvePackage = __require.reso
|
|
|
175
175
|
if (parent === dir) break;
|
|
176
176
|
dir = parent;
|
|
177
177
|
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
function resolveExternalPnpmStore(nodeModulesDir) {
|
|
181
|
+
const pnpmDir = path5.join(nodeModulesDir, ".pnpm");
|
|
178
182
|
try {
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const candidate = parts.slice(0, nmIndex + 1).join(path5.sep) || path5.sep;
|
|
184
|
-
if (fs2.existsSync(candidate) && candidate !== path5.join(projectRoot, "node_modules")) {
|
|
185
|
-
return candidate;
|
|
186
|
-
}
|
|
183
|
+
const realPnpmDir = fs2.realpathSync(pnpmDir);
|
|
184
|
+
const realNmDir = path5.dirname(realPnpmDir);
|
|
185
|
+
if (realNmDir !== nodeModulesDir) {
|
|
186
|
+
return realNmDir;
|
|
187
187
|
}
|
|
188
188
|
} catch {
|
|
189
189
|
}
|
|
@@ -191,49 +191,19 @@ function findAncestorNodeModulesDir(projectRoot, resolvePackage = __require.reso
|
|
|
191
191
|
}
|
|
192
192
|
function withWorkspaceNodeModules(config) {
|
|
193
193
|
const projectRoot = config.projectRoot ?? process.cwd();
|
|
194
|
-
if (fs2.existsSync(path5.join(projectRoot, "node_modules"))) {
|
|
195
|
-
return config;
|
|
196
|
-
}
|
|
197
194
|
const found = findAncestorNodeModulesDir(projectRoot);
|
|
198
195
|
if (!found) return config;
|
|
199
|
-
const
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const isExternalPath = !projectRoot.startsWith(foundParentWithSep);
|
|
204
|
-
if (!isExternalPath) {
|
|
205
|
-
return {
|
|
206
|
-
...config,
|
|
207
|
-
watchFolders: [...existingWatchFolders, found],
|
|
208
|
-
resolver: {
|
|
209
|
-
...config.resolver,
|
|
210
|
-
nodeModulesPaths: [...existingNodeModulesPaths, found]
|
|
211
|
-
}
|
|
212
|
-
};
|
|
196
|
+
const foldersToAdd = [found];
|
|
197
|
+
const externalStore = resolveExternalPnpmStore(found);
|
|
198
|
+
if (externalStore) {
|
|
199
|
+
foldersToAdd.push(externalStore);
|
|
213
200
|
}
|
|
214
|
-
const upstream = config.resolver?.resolveRequest ?? null;
|
|
215
|
-
const foundRelativePrefix = found.slice(1) + path5.sep;
|
|
216
|
-
const resolveRequest = (context, moduleName, platform) => {
|
|
217
|
-
if (moduleName.startsWith("./") && moduleName.slice(2).startsWith(foundRelativePrefix)) {
|
|
218
|
-
const absolutePath = path5.sep + moduleName.slice(2);
|
|
219
|
-
const extsToTry = ["", ".js", ".ts", ".tsx", ".jsx", ".json"];
|
|
220
|
-
for (const ext of extsToTry) {
|
|
221
|
-
const candidate = absolutePath + ext;
|
|
222
|
-
if (fs2.existsSync(candidate)) {
|
|
223
|
-
return { filePath: candidate, type: "sourceFile" };
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
if (upstream) return upstream(context, moduleName, platform);
|
|
228
|
-
return context.resolveRequest(context, moduleName, platform);
|
|
229
|
-
};
|
|
230
201
|
return {
|
|
231
202
|
...config,
|
|
232
|
-
watchFolders: [...
|
|
203
|
+
watchFolders: [...config.watchFolders ?? [], ...foldersToAdd],
|
|
233
204
|
resolver: {
|
|
234
205
|
...config.resolver,
|
|
235
|
-
nodeModulesPaths: [...
|
|
236
|
-
resolveRequest
|
|
206
|
+
nodeModulesPaths: [...config.resolver?.nodeModulesPaths ?? [], ...foldersToAdd]
|
|
237
207
|
}
|
|
238
208
|
};
|
|
239
209
|
}
|