nx
Version:
231 lines (230 loc) โข 10.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.addNxToCraRepo = addNxToCraRepo;
const child_process_1 = require("child_process");
const node_fs_1 = require("node:fs");
const path_1 = require("path");
const fileutils_1 = require("../../../../utils/fileutils");
const output_1 = require("../../../../utils/output");
const package_manager_1 = require("../../../../utils/package-manager");
const check_for_custom_webpack_setup_1 = require("./check-for-custom-webpack-setup");
const check_for_uncommitted_changes_1 = require("./check-for-uncommitted-changes");
const clean_up_files_1 = require("./clean-up-files");
const read_name_from_package_json_1 = require("./read-name-from-package-json");
const rename_js_to_jsx_1 = require("./rename-js-to-jsx");
const tsconfig_setup_1 = require("./tsconfig-setup");
const write_craco_config_1 = require("./write-craco-config");
const write_vite_config_1 = require("./write-vite-config");
const write_vite_index_html_1 = require("./write-vite-index-html");
const connect_to_nx_cloud_1 = require("../../../connect/connect-to-nx-cloud");
async function addNxToCraRepo(options) {
if (!options.force) {
(0, check_for_uncommitted_changes_1.checkForUncommittedChanges)();
(0, check_for_custom_webpack_setup_1.checkForCustomWebpackSetup)();
}
output_1.output.log({ title: '๐ณ Nx initialization' });
const normalizedOptions = await normalizeOptions(options);
await reorgnizeWorkspaceStructure(normalizedOptions);
}
function installDependencies(options) {
const dependencies = [
'@testing-library/jest-dom',
'eslint-config-react-app',
'web-vitals',
'jest-watch-typeahead',
];
if (options.isVite) {
dependencies.push('vite', 'vitest', '@vitejs/plugin-react');
}
else {
dependencies.push('@craco/craco', 'cross-env', 'react-scripts', 'tsconfig-paths-webpack-plugin');
}
(0, child_process_1.execSync)(`${options.pmc.addDev} ${dependencies.join(' ')}`, {
stdio: [0, 1, 2],
windowsHide: true,
});
}
async function normalizeOptions(options) {
const packageManager = (0, package_manager_1.detectPackageManager)();
const pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager);
const appIsJs = !(0, fileutils_1.fileExists)(`tsconfig.json`);
const reactAppName = (0, read_name_from_package_json_1.readNameFromPackageJson)();
const packageJson = (0, fileutils_1.readJsonFile)((0, path_1.join)(process.cwd(), 'package.json'));
const deps = {
...packageJson.dependencies,
...packageJson.devDependencies,
};
const isCRA5 = /^[^~]?5/.test(deps['react-scripts']);
const npmVersion = (0, child_process_1.execSync)('npm -v', {
windowsHide: true,
}).toString();
// Should remove this check 04/2023 once Node 14 & npm 6 reach EOL
const npxYesFlagNeeded = !npmVersion.startsWith('6'); // npm 7 added -y flag to npx
const isVite = options.vite;
const isStandalone = !options.integrated;
const nxCloud = options.nxCloud ??
(options.interactive ? await (0, connect_to_nx_cloud_1.connectExistingRepoToNxCloudPrompt)() : false);
return {
...options,
nxCloud,
packageManager,
pmc,
appIsJs,
reactAppName,
isCRA5,
npxYesFlagNeeded,
isVite,
isStandalone,
};
}
/**
* - Create a temp workspace
* - Move all files to temp workspace
* - Add bundler to temp workspace
* - Move files back to root
* - Clean up unused files
*/
async function reorgnizeWorkspaceStructure(options) {
createTempWorkspace(options);
moveFilesToTempWorkspace(options);
await addBundler(options);
output_1.output.log({ title: '๐งถ Updating .gitignore file' });
(0, child_process_1.execSync)(`echo "node_modules" >> .gitignore`, {
stdio: [0, 1, 2],
windowsHide: true,
});
(0, child_process_1.execSync)(`echo "dist" >> .gitignore`, {
stdio: [0, 1, 2],
windowsHide: true,
});
process.chdir('..');
copyFromTempWorkspaceToRoot();
cleanUpUnusedFilesAndAddConfigFiles(options);
output_1.output.log({ title: '๐ Please be patient, one final step remaining!' });
output_1.output.log({ title: '๐ฆ Installing dependencies' });
installDependencies(options);
if (options.isVite) {
const indexPath = options.isStandalone
? 'index.html'
: (0, path_1.join)('apps', options.reactAppName, 'index.html');
const oldIndexPath = options.isStandalone
? (0, path_1.join)('public', 'index.html')
: (0, path_1.join)('apps', options.reactAppName, 'public', 'index.html');
output_1.output.note({
title: `A new ${indexPath} has been created. Compare it to the previous ${oldIndexPath} file and make any changes needed, then delete the previous file.`,
});
}
}
function createTempWorkspace(options) {
(0, node_fs_1.rmSync)('temp-workspace', { recursive: true, force: true });
(0, child_process_1.execSync)(`npx ${options.npxYesFlagNeeded ? '-y' : ''} create-nx-workspace@latest temp-workspace --appName=${options.reactAppName} --preset=react-monorepo --style=css --bundler=${options.isVite ? 'vite' : 'webpack'} --packageManager=${options.packageManager} ${options.nxCloud ? '--nxCloud=yes' : '--nxCloud=skip'} ${options.addE2e ? '--e2eTestRunner=playwright' : '--e2eTestRunner=none'}`, { stdio: [0, 1, 2], windowsHide: true });
output_1.output.log({ title: '๐ Welcome to Nx!' });
output_1.output.log({ title: '๐งน Clearing unused files' });
(0, node_fs_1.cpSync)((0, path_1.join)('temp-workspace', 'apps', options.reactAppName, 'project.json'), 'project.json', { recursive: true });
(0, node_fs_1.rmSync)((0, path_1.join)('temp-workspace', 'apps', options.reactAppName), {
recursive: true,
force: true,
});
(0, node_fs_1.rmSync)('node_modules', { recursive: true, force: true });
}
function copyPackageJsonDepsFromTempWorkspace() {
const repoRoot = process.cwd();
let rootPackageJson = (0, fileutils_1.readJsonFile)((0, path_1.join)(repoRoot, 'package.json'));
const tempWorkspacePackageJson = (0, fileutils_1.readJsonFile)((0, path_1.join)(repoRoot, 'temp-workspace', 'package.json'));
rootPackageJson = overridePackageDeps('dependencies', rootPackageJson, tempWorkspacePackageJson);
rootPackageJson = overridePackageDeps('devDependencies', rootPackageJson, tempWorkspacePackageJson);
rootPackageJson.scripts = {}; // remove existing scripts
(0, fileutils_1.writeJsonFile)((0, path_1.join)(repoRoot, 'package.json'), rootPackageJson);
(0, fileutils_1.writeJsonFile)((0, path_1.join)(repoRoot, 'temp-workspace', 'package.json'), rootPackageJson);
}
function overridePackageDeps(depConfigName, base, override) {
if (!base[depConfigName]) {
base[depConfigName] = override[depConfigName];
return base;
}
const deps = override[depConfigName];
Object.keys(deps).forEach((dep) => {
if (base.dependencies?.[dep]) {
delete base.dependencies[dep];
}
if (base.devDependencies?.[dep]) {
delete base.devDependencies[dep];
}
base[depConfigName][dep] = deps[dep];
});
return base;
}
function moveSync(src, dest) {
const destParentDir = (0, path_1.dirname)(dest);
(0, node_fs_1.mkdirSync)(destParentDir, { recursive: true });
(0, node_fs_1.rmSync)(dest, { recursive: true, force: true });
return (0, node_fs_1.renameSync)(src, dest);
}
function moveFilesToTempWorkspace(options) {
output_1.output.log({ title: '๐ Moving your React app in your new Nx workspace' });
copyPackageJsonDepsFromTempWorkspace();
const requiredCraFiles = [
'project.json',
'package.json',
'src',
'public',
options.appIsJs ? null : 'tsconfig.json',
options.packageManager === 'yarn' ? 'yarn.lock' : null,
options.packageManager === 'pnpm' ? 'pnpm-lock.yaml' : null,
options.packageManager === 'npm' ? 'package-lock.json' : null,
options.packageManager === 'bun' ? 'bun.lockb' : null,
];
const optionalCraFiles = ['README.md'];
const filesToMove = [...requiredCraFiles, ...optionalCraFiles].filter(Boolean);
filesToMove.forEach((f) => {
try {
moveSync(f, options.isStandalone
? (0, path_1.join)('temp-workspace', f)
: (0, path_1.join)('temp-workspace', 'apps', options.reactAppName, f));
}
catch (error) {
if (requiredCraFiles.includes(f)) {
throw error;
}
}
});
process.chdir('temp-workspace');
}
async function addBundler(options) {
if (options.isVite) {
output_1.output.log({ title: '๐งโ๐ง Setting up Vite' });
const { addViteCommandsToPackageScripts } = await Promise.resolve().then(() => require('./add-vite-commands-to-package-scripts'));
addViteCommandsToPackageScripts(options.reactAppName, options.isStandalone);
(0, write_vite_config_1.writeViteConfig)(options.reactAppName, options.isStandalone, options.appIsJs);
(0, write_vite_index_html_1.writeViteIndexHtml)(options.reactAppName, options.isStandalone, options.appIsJs);
await (0, rename_js_to_jsx_1.renameJsToJsx)(options.reactAppName, options.isStandalone);
}
else {
output_1.output.log({ title: '๐งโ๐ง Setting up craco + Webpack' });
const { addCracoCommandsToPackageScripts } = await Promise.resolve().then(() => require('./add-craco-commands-to-package-scripts'));
addCracoCommandsToPackageScripts(options.reactAppName, options.isStandalone);
(0, write_craco_config_1.writeCracoConfig)(options.reactAppName, options.isCRA5, options.isStandalone);
output_1.output.log({
title: '๐ฌ Skip CRA preflight check since Nx manages the monorepo',
});
(0, child_process_1.execSync)(`echo "SKIP_PREFLIGHT_CHECK=true" > .env`, {
stdio: [0, 1, 2],
windowsHide: true,
});
}
}
function copyFromTempWorkspaceToRoot() {
output_1.output.log({ title: '๐ Folder restructuring.' });
(0, node_fs_1.readdirSync)('temp-workspace').forEach((f) => {
moveSync((0, path_1.join)('temp-workspace', f), f);
});
}
function cleanUpUnusedFilesAndAddConfigFiles(options) {
output_1.output.log({ title: '๐งน Cleaning up.' });
(0, clean_up_files_1.cleanUpFiles)(options.reactAppName, options.isStandalone);
output_1.output.log({ title: "๐ Extend the app's tsconfig.json from the base" });
(0, tsconfig_setup_1.setupTsConfig)(options.reactAppName, options.isStandalone);
if (options.isStandalone) {
(0, node_fs_1.rmSync)('apps', { recursive: true, force: true });
}
}