@nx/expo
Version: 
158 lines (157 loc) • 6.45 kB
JavaScript
;
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 devkit_internals_1 = require("nx/src/devkit-internals");
const config_utils_1 = require("@nx/devkit/src/utils/config-utils");
const util_1 = require("@nx/js/src/plugins/typescript/util");
const pmc = (0, devkit_1.getPackageManagerCommand)();
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, `expo-${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) => {
        devkit_1.logger.warn('`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.');
        const optionsHash = (0, devkit_internals_1.hashObject)(options);
        const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, `expo-${optionsHash}.hash`);
        const targetsCache = readTargetsCache(cachePath);
        return createNodesInternal(configFilePath, options, context, targetsCache);
    },
];
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] ??= buildExpoTargets(projectRoot, options, context);
    return {
        projects: {
            [projectRoot]: {
                targets: targetsCache[hash],
            },
        },
    };
}
function buildExpoTargets(projectRoot, options, context) {
    const namedInputs = (0, get_named_inputs_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',
        },
        [options.prebuildTargetName]: {
            executor: `@nx/expo:prebuild`,
        },
        [options.buildTargetName]: {
            executor: `@nx/expo:build`,
        },
        [options.submitTargetName]: {
            command: `eas submit`,
            options: { cwd: projectRoot },
        },
    };
    (0, util_1.addBuildAndWatchDepsTargets)(context.workspaceRoot, projectRoot, targets, options, pmc);
    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: ['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;
}