@nx/react
Version:
192 lines (191 loc) • 8.29 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.applicationGenerator = applicationGenerator;
exports.applicationGeneratorInternal = applicationGeneratorInternal;
const tslib_1 = require("tslib");
const internal_1 = require("@nx/devkit/internal");
const assert_supported_react_version_1 = require("../../utils/assert-supported-react-version");
const devkit_1 = require("@nx/devkit");
const internal_2 = require("@nx/devkit/internal");
const js_1 = require("@nx/js");
const internal_3 = require("@nx/js/internal");
const create_ts_config_1 = require("../../utils/create-ts-config");
const init_1 = tslib_1.__importDefault(require("../init/init"));
const create_application_files_1 = require("./lib/create-application-files");
const update_jest_config_1 = require("./lib/update-jest-config");
const normalize_options_1 = require("./lib/normalize-options");
const add_project_1 = require("./lib/add-project");
const add_jest_1 = require("./lib/add-jest");
const add_routing_1 = require("./lib/add-routing");
const set_defaults_1 = require("./lib/set-defaults");
const add_linting_1 = require("./lib/add-linting");
const add_e2e_1 = require("./lib/add-e2e");
const install_common_dependencies_1 = require("./lib/install-common-dependencies");
const add_webpack_1 = require("./lib/bundlers/add-webpack");
const add_rspack_1 = require("./lib/bundlers/add-rspack");
const add_rsbuild_1 = require("./lib/bundlers/add-rsbuild");
const add_vite_1 = require("./lib/bundlers/add-vite");
async function applicationGenerator(tree, schema) {
return await applicationGeneratorInternal(tree, {
addPlugin: false,
useProjectJson: true,
...schema,
});
}
async function applicationGeneratorInternal(tree, schema) {
(0, assert_supported_react_version_1.assertSupportedReactVersion)(tree);
const tasks = [];
const addTsPlugin = (0, internal_3.shouldConfigureTsSolutionSetup)(tree, schema.addPlugin, schema.useTsSolution);
const jsInitTask = await (0, js_1.initGenerator)(tree, {
...schema,
tsConfigName: schema.rootProject ? 'tsconfig.json' : 'tsconfig.base.json',
skipFormat: true,
addTsPlugin,
formatter: schema.formatter,
platform: 'web',
});
tasks.push(jsInitTask);
const options = await (0, normalize_options_1.normalizeOptions)(tree, schema);
options.useReactRouter =
options.routing && options.bundler === 'vite'
? (options.useReactRouter ??
(await (0, internal_1.promptWhenInteractive)({
name: 'response',
message: 'Would you like to use react-router for server-side rendering?',
type: 'autocomplete',
choices: [
{
name: 'Yes',
message: 'I want to use react-router [ https://reactrouter.com/start/framework/routing ]',
},
{
name: 'No',
message: 'I do not want to use react-router for server-side rendering',
},
],
initial: 0,
}, { response: 'No' }).then((r) => r.response === 'Yes')))
: false;
const initTask = await (0, init_1.default)(tree, {
...options,
skipFormat: true,
useReactRouterPlugin: options.useReactRouter,
});
tasks.push(initTask);
if (!options.addPlugin) {
const nxJson = (0, devkit_1.readNxJson)(tree) ?? {};
const existing = findBuildDefault(nxJson.targetDefaults);
if (!existing) {
(0, internal_2.upsertTargetDefault)(tree, nxJson, {
target: 'build',
cache: true,
dependsOn: ['^build'],
});
(0, devkit_1.updateNxJson)(tree, nxJson);
}
else if (!existing.dependsOn) {
(0, internal_2.upsertTargetDefault)(tree, nxJson, {
target: 'build',
dependsOn: ['^build'],
});
(0, devkit_1.updateNxJson)(tree, nxJson);
}
}
if (options.bundler === 'webpack') {
await (0, add_webpack_1.initWebpack)(tree, options, tasks);
}
else if (options.bundler === 'rspack') {
await (0, add_rspack_1.initRspack)(tree, options, tasks);
}
else if (options.bundler === 'rsbuild') {
await (0, add_rsbuild_1.initRsbuild)(tree, options, tasks);
}
if (!options.rootProject) {
(0, create_ts_config_1.extractTsConfigBase)(tree);
}
await (0, create_application_files_1.createApplicationFiles)(tree, options);
(0, add_project_1.addProject)(tree, options);
// If we are using the new TS solution
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
if (options.isUsingTsSolutionConfig) {
await (0, internal_3.addProjectToTsSolutionWorkspace)(tree, options.appProjectRoot);
}
const lintTask = await (0, add_linting_1.addLinting)(tree, options);
tasks.push(lintTask);
if (options.bundler === 'vite') {
await (0, add_vite_1.setupViteConfiguration)(tree, options, tasks);
}
else if (options.bundler === 'rsbuild') {
await (0, add_rsbuild_1.setupRsbuildConfiguration)(tree, options, tasks);
}
if (options.bundler !== 'vite' && options.unitTestRunner === 'vitest') {
await (0, add_vite_1.setupVitestConfiguration)(tree, options, tasks);
}
if ((options.bundler === 'vite' || options.unitTestRunner === 'vitest') &&
options.inSourceTests) {
tree.delete((0, devkit_1.joinPathFragments)(options.appProjectRoot, `src/app/${options.fileName}.spec.tsx`));
}
const e2eTask = await (0, add_e2e_1.addE2e)(tree, options);
tasks.push(e2eTask);
if (options.unitTestRunner === 'jest') {
const jestTask = await (0, add_jest_1.addJest)(tree, options);
tasks.push(jestTask);
}
// Handle tsconfig.spec.json for jest or vitest
(0, update_jest_config_1.updateSpecConfig)(tree, options);
const commonDependencyTask = await (0, install_common_dependencies_1.installCommonDependencies)(tree, options);
tasks.push(commonDependencyTask);
if (!options.useReactRouter) {
const routingTask = (0, add_routing_1.addRouting)(tree, options);
tasks.push(routingTask);
}
(0, set_defaults_1.setDefaults)(tree, options);
if (options.useReactRouter) {
(0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.json'), (json) => {
const types = new Set(json.compilerOptions?.types || []);
types.add('@react-router/node');
types.add('node');
return {
...json,
compilerOptions: {
...json.compilerOptions,
jsx: 'react-jsx',
moduleResolution: 'bundler',
types: Array.from(types),
},
};
});
}
// Only for the new TS solution
(0, internal_3.updateTsconfigFiles)(tree, options.appProjectRoot, 'tsconfig.app.json', {
jsx: 'react-jsx',
module: 'esnext',
moduleResolution: 'bundler',
}, options.linter === 'eslint'
? ['eslint.config.js', 'eslint.config.cjs', 'eslint.config.mjs']
: undefined, options.useReactRouter ? 'app' : 'src');
(0, internal_3.sortPackageJsonFields)(tree, options.appProjectRoot);
if (!options.skipFormat) {
await (0, devkit_1.formatFiles)(tree);
}
tasks.push(() => {
(0, internal_1.logShowProjectCommand)(options.projectName);
});
return (0, devkit_1.runTasksInSerial)(...tasks);
}
function findBuildDefault(td) {
if (!td)
return undefined;
const value = td['build'];
if (value === undefined)
return undefined;
if (Array.isArray(value)) {
const found = value.find((e) => e.filter === undefined);
if (!found)
return undefined;
const { filter: _f, ...rest } = found;
return rest;
}
return value;
}
exports.default = applicationGenerator;