@react-native-harness/metro 1.1.0-rc.1 → 1.1.0-rc.3
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 +6 -1
- package/dist/__tests__/paths.test.d.ts +2 -0
- package/dist/__tests__/paths.test.d.ts.map +1 -0
- package/dist/__tests__/paths.test.js +43 -0
- package/dist/__tests__/withRnHarness.test.d.ts +2 -0
- package/dist/__tests__/withRnHarness.test.d.ts.map +1 -0
- package/dist/__tests__/withRnHarness.test.js +25 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +2 -1
- package/dist/metro-cache.d.ts.map +1 -1
- package/dist/metro-cache.js +4 -4
- package/dist/paths.d.ts +5 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +29 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/withRnHarness.d.ts +1 -2
- package/dist/withRnHarness.d.ts.map +1 -1
- package/dist/withRnHarness.js +6 -76
- package/package.json +4 -9
- package/src/__tests__/withRnHarness.test.ts +32 -0
- package/src/withRnHarness.ts +9 -101
- package/tsconfig.json +0 -9
- package/tsconfig.lib.json +1 -12
- package/vite.config.ts +18 -0
- package/src/babel-transformer.ts +0 -40
- package/src/errors.ts +0 -6
- package/src/getHarnessSerializer.ts +0 -46
- package/src/jest-globals-mock.ts +0 -6
- package/src/manifest.ts +0 -24
- package/src/metro-cache.ts +0 -24
- package/src/resolvers/composite-resolver.ts +0 -16
- package/src/resolvers/resolver.ts +0 -100
- package/src/resolvers/tsconfig-resolver.ts +0 -210
- package/src/resolvers/types.ts +0 -4
- package/src/utils.ts +0 -3
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import type { Resolution, CustomResolutionContext } from 'metro-resolver';
|
|
4
|
-
import type { HarnessResolver } from './types';
|
|
5
|
-
|
|
6
|
-
// This resolver is based on the Expo's implementation.
|
|
7
|
-
// https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/start/server/metro/withMetroMultiPlatform.ts
|
|
8
|
-
// The reason to have it in Harness is that Expo doesn't set the resolveRequest function in the context.
|
|
9
|
-
// In order for tsconfig's paths to work, we need to recreate this logic ourselves.
|
|
10
|
-
|
|
11
|
-
export type TsConfigPaths = {
|
|
12
|
-
paths: Record<string, string[]>;
|
|
13
|
-
baseUrl: string;
|
|
14
|
-
hasBaseUrl: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Load tsconfig.json or jsconfig.json and extract path mappings
|
|
19
|
-
*/
|
|
20
|
-
export const loadTsConfigPaths = (
|
|
21
|
-
projectRoot: string
|
|
22
|
-
): TsConfigPaths | null => {
|
|
23
|
-
const configFiles = ['tsconfig.json', 'jsconfig.json'];
|
|
24
|
-
|
|
25
|
-
for (const configFile of configFiles) {
|
|
26
|
-
const configPath = path.join(projectRoot, configFile);
|
|
27
|
-
|
|
28
|
-
if (!fs.existsSync(configPath)) continue;
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
const content = fs.readFileSync(configPath, 'utf8');
|
|
32
|
-
// Strip comments without touching string literals
|
|
33
|
-
const jsonContent = stripJsonComments(content);
|
|
34
|
-
const config = JSON.parse(jsonContent);
|
|
35
|
-
|
|
36
|
-
const compilerOptions = config.compilerOptions || {};
|
|
37
|
-
const paths = compilerOptions.paths || {};
|
|
38
|
-
const baseUrl = compilerOptions.baseUrl;
|
|
39
|
-
|
|
40
|
-
if (Object.keys(paths).length > 0 || baseUrl) {
|
|
41
|
-
return {
|
|
42
|
-
paths,
|
|
43
|
-
baseUrl: baseUrl ? path.resolve(projectRoot, baseUrl) : projectRoot,
|
|
44
|
-
hasBaseUrl: !!baseUrl,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.warn(`Failed to parse ${configFile}:`, error);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return null;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const stripJsonComments = (input: string): string => {
|
|
56
|
-
let result = '';
|
|
57
|
-
let inString = false;
|
|
58
|
-
let stringChar = '';
|
|
59
|
-
let isEscaped = false;
|
|
60
|
-
let inLineComment = false;
|
|
61
|
-
let inBlockComment = false;
|
|
62
|
-
|
|
63
|
-
for (let i = 0; i < input.length; i += 1) {
|
|
64
|
-
const char = input[i];
|
|
65
|
-
const nextChar = input[i + 1];
|
|
66
|
-
|
|
67
|
-
if (inLineComment) {
|
|
68
|
-
if (char === '\n') {
|
|
69
|
-
inLineComment = false;
|
|
70
|
-
result += char;
|
|
71
|
-
}
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (inBlockComment) {
|
|
76
|
-
if (char === '*' && nextChar === '/') {
|
|
77
|
-
inBlockComment = false;
|
|
78
|
-
i += 1;
|
|
79
|
-
}
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (inString) {
|
|
84
|
-
result += char;
|
|
85
|
-
if (!isEscaped && char === stringChar) {
|
|
86
|
-
inString = false;
|
|
87
|
-
stringChar = '';
|
|
88
|
-
}
|
|
89
|
-
isEscaped = !isEscaped && char === '\\';
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (char === '"' || char === "'") {
|
|
94
|
-
inString = true;
|
|
95
|
-
stringChar = char;
|
|
96
|
-
result += char;
|
|
97
|
-
isEscaped = false;
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (char === '/' && nextChar === '/') {
|
|
102
|
-
inLineComment = true;
|
|
103
|
-
i += 1;
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (char === '/' && nextChar === '*') {
|
|
108
|
-
inBlockComment = true;
|
|
109
|
-
i += 1;
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
result += char;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return result;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Match module name against tsconfig path pattern (supports wildcards)
|
|
121
|
-
*/
|
|
122
|
-
const matchPattern = (
|
|
123
|
-
pattern: string,
|
|
124
|
-
moduleName: string
|
|
125
|
-
): { matched: boolean; captured: string } => {
|
|
126
|
-
const escapedPattern = pattern
|
|
127
|
-
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
|
|
128
|
-
.replace(/\*/g, '(.*)');
|
|
129
|
-
|
|
130
|
-
const regex = new RegExp(`^${escapedPattern}$`);
|
|
131
|
-
const match = moduleName.match(regex);
|
|
132
|
-
|
|
133
|
-
return {
|
|
134
|
-
matched: !!match,
|
|
135
|
-
captured: match?.[1] || '',
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Resolve module using tsconfig path mappings
|
|
141
|
-
* Use this directly in your custom resolver
|
|
142
|
-
*/
|
|
143
|
-
export const resolveWithTsConfigPaths = (
|
|
144
|
-
tsConfig: TsConfigPaths,
|
|
145
|
-
context: CustomResolutionContext,
|
|
146
|
-
moduleName: string,
|
|
147
|
-
platform: string | null
|
|
148
|
-
): Resolution | null => {
|
|
149
|
-
const { paths, baseUrl, hasBaseUrl } = tsConfig;
|
|
150
|
-
const resolveRequest = context.resolveRequest;
|
|
151
|
-
|
|
152
|
-
if (!resolveRequest) {
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Try path mappings first
|
|
157
|
-
for (const [pattern, targets] of Object.entries(paths)) {
|
|
158
|
-
const { matched, captured } = matchPattern(pattern, moduleName);
|
|
159
|
-
if (!matched) continue;
|
|
160
|
-
|
|
161
|
-
// Try each target
|
|
162
|
-
for (const target of targets) {
|
|
163
|
-
const resolvedTarget = target.replace('*', captured);
|
|
164
|
-
const absolutePath = path.resolve(baseUrl, resolvedTarget);
|
|
165
|
-
|
|
166
|
-
try {
|
|
167
|
-
return resolveRequest(context, absolutePath, platform);
|
|
168
|
-
} catch {
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Try baseUrl for non-relative imports
|
|
175
|
-
if (hasBaseUrl && !moduleName.startsWith('.') && !moduleName.startsWith('/')) {
|
|
176
|
-
const absolutePath = path.resolve(baseUrl, moduleName);
|
|
177
|
-
try {
|
|
178
|
-
return resolveRequest(context, absolutePath, platform);
|
|
179
|
-
} catch {
|
|
180
|
-
// Fall through
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return null;
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
export const createTsConfigResolver = (
|
|
188
|
-
projectRoot: string
|
|
189
|
-
): HarnessResolver => {
|
|
190
|
-
const tsConfig = loadTsConfigPaths(projectRoot);
|
|
191
|
-
|
|
192
|
-
return (context, moduleName, platform) => {
|
|
193
|
-
if (!tsConfig) {
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (!context.resolveRequest) {
|
|
198
|
-
return null;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const resolved = resolveWithTsConfigPaths(
|
|
202
|
-
tsConfig,
|
|
203
|
-
context,
|
|
204
|
-
moduleName,
|
|
205
|
-
platform
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
return resolved ?? null;
|
|
209
|
-
};
|
|
210
|
-
};
|
package/src/resolvers/types.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { CustomResolutionContext, Resolution } from 'metro-resolver';
|
|
2
|
-
|
|
3
|
-
export type HarnessResolver = (context: CustomResolutionContext, moduleName: string, platform: string | null) => Resolution | null;
|
|
4
|
-
export type MetroResolver = (context: CustomResolutionContext, moduleName: string, platform: string | null) => Resolution;
|
package/src/utils.ts
DELETED