@nx/expo
Version:
178 lines (177 loc) • 6.88 kB
JavaScript
;
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;
}