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.

220 lines (219 loc) • 9.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.expoLibraryGenerator = expoLibraryGenerator; exports.expoLibraryGeneratorInternal = expoLibraryGeneratorInternal; const devkit_1 = require("@nx/devkit"); const js_1 = require("@nx/js"); const init_1 = require("../init/init"); const add_linting_1 = require("../../utils/add-linting"); const add_jest_1 = require("../../utils/jest/add-jest"); const normalize_options_1 = require("./lib/normalize-options"); const ensure_dependencies_1 = require("../../utils/ensure-dependencies"); const init_root_babel_config_1 = require("../../utils/init-root-babel-config"); const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-project-command"); const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup"); const sort_fields_1 = require("@nx/js/src/utils/package-json/sort-fields"); const add_rollup_build_target_1 = require("@nx/react/src/generators/library/lib/add-rollup-build-target"); const artifact_name_and_directory_utils_1 = require("@nx/devkit/src/generators/artifact-name-and-directory-utils"); const component_1 = require("../component/component"); const path_1 = require("path"); const version_utils_1 = require("../../utils/version-utils"); async function expoLibraryGenerator(host, schema) { return await expoLibraryGeneratorInternal(host, { addPlugin: false, useProjectJson: true, ...schema, }); } async function expoLibraryGeneratorInternal(host, schema) { const tasks = []; const addTsPlugin = (0, ts_solution_setup_1.shouldConfigureTsSolutionSetup)(host, schema.addPlugin); const jsInitTask = await (0, js_1.initGenerator)(host, { ...schema, addTsPlugin, skipFormat: true, }); tasks.push(jsInitTask); const options = await (0, normalize_options_1.normalizeOptions)(host, schema); if (options.publishable === true && !schema.importPath) { throw new Error(`For publishable libs you have to provide a proper "--importPath" which needs to be a valid npm package name (e.g. my-awesome-lib or @myorg/my-lib)`); } if (options.isUsingTsSolutionConfig) { await (0, ts_solution_setup_1.addProjectToTsSolutionWorkspace)(host, options.projectRoot); } const initTask = await (0, init_1.default)(host, { ...options, skipFormat: true }); tasks.push(initTask); if (!options.skipPackageJson) { tasks.push(await (0, ensure_dependencies_1.ensureDependencies)(host, options.unitTestRunner)); } (0, init_root_babel_config_1.initRootBabelConfig)(host); createFiles(host, options); const addProjectTask = await addProject(host, options); if (addProjectTask) { tasks.push(addProjectTask); } const lintTask = await (0, add_linting_1.addLinting)(host, { ...options, projectName: options.projectName, tsConfigPaths: [ (0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.lib.json'), ], }); tasks.push(lintTask); const relativeCwd = (0, artifact_name_and_directory_utils_1.getRelativeCwd)(); const path = (0, devkit_1.joinPathFragments)(options.projectRoot, 'src/lib', options.fileName); const componentTask = await (0, component_1.expoComponentGenerator)(host, { path: relativeCwd ? (0, path_1.relative)(relativeCwd, path) : path, skipTests: options.unitTestRunner === 'none', export: true, skipFormat: true, js: options.js, }); tasks.push(() => componentTask); if (!options.skipTsConfig && !options.isUsingTsSolutionConfig) { (0, js_1.addTsConfigPath)(host, options.importPath, [ (0, devkit_1.joinPathFragments)(options.projectRoot, options.js ? './src/index.js' : './src/index.ts'), ]); } (0, ts_solution_setup_1.updateTsconfigFiles)(host, options.projectRoot, 'tsconfig.lib.json', { jsx: 'react-jsx', module: 'esnext', moduleResolution: 'bundler', }, options.linter === 'eslint' ? ['eslint.config.js', 'eslint.config.cjs', 'eslint.config.mjs'] : undefined); // Update Jest tsconfig after general tsconfig updates to ensure Jest resolver configuration is preserved if (options.unitTestRunner === 'jest') { const jestTask = await (0, add_jest_1.addJest)(host, options.unitTestRunner, options.projectName, options.projectRoot, options.js, options.skipPackageJson, options.addPlugin); tasks.push(jestTask); } (0, sort_fields_1.sortPackageJsonFields)(host, options.projectRoot); if (!options.skipFormat) { await (0, devkit_1.formatFiles)(host); } // Always run install to link packages. if (options.isUsingTsSolutionConfig) { tasks.push(() => (0, devkit_1.installPackagesTask)(host, true)); } tasks.push(() => { (0, log_show_project_command_1.logShowProjectCommand)(options.projectName); }); return (0, devkit_1.runTasksInSerial)(...tasks); } async function addProject(host, options) { const versions = await (0, version_utils_1.getExpoDependenciesVersionsToInstall)(host); const project = { root: options.projectRoot, sourceRoot: (0, devkit_1.joinPathFragments)(options.projectRoot, 'src'), projectType: 'library', tags: options.parsedTags, targets: {}, }; let packageJson = { name: options.importPath, version: '0.0.1', peerDependencies: { react: versions.react, 'react-native': versions.reactNative, }, }; if (options.isUsingTsSolutionConfig) { packageJson = { ...packageJson, ...determineEntryFields(options), files: options.publishable ? ['dist', '!**/*.tsbuildinfo'] : undefined, }; } if (!options.useProjectJson) { if (options.projectName !== options.importPath) { packageJson.nx = { name: options.projectName }; } if (options.parsedTags?.length) { packageJson.nx ??= {}; packageJson.nx.tags = options.parsedTags; } } else { (0, devkit_1.addProjectConfiguration)(host, options.projectName, project); } if (!options.useProjectJson || options.isUsingTsSolutionConfig || options.publishable || options.buildable) { (0, devkit_1.writeJson)(host, (0, devkit_1.joinPathFragments)(options.projectRoot, 'package.json'), packageJson); } if (options.publishable || options.buildable) { const external = new Set([ 'react/jsx-runtime', 'react-native', 'react', 'react-dom', ]); const rollupTask = await (0, add_rollup_build_target_1.addRollupBuildTarget)(host, { ...options, name: options.projectName, format: ['cjs', 'esm'], style: 'none', skipFormat: true, }, external); (0, devkit_1.updateJson)(host, `${options.projectRoot}/package.json`, (json) => { json.peerDependencies = { ...json.peerDependencies, react: versions.react, 'react-native': versions.reactNative, }; return json; }); return rollupTask; } return () => { }; } function updateTsConfig(tree, options) { (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.json'), (json) => { if (options.strict) { json.compilerOptions = { ...json.compilerOptions, forceConsistentCasingInFileNames: true, strict: true, noImplicitReturns: true, noFallthroughCasesInSwitch: true, }; } return json; }); } function createFiles(host, options) { (0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, './files/lib'), options.projectRoot, { ...options, tmpl: '', offsetFromRoot: (0, devkit_1.offsetFromRoot)(options.projectRoot), rootTsConfigPath: (0, js_1.getRelativePathToRootTsConfig)(host, options.projectRoot), }); if (options.js) { (0, devkit_1.toJS)(host); } updateTsConfig(host, options); } function determineEntryFields(options) { if (options.buildable || options.publishable || !options.isUsingTsSolutionConfig) { // For buildable libraries, the entries are configured by the bundler (i.e. Rollup). return undefined; } return { main: options.js ? './src/index.js' : './src/index.ts', types: options.js ? './src/index.js' : './src/index.ts', exports: { '.': options.js ? './src/index.js' : { types: './src/index.ts', import: './src/index.ts', default: './src/index.ts', }, './package.json': './package.json', }, }; } exports.default = expoLibraryGenerator;