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.

187 lines (186 loc) • 8.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = update; const devkit_1 = require("@nx/devkit"); /** * Update Expo splash screen configuration to use the new expo-splash-screen plugin format. * This migration handles the transition from the legacy splash screen configuration * to the new plugin-based format introduced in Expo SDK 53+. */ function update(tree) { const projects = (0, devkit_1.getProjects)(tree); for (const [projectName, config] of projects.entries()) { // Only process Expo projects if (config.projectType !== 'application' || !isExpoProject(tree, config.root)) { continue; } const appConfigPath = (0, devkit_1.joinPathFragments)(config.root, 'app.json'); const appConfigTsPath = (0, devkit_1.joinPathFragments)(config.root, 'app.config.ts'); const appConfigJsPath = (0, devkit_1.joinPathFragments)(config.root, 'app.config.js'); // Check which config file exists let configPath = null; if (tree.exists(appConfigPath)) { configPath = appConfigPath; } else if (tree.exists(appConfigTsPath)) { configPath = appConfigTsPath; } else if (tree.exists(appConfigJsPath)) { configPath = appConfigJsPath; } if (!configPath) { continue; } // Handle JSON config files if (configPath.endsWith('.json')) { updateJsonSplashScreenConfig(tree, configPath, projectName); } else { // Handle JS/TS config files updateJsConfigSplashScreenConfig(tree, configPath, projectName); } } } function isExpoProject(tree, projectRoot) { const packageJsonPath = (0, devkit_1.joinPathFragments)(projectRoot, 'package.json'); if (!tree.exists(packageJsonPath)) { return false; } try { const packageJson = (0, devkit_1.readJson)(tree, packageJsonPath); return (packageJson.dependencies?.expo || packageJson.devDependencies?.expo || packageJson.dependencies?.['expo-splash-screen'] || packageJson.devDependencies?.['expo-splash-screen']); } catch { return false; } } function updateJsonSplashScreenConfig(tree, configPath, projectName) { try { (0, devkit_1.updateJson)(tree, configPath, (config) => { if (config.expo?.splash) { const oldSplash = config.expo.splash; // Convert legacy splash configuration to plugin format const splashPluginConfig = {}; // Map legacy properties to plugin format if (oldSplash.image || oldSplash.imageUrl) { splashPluginConfig.image = oldSplash.image || oldSplash.imageUrl; } if (oldSplash.backgroundColor) { splashPluginConfig.backgroundColor = oldSplash.backgroundColor; } if (oldSplash.resizeMode) { splashPluginConfig.resizeMode = oldSplash.resizeMode; } if (oldSplash.tabletImage) { splashPluginConfig.tabletImage = oldSplash.tabletImage; } if (oldSplash.dark) { splashPluginConfig.dark = oldSplash.dark; } // Add width property if image exists (common requirement) if (splashPluginConfig.image && !splashPluginConfig.imageWidth) { splashPluginConfig.imageWidth = 200; // Default width } // Initialize plugins array if it doesn't exist if (!config.expo.plugins) { config.expo.plugins = []; } // Check if expo-splash-screen plugin already exists const existingPluginIndex = config.expo.plugins.findIndex((plugin) => plugin === 'expo-splash-screen' || (Array.isArray(plugin) && plugin[0] === 'expo-splash-screen')); if (existingPluginIndex !== -1) { // Update existing plugin configuration config.expo.plugins[existingPluginIndex] = [ 'expo-splash-screen', splashPluginConfig, ]; } else { // Add new plugin configuration config.expo.plugins.push(['expo-splash-screen', splashPluginConfig]); } // Remove legacy splash configuration delete config.expo.splash; devkit_1.logger.info(`Migrated splash screen configuration to plugin format for ${projectName}`); } return config; }); } catch (error) { devkit_1.logger.warn(`Failed to update splash screen configuration for ${projectName}: ${error}`); } } function updateJsConfigSplashScreenConfig(tree, configPath, projectName) { try { const content = tree.read(configPath, 'utf-8'); // Check if the file contains legacy splash screen configuration if (content.includes('splash:') && !content.includes('plugins:')) { let updatedContent = content; // Transform splash configuration to plugin format // This is a basic transformation - for complex configs, manual review may be needed const splashRegex = /splash\s*:\s*{([^}]*)}/gs; const match = splashRegex.exec(content); if (match) { const splashConfig = match[1]; // Extract properties from splash config const imageMatch = splashConfig.match(/image\s*:\s*['"`]([^'"`]+)['"`]/); const imageUrlMatch = splashConfig.match(/imageUrl\s*:\s*['"`]([^'"`]+)['"`]/); const backgroundColorMatch = splashConfig.match(/backgroundColor\s*:\s*['"`]([^'"`]+)['"`]/); const resizeModeMatch = splashConfig.match(/resizeMode\s*:\s*['"`]([^'"`]+)['"`]/); // Build plugin configuration const pluginConfig = []; if (imageMatch || imageUrlMatch) { const imageValue = imageMatch ? imageMatch[1] : imageUrlMatch[1]; pluginConfig.push(` image: '${imageValue}'`); pluginConfig.push(` imageWidth: 200`); } if (backgroundColorMatch) { pluginConfig.push(` backgroundColor: '${backgroundColorMatch[1]}'`); } if (resizeModeMatch) { pluginConfig.push(` resizeMode: '${resizeModeMatch[1]}'`); } if (pluginConfig.length > 0) { const pluginConfigString = `plugins: [ [ 'expo-splash-screen', { ${pluginConfig.join(',\n')} } ] ]`; // Replace splash config with plugin config updatedContent = updatedContent.replace(splashRegex, pluginConfigString); // Add migration comment const migrationComment = ` /* * Note: Splash screen configuration has been migrated to use expo-splash-screen plugin. * Please review the generated configuration and adjust as needed. * For more information, see: https://docs.expo.dev/develop/user-interface/splash-screen/ */ `; if (!content.includes('migrated to use expo-splash-screen plugin')) { const lines = updatedContent.split('\n'); const importEndIndex = lines.findIndex((line) => !line.trim().startsWith('import') && !line.trim().startsWith('//') && !line.trim().startsWith('/*') && line.trim() !== ''); if (importEndIndex !== -1) { lines.splice(importEndIndex, 0, migrationComment); updatedContent = lines.join('\n'); } } tree.write(configPath, updatedContent); devkit_1.logger.info(`Migrated splash screen configuration to plugin format for ${projectName}`); } } } } catch (error) { devkit_1.logger.warn(`Failed to update JS/TS config for ${projectName}: ${error}`); } }