UNPKG

@nx/expo

Version:

The Expo Plugin for Nx contains executors and generators for managing and developing an expo application within your workspace. For example, you can directly build for different target platforms as well as generate projects and publish your code.

178 lines (177 loc) • 6.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createNodesV2 = exports.createNodes = void 0; const internal_1 = require("@nx/devkit/internal"); const devkit_1 = require("@nx/devkit"); const path_1 = require("path"); const js_1 = require("@nx/js"); const fs_1 = require("fs"); const cache_directory_1 = require("nx/src/utils/cache-directory"); const devkit_internals_1 = require("nx/src/devkit-internals"); const internal_2 = require("@nx/js/internal"); exports.createNodes = [ '**/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, `expo-${optionsHash}.hash`); const targetsCache = new internal_1.PluginCache(cachePath); const packageManager = (0, devkit_1.detectPackageManager)(context.workspaceRoot); const pmc = (0, devkit_1.getPackageManagerCommand)(packageManager); const lockFileName = (0, js_1.getLockFileName)(packageManager); const normalizedOptions = normalizeOptions(options); try { const { entries, preErrors } = await filterExpoConfigs(configFiles, context); const projectHashes = await (0, internal_1.calculateHashesForCreateNodes)(entries.map((e) => e.projectRoot), normalizedOptions, context, entries.map(() => [lockFileName])); let results = []; let nodeErrors = []; try { results = await (0, devkit_1.createNodesFromFiles)((configFile, _, ctx, idx) => createNodesInternal(configFile, normalizedOptions, ctx, targetsCache, pmc, projectHashes[idx]), entries.map((e) => e.configFile), options, context); } catch (e) { if (e instanceof devkit_1.AggregateCreateNodesError) { results = e.partialResults ?? []; nodeErrors = e.errors; } else { throw e; } } const allErrors = [...preErrors, ...nodeErrors]; if (allErrors.length > 0) { throw new devkit_1.AggregateCreateNodesError(allErrors, results); } return results; } finally { targetsCache.writeToDisk(); } }, ]; exports.createNodesV2 = exports.createNodes; async function createNodesInternal(configFile, options, context, targetsCache, pmc, hash) { const projectRoot = (0, path_1.dirname)(configFile); if (!targetsCache.has(hash)) { targetsCache.set(hash, buildExpoTargets(projectRoot, options, context, pmc)); } return { projects: { [projectRoot]: { targets: targetsCache.get(hash), }, }, }; } function buildExpoTargets(projectRoot, options, context, pmc) { const namedInputs = (0, internal_1.getNamedInputs)(projectRoot, context); const targets = { [options.startTargetName]: { executor: `@nx/expo:start`, continuous: true, }, [options.serveTargetName]: { command: `expo start --web`, continuous: true, options: { cwd: projectRoot, args: ['--clear'] }, }, [options.runIosTargetName]: { command: `expo run:ios`, continuous: true, options: { cwd: projectRoot }, }, [options.runAndroidTargetName]: { command: `expo run:android`, continuous: true, options: { cwd: projectRoot }, }, [options.exportTargetName]: { command: `expo export`, options: { cwd: projectRoot, args: ['--clear'] }, cache: true, dependsOn: [`^${options.exportTargetName}`], inputs: getInputs(namedInputs), outputs: [getOutputs(projectRoot, 'dist')], }, [options.installTargetName]: { executor: '@nx/expo:install', continuous: false, }, [options.prebuildTargetName]: { executor: `@nx/expo:prebuild`, continuous: false, }, [options.buildTargetName]: { executor: `@nx/expo:build`, continuous: false, }, [options.submitTargetName]: { command: `eas submit`, options: { cwd: projectRoot }, }, }; (0, internal_2.addBuildAndWatchDepsTargets)(context.workspaceRoot, projectRoot, targets, options, pmc); return targets; } function getAppConfig(configFilePath, context) { const resolvedPath = (0, path_1.join)(context.workspaceRoot, configFilePath); return (0, internal_1.loadConfigFile)(resolvedPath); } async function filterExpoConfigs(configFiles, context) { const preErrors = []; const candidates = await Promise.all(configFiles.map(async (configFile) => { try { const projectRoot = (0, path_1.dirname)(configFile); const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot)); if (!siblingFiles.includes('package.json') || !siblingFiles.includes('metro.config.js')) { return null; } 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 null; } return { configFile, projectRoot }; } catch (e) { preErrors.push([configFile, e]); return null; } })); return { entries: candidates.filter((c) => c !== null), preErrors, }; } function getInputs(namedInputs) { return [ ...('production' in namedInputs ? ['default', '^production'] : ['default', '^default']), { externalDependencies: ['expo'], }, ]; } function getOutputs(projectRoot, dir) { if (projectRoot === '.') { return `{projectRoot}/${dir}`; } else { return `{workspaceRoot}/${projectRoot}/${dir}`; } } function normalizeOptions(options) { options ??= {}; options.startTargetName ??= 'start'; options.serveTargetName ??= 'serve'; options.runIosTargetName ??= 'run-ios'; options.runAndroidTargetName ??= 'run-android'; options.exportTargetName ??= 'export'; options.prebuildTargetName ??= 'prebuild'; options.installTargetName ??= 'install'; options.buildTargetName ??= 'build'; options.submitTargetName ??= 'submit'; return options; }