@nx/expo
Version:
220 lines (219 loc) • 8.86 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.expoLibraryGenerator = expoLibraryGenerator;
exports.expoLibraryGeneratorInternal = expoLibraryGeneratorInternal;
const tslib_1 = require("tslib");
const internal_1 = require("@nx/devkit/internal");
const devkit_1 = require("@nx/devkit");
const js_1 = require("@nx/js");
const init_1 = tslib_1.__importDefault(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 internal_2 = require("@nx/js/internal");
const internal_3 = require("@nx/react/internal");
const component_1 = require("../component/component");
const path_1 = require("path");
const version_utils_1 = require("../../utils/version-utils");
const versions_1 = require("../../utils/versions");
async function expoLibraryGenerator(host, schema) {
return await expoLibraryGeneratorInternal(host, {
addPlugin: false,
useProjectJson: true,
...schema,
});
}
async function expoLibraryGeneratorInternal(host, schema) {
(0, versions_1.assertSupportedExpoVersion)(host);
const tasks = [];
const addTsPlugin = (0, internal_2.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, internal_2.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, internal_1.getRelativeCwd)();
const path = (0, devkit_1.joinPathFragments)(options.projectRoot, 'src/lib', options.js ? `${options.fileName}.js` : 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,
});
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, internal_2.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, internal_2.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, internal_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, internal_3.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;