UNPKG

@nx/react-native

Version:

The Nx Plugin for React Native contains generators for managing React Native applications and libraries within an Nx workspace. It provides: -Integration with libraries such as Jest, Detox, and Storybook. -Scaffolding for creating buildable libraries th

163 lines (162 loc) 6.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getResolveRequest = getResolveRequest; const tsconfig_paths_1 = require("tsconfig-paths"); const pc = require("picocolors"); const enhanced_resolve_1 = require("enhanced-resolve"); const path_1 = require("path"); const fs = require("fs"); const devkit_1 = require("@nx/devkit"); // Cache for metro-resolver module let metroResolver = null; /** * Lazily require metro-resolver to handle cases where it might not be installed */ function getMetroResolver() { if (!metroResolver) { try { metroResolver = require('metro-resolver'); } catch (error) { throw new Error('metro-resolver is required but not installed. Please install metro-resolver >= 0.82.0'); } } return metroResolver; } /* * Use tsconfig to resolve additional workspace libs. * * This resolve function requires projectRoot to be set to * workspace root in order modules and assets to be registered and watched. */ function getResolveRequest(extensions, exportsConditionNames = [], mainFields = []) { return function (_context, realModuleName, platform) { const debug = process.env.NX_REACT_NATIVE_DEBUG === 'true'; const { resolveRequest, ...context } = _context; const resolvedPath = resolveRequestFromContext(resolveRequest, _context, realModuleName, platform, debug) ?? defaultMetroResolver(context, realModuleName, platform, debug) ?? tsconfigPathsResolver(context, extensions, realModuleName, platform, debug) ?? pnpmResolver(extensions, context, realModuleName, debug, exportsConditionNames, mainFields); if (resolvedPath) { return resolvedPath; } if (debug) { console.log(pc.red(`[Nx] Unable to resolve with any resolver: ${realModuleName}`)); } throw new Error(`Cannot resolve ${pc.bold(realModuleName)}`); }; } function resolveRequestFromContext(resolveRequest, context, realModuleName, platform, debug) { try { return resolveRequest(context, realModuleName, platform); } catch { if (debug) console.log(pc.cyan(`[Nx] Unable to resolve with default resolveRequest: ${realModuleName}`)); } } /** * This function try to resolve path using metro's default resolver * @returns path if resolved, else undefined */ function defaultMetroResolver(context, realModuleName, platform, debug) { try { const resolver = getMetroResolver(); return resolver.resolve(context, realModuleName, platform); } catch { if (debug) console.log(pc.cyan(`[Nx] Unable to resolve with default Metro resolver: ${realModuleName}`)); } } /** * This resolver try to resolve module for pnpm. * @returns path if resolved, else undefined * This pnpm resolver is inspired from https://github.com/vjpr/pnpm-react-native-example/blob/main/packages/pnpm-expo-helper/util/make-resolver.js */ function pnpmResolver(extensions, context, realModuleName, debug, exportsConditionNames = [], mainFields = []) { try { const pnpmResolve = getPnpmResolver(extensions, exportsConditionNames, mainFields); const lookupStartPath = (0, path_1.dirname)(context.originModulePath); const filePath = pnpmResolve.resolveSync({}, lookupStartPath, realModuleName); if (filePath) { return { type: 'sourceFile', filePath }; } } catch { if (debug) console.log(pc.cyan(`[Nx] Unable to resolve with default PNPM resolver: ${realModuleName}`)); } } /** * This function try to resolve files that are specified in tsconfig's paths * @returns path if resolved, else undefined */ function tsconfigPathsResolver(context, extensions, realModuleName, platform, debug) { try { const tsConfigPathMatcher = getMatcher(debug); const match = tsConfigPathMatcher(realModuleName, undefined, undefined, extensions.map((ext) => `.${ext}`)); const resolver = getMetroResolver(); return resolver.resolve(context, match, platform); } catch { if (debug) { console.log(pc.cyan(`[Nx] Failed to resolve ${pc.bold(realModuleName)}`)); console.log(pc.cyan(`[Nx] The following tsconfig paths was used:\n:${pc.bold(JSON.stringify(paths, null, 2))}`)); } } } let matcher; let absoluteBaseUrl; let paths; function getMatcher(debug) { if (!matcher) { const result = (0, tsconfig_paths_1.loadConfig)(); if (result.resultType === 'success') { absoluteBaseUrl = result.absoluteBaseUrl; paths = result.paths; if (debug) { console.log(pc.cyan(`[Nx] Located tsconfig at ${pc.bold(absoluteBaseUrl)}`)); console.log(pc.cyan(`[Nx] Found the following paths:\n:${pc.bold(JSON.stringify(paths, null, 2))}`)); } matcher = (0, tsconfig_paths_1.createMatchPath)(absoluteBaseUrl, paths); } else { console.log(pc.cyan(`[Nx] Failed to locate tsconfig}`)); throw new Error(`Could not load tsconfig for project`); } } return matcher; } /** * This function returns resolver for pnpm. * It is inspired form https://github.com/vjpr/pnpm-expo-example/blob/main/packages/pnpm-expo-helper/util/make-resolver.js. */ let pnpmpResolver; function getPnpmResolver(extensions, exportsConditionNames = [], mainFields = []) { if (!pnpmpResolver) { // Create a filesystem adapter that matches enhanced-resolve's expected interface // The issue is that Node.js fs types allow withFileTypes: true, but enhanced-resolve expects withFileTypes?: false // This is compatible with the latest version of enhanced-resolve and is the intended way to use it. // See https://github.com/webpack/enhanced-resolve/commit/d55471f20c17bce4def0b53cfe0b7027e7b48d82 const fileSystem = new enhanced_resolve_1.CachedInputFileSystem(fs, 4000); pnpmpResolver = enhanced_resolve_1.ResolverFactory.createResolver({ fileSystem, extensions: extensions.map((extension) => '.' + extension), useSyncFileSystemCalls: true, modules: [(0, path_1.join)(devkit_1.workspaceRoot, 'node_modules'), 'node_modules'], conditionNames: [ 'native', 'browser', 'require', 'default', 'react-native', 'node', ...exportsConditionNames, ], mainFields: ['react-native', 'browser', 'main', ...mainFields], aliasFields: ['browser'], }); } return pnpmpResolver; }