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

162 lines (161 loc) • 6.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createNodes = exports.createNodesV2 = void 0; const devkit_1 = require("@nx/devkit"); const path_1 = require("path"); const js_1 = require("@nx/js"); const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs"); const fs_1 = require("fs"); const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes"); const cache_directory_1 = require("nx/src/utils/cache-directory"); const config_utils_1 = require("@nx/devkit/src/utils/config-utils"); const devkit_internals_1 = require("nx/src/devkit-internals"); function readTargetsCache(cachePath) { return (0, fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {}; } function writeTargetsToCache(cachePath, targetsCache) { const oldCache = readTargetsCache(cachePath); (0, devkit_1.writeJsonFile)(cachePath, { ...oldCache, targetsCache, }); } exports.createNodesV2 = [ '**/app.{json,config.js,config.ts}', async (configFiles, options, context) => { const optionsHash = (0, devkit_internals_1.hashObject)(options); const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, `react-native-${optionsHash}.hash`); const targetsCache = readTargetsCache(cachePath); try { return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => createNodesInternal(configFile, options, context, targetsCache), configFiles, options, context); } finally { writeTargetsToCache(cachePath, targetsCache); } }, ]; exports.createNodes = [ '**/app.{json,config.js,config.ts}', async (configFilePath, options, context) => { const optionsHash = (0, devkit_internals_1.hashObject)(options); const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, `react-native-${optionsHash}.hash`); const targetsCache = readTargetsCache(cachePath); const result = await createNodesInternal(configFilePath, options, context, targetsCache); writeTargetsToCache(cachePath, targetsCache); return result; }, ]; async function createNodesInternal(configFile, options, context, targetsCache) { options = normalizeOptions(options); const projectRoot = (0, path_1.dirname)(configFile); // Do not create a project if package.json or project.json or metro.config.js isn't there. const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot)); if (!siblingFiles.includes('package.json') || !siblingFiles.includes('metro.config.js')) { return {}; } // Check if it's an Expo project const packageJson = (0, devkit_1.readJsonFile)((0, path_1.join)(context.workspaceRoot, projectRoot, 'package.json')); const appConfig = await getAppConfig(configFile, context); if (appConfig.expo || packageJson.dependencies?.['expo'] || packageJson.devDependencies?.['expo']) { return {}; } const hash = await (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context, [(0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot))]); targetsCache[hash] ??= buildReactNativeTargets(projectRoot, options, context); return { projects: { [projectRoot]: { targets: targetsCache[hash], }, }, }; } function buildReactNativeTargets(projectRoot, options, context) { const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context); const targets = { [options.startTargetName]: { command: `react-native start`, options: { cwd: projectRoot }, }, [options.podInstallTargetName]: { command: `pod install`, options: { cwd: (0, devkit_1.joinPathFragments)(projectRoot, 'ios') }, dependsOn: [`${options.syncDepsTargetName}`], }, [options.runIosTargetName]: { command: `react-native run-ios`, options: { cwd: projectRoot }, }, [options.runAndroidTargetName]: { command: `react-native run-android`, options: { cwd: projectRoot }, }, [options.buildIosTargetName]: { command: `react-native build-ios`, options: { cwd: projectRoot }, cache: true, dependsOn: [`^${options.buildIosTargetName}`], inputs: getInputs(namedInputs), outputs: [getOutputs(projectRoot, 'ios/build/Build/Products')], }, [options.buildAndroidTargetName]: { command: `react-native build-android`, options: { cwd: projectRoot }, cache: true, dependsOn: [`^${options.buildAndroidTargetName}`], inputs: getInputs(namedInputs), outputs: [getOutputs(projectRoot, 'android/app/build/outputs')], }, [options.bundleTargetName]: { command: `react-native bundle`, options: { cwd: projectRoot }, dependsOn: [`^${options.bundleTargetName}`], inputs: getInputs(namedInputs), }, [options.syncDepsTargetName]: { executor: '@nx/react-native:sync-deps', }, [options.upgradeTargetName]: { command: `react-native upgrade`, options: { cwd: projectRoot }, }, }; return targets; } function getAppConfig(configFilePath, context) { const resolvedPath = (0, path_1.join)(context.workspaceRoot, configFilePath); return (0, config_utils_1.loadConfigFile)(resolvedPath); } function getInputs(namedInputs) { return [ ...('production' in namedInputs ? ['default', '^production'] : ['default', '^default']), { externalDependencies: ['react-native'], }, ]; } function getOutputs(projectRoot, dir) { if (projectRoot === '.') { return `{projectRoot}/${dir}`; } else { return `{workspaceRoot}/${projectRoot}/${dir}`; } } function normalizeOptions(options) { options ??= {}; options.startTargetName ??= 'start'; options.podInstallTargetName ??= 'pod-install'; options.runIosTargetName ??= 'run-ios'; options.runAndroidTargetName ??= 'run-android'; options.buildIosTargetName ??= 'build-ios'; options.buildAndroidTargetName ??= 'build-android'; options.bundleTargetName ??= 'bundle'; options.syncDepsTargetName ??= 'sync-deps'; options.upgradeTargetName ??= 'upgrade'; return options; }