Skip to content

Commit 603d2c6

Browse files
committed
Fixed inline modules without TS, added caching
1 parent 434d094 commit 603d2c6

File tree

6 files changed

+153
-101
lines changed

6 files changed

+153
-101
lines changed

apps/bare-expo/metro.config.js

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,22 @@ config.watchFolders = [
2525
path.join(monorepoRoot, 'apps/test-suite'), // Workaround for Yarn v1 workspace issue where workspace dependencies aren't properly linked, should be at `<root>/node_modules/apps/test-suite`
2626
];
2727

28-
function findUpTSConfig(cwd) {
29-
const tsconfigPath = path.resolve(cwd, './tsconfig.json');
30-
if (fs.existsSync(tsconfigPath)) {
31-
return path.dirname(tsconfigPath);
28+
function findUpPackageJsonDirectory(cwd, directoryToPackage) {
29+
if (['.', path.sep].includes(cwd)) return undefined;
30+
if (directoryToPackage.has(cwd)) return directoryToPackage.get(cwd);
31+
32+
const packageFound = fs.existsSync(path.resolve(cwd, './package.json'));
33+
if (packageFound) {
34+
directoryToPackage.set(cwd, cwd);
35+
return cwd;
3236
}
33-
34-
const parent = path.dirname(cwd);
35-
if (parent === cwd) return null;
36-
37-
return findUpTSConfig(parent);
38-
}
39-
40-
function findUpTSProjectRootOrThrow(dir) {
41-
const tsProjectRoot = findUpTSConfig(dir);
42-
if (!tsProjectRoot) {
43-
throw new Error(
44-
'Inline modules watched dir needs to be inside a TS project with tsconfig.json'
45-
);
37+
const packageRoot = findUpPackageJsonDirectory(path.dirname(cwd), directoryToPackage);
38+
if (packageRoot) {
39+
directoryToPackage.set(cwd, packageRoot);
4640
}
47-
return tsProjectRoot;
41+
return packageRoot;
4842
}
43+
const directoryToPackage = new Map();
4944

5045
// When testing on MacOS we need to swap out `react-native` for `react-native-macos`
5146
config.resolver.resolveRequest = (context, moduleName, platform) => {
@@ -66,15 +61,24 @@ config.resolver.resolveRequest = (context, moduleName, platform) => {
6661
inlineModuleFileExtension = '.view.js';
6762
}
6863
if (inlineModuleFileExtension) {
69-
const tsProjectRoot = findUpTSProjectRootOrThrow(path.dirname(context.originModulePath));
70-
const modulePathRelativeToTSRoot = path.relative(
71-
tsProjectRoot,
64+
const originModuleDirname = path.dirname(context.originModulePath);
65+
let modulePackageRoot = directoryToPackage.get(originModuleDirname);
66+
if (!modulePackageRoot) {
67+
modulePackageRoot = findUpPackageJsonDirectory(
68+
path.dirname(context.originModulePath),
69+
directoryToPackage
70+
);
71+
}
72+
if (!modulePackageRoot) {
73+
return { type: 'empty' };
74+
}
75+
const modulePathRelativeToItsPackageRoot = path.relative(
76+
modulePackageRoot,
7277
fs.realpathSync(path.dirname(context.originModulePath))
7378
);
74-
7579
const modulePath = path.resolve(
7680
inlineModulesModulesPath,
77-
modulePathRelativeToTSRoot,
81+
modulePathRelativeToItsPackageRoot,
7882
moduleName.substring(0, moduleName.lastIndexOf('.')) + inlineModuleFileExtension
7983
);
8084

packages/@expo/cli/src/inlineModules/generation.ts

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { getConfig } from '@expo/config';
22
import { getPbxproj } from '@expo/config-plugins/build/ios/utils/Xcodeproj';
33
import Server from '@expo/metro/metro/Server';
4-
import type MetroServer from '@expo/metro/metro/Server';
54
import fs from 'fs';
65
import path from 'path';
76

@@ -13,26 +12,24 @@ export interface ModuleGenerationArguments {
1312
metro: Server | null;
1413
}
1514

16-
function findUpTSConfig(cwd: string): string | null {
17-
const tsconfigPath = path.resolve(cwd, './tsconfig.json');
18-
if (fs.existsSync(tsconfigPath)) {
19-
return path.dirname(tsconfigPath);
15+
function findUpPackageJsonDirectory(
16+
cwd: string,
17+
directoryToPackage: Map<string, string>
18+
): string | undefined {
19+
if (['.', path.sep].includes(cwd)) return undefined;
20+
if (directoryToPackage.has(cwd)) return directoryToPackage.get(cwd);
21+
22+
const packageFound = fs.existsSync(path.resolve(cwd, './package.json'));
23+
if (packageFound) {
24+
directoryToPackage.set(cwd, cwd);
25+
return cwd;
2026
}
21-
22-
const parent = path.dirname(cwd);
23-
if (parent === cwd) return null;
24-
25-
return findUpTSConfig(parent);
26-
}
27-
28-
function findUpTSProjectRootOrThrow(dir: string): string {
29-
const tsProjectRoot = findUpTSConfig(dir);
30-
if (!tsProjectRoot) {
31-
throw new Error('Local modules watched dir needs to be inside a TS project with tsconfig.json');
27+
const packageRoot = findUpPackageJsonDirectory(path.dirname(cwd), directoryToPackage);
28+
if (packageRoot) {
29+
directoryToPackage.set(cwd, packageRoot);
3230
}
33-
return tsProjectRoot;
31+
return packageRoot;
3432
}
35-
3633
const nativeExtensions = ['.kt', '.swift'];
3734

3835
function isValidLocalModuleFileName(fileName: string): boolean {
@@ -90,7 +87,8 @@ function trimExtension(fileName: string): string {
9087
function typesAndLocalModulePathsForFile(
9188
projectRoot: string,
9289
watchedDirRootAbolutePath: string,
93-
absoluteFilePath: string
90+
absoluteFilePath: string,
91+
directoryToPackage: Map<string, string>
9492
): {
9593
moduleTypesFilePath: string;
9694
viewTypesFilePath: string;
@@ -102,8 +100,14 @@ function typesAndLocalModulePathsForFile(
102100
const fileName = path.basename(absoluteFilePath);
103101
const moduleName = trimExtension(fileName);
104102

105-
const watchedDirTSProjectRoot = findUpTSProjectRootOrThrow(watchedDirRootAbolutePath);
106-
const filePathRelativeToTSProjectRoot = path.relative(watchedDirTSProjectRoot, absoluteFilePath);
103+
const watchedDirProjectRoot = findUpPackageJsonDirectory(
104+
watchedDirRootAbolutePath,
105+
directoryToPackage
106+
);
107+
if (!watchedDirProjectRoot) {
108+
throw Error('Watched directory is not inside a project with package.json!');
109+
}
110+
const filePathRelativeToTSProjectRoot = path.relative(watchedDirProjectRoot, absoluteFilePath);
107111
const filePathRelativeToTSProjectRootWithoutExtension = trimExtension(
108112
filePathRelativeToTSProjectRoot
109113
);
@@ -231,10 +235,16 @@ function onSourceFileCreated(
231235
projectRoot: string,
232236
watchedDirRootAbolutePath: string,
233237
absoluteFilePath: string,
238+
directoryToPackage: Map<string, string>,
234239
filesWatched?: Set<string>
235240
): void {
236241
const { moduleTypesFilePath, viewTypesFilePath, viewExportPath, moduleExportPath, moduleName } =
237-
typesAndLocalModulePathsForFile(projectRoot, watchedDirRootAbolutePath, absoluteFilePath);
242+
typesAndLocalModulePathsForFile(
243+
projectRoot,
244+
watchedDirRootAbolutePath,
245+
absoluteFilePath,
246+
directoryToPackage
247+
);
238248

239249
if (filesWatched && fileWatchedWithAnyNativeExtension(absoluteFilePath, filesWatched)) {
240250
filesWatched.add(absoluteFilePath);
@@ -270,7 +280,8 @@ export default _default`
270280

271281
async function generateMirrorDirectories(
272282
projectRoot: string,
273-
filesWatched?: Set<string>
283+
filesWatched?: Set<string>,
284+
directoryToPackage: Map<string, string> = new Map<string, string>()
274285
): Promise<void> {
275286
createFreshMirrorDirectories(projectRoot);
276287

@@ -296,6 +307,7 @@ async function generateMirrorDirectories(
296307
projectRoot,
297308
watchedDirRootAbolutePath,
298309
absoluteDirentPath,
310+
directoryToPackage,
299311
filesWatched
300312
);
301313
} else if (dirent.isDirectory()) {
@@ -336,6 +348,7 @@ export async function startModuleGenerationAsync({
336348
}: ModuleGenerationArguments): Promise<void> {
337349
const dotExpoDir = ensureDotExpoProjectDirectoryInitialized(projectRoot);
338350
const filesWatched = new Set<string>();
351+
const directoryToPackage: Map<string, string> = new Map<string, string>();
339352

340353
const isFileExcluded = (absolutePath: string) => {
341354
for (const glob of excludePathsGlobs(projectRoot)) {
@@ -359,7 +372,12 @@ export async function startModuleGenerationAsync({
359372

360373
const onSourceFileRemoved = (absoluteFilePath: string, watchedDirRootAbolutePath: string) => {
361374
const { moduleTypesFilePath, moduleExportPath, viewExportPath, viewTypesFilePath } =
362-
typesAndLocalModulePathsForFile(projectRoot, watchedDirRootAbolutePath, absoluteFilePath);
375+
typesAndLocalModulePathsForFile(
376+
projectRoot,
377+
watchedDirRootAbolutePath,
378+
absoluteFilePath,
379+
directoryToPackage
380+
);
363381

364382
filesWatched.delete(absoluteFilePath);
365383
if (!fileWatchedWithAnyNativeExtension(absoluteFilePath, filesWatched)) {
@@ -395,7 +413,13 @@ export async function startModuleGenerationAsync({
395413
) {
396414
const { filePath } = event;
397415
if (event.type === 'add') {
398-
onSourceFileCreated(projectRoot, watchedDirAncestor, filePath, filesWatched);
416+
onSourceFileCreated(
417+
projectRoot,
418+
watchedDirAncestor,
419+
filePath,
420+
directoryToPackage,
421+
filesWatched
422+
);
399423
} else if (event.type === 'delete') {
400424
onSourceFileRemoved(filePath, watchedDirAncestor);
401425
}
@@ -405,5 +429,5 @@ export async function startModuleGenerationAsync({
405429

406430
watcher?.addListener('change', listener);
407431

408-
await generateMirrorDirectories(projectRoot, filesWatched);
432+
await generateMirrorDirectories(projectRoot, filesWatched, directoryToPackage);
409433
}

packages/@expo/cli/src/start/server/metro/MetroBundlerDevServer.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,21 +1493,26 @@ export class MetroBundlerDevServer extends BundlerDevServer {
14931493
}
14941494

14951495
public async startTypeScriptServices(): Promise<any> {
1496-
const { projectRoot, metro } = this;
14971496
const startTypescriptTypeGenerationPromise = startTypescriptTypeGenerationAsync({
14981497
server: this.instance?.server,
14991498
metro: this.metro,
15001499
projectRoot: this.projectRoot,
15011500
});
15021501

1502+
return startTypescriptTypeGenerationPromise;
1503+
}
1504+
1505+
private async inlineModulesSetup(): Promise<void> {
1506+
const { projectRoot, metro } = this;
15031507
const { exp } = getConfig(this.projectRoot);
15041508
if (exp.experiments?.inlineModules === true) {
1505-
return Promise.all([
1506-
startTypescriptTypeGenerationPromise,
1507-
startModuleGenerationAsync({ projectRoot, metro }),
1508-
]);
1509+
return startModuleGenerationAsync({ projectRoot, metro });
15091510
}
1510-
return startTypescriptTypeGenerationPromise;
1511+
}
1512+
1513+
protected async postStartAsync(options: BundlerStartOptions): Promise<void> {
1514+
await super.postStartAsync(options);
1515+
return this.inlineModulesSetup();
15111516
}
15121517

15131518
protected getConfigModuleIds(): string[] {

packages/@expo/metro-config/build/ExpoMetroConfig.js

Lines changed: 28 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)