using `windowsHide: true` is causing an issue on windows: Ctrl + C handling isn't enabled and no `SIGINT` is sent to the child process when users exit the process. See https://github.com/nodejs/node/issues/29837 and https://github.com/nodejs/node-v0.x-archive/issues/5054 for reference. This will cause leftover processes throughout nx. This PR sets `windowsHide: false` everywhere except for the plugin workers and some short-lived utils. They `spawn` child processes but have explicit handling to make sure they kill themselves when the parent process dies, so the missing Ctrl + C handling doesn't cause issues. We will follow up to make sure any other culprits that still cause windows popups (especially when used through Nx Console) are handled. Leaving no leftover processes running is more important for now, though. Keep in mind the underlying tooling (like vite) might have some windows popups themselves that Nx will inherit.
179 lines
4.7 KiB
TypeScript
179 lines
4.7 KiB
TypeScript
import {
|
|
addDependenciesToPackageJson,
|
|
addProjectConfiguration,
|
|
formatFiles,
|
|
generateFiles,
|
|
GeneratorCallback,
|
|
joinPathFragments,
|
|
offsetFromRoot,
|
|
runTasksInSerial,
|
|
toJS,
|
|
Tree,
|
|
} from '@nx/devkit';
|
|
import { Schema } from './schema';
|
|
import nuxtInitGenerator from '../init/init';
|
|
import { normalizeOptions } from './lib/normalize-options';
|
|
import { createTsConfig } from '../../utils/create-ts-config';
|
|
import {
|
|
getRelativePathToRootTsConfig,
|
|
initGenerator as jsInitGenerator,
|
|
} from '@nx/js';
|
|
import { assertNotUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
|
import { updateGitIgnore } from '../../utils/update-gitignore';
|
|
import { Linter } from '@nx/eslint';
|
|
import { addE2e } from './lib/add-e2e';
|
|
import { addLinting } from '../../utils/add-linting';
|
|
import { addVitest } from './lib/add-vitest';
|
|
import { vueTestUtilsVersion, vitePluginVueVersion } from '@nx/vue';
|
|
import { ensureDependencies } from './lib/ensure-dependencies';
|
|
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
|
|
import { execSync } from 'node:child_process';
|
|
import {
|
|
getNxCloudAppOnBoardingUrl,
|
|
createNxCloudOnboardingURLForWelcomeApp,
|
|
} from 'nx/src/nx-cloud/utilities/onboarding';
|
|
|
|
export async function applicationGenerator(tree: Tree, schema: Schema) {
|
|
assertNotUsingTsSolutionSetup(tree, 'nuxt', 'application');
|
|
|
|
const tasks: GeneratorCallback[] = [];
|
|
|
|
const options = await normalizeOptions(tree, schema);
|
|
|
|
const projectOffsetFromRoot = offsetFromRoot(options.appProjectRoot);
|
|
|
|
const onBoardingStatus = await createNxCloudOnboardingURLForWelcomeApp(
|
|
tree,
|
|
options.nxCloudToken
|
|
);
|
|
|
|
const connectCloudUrl =
|
|
onBoardingStatus === 'unclaimed' &&
|
|
(await getNxCloudAppOnBoardingUrl(options.nxCloudToken));
|
|
|
|
const jsInitTask = await jsInitGenerator(tree, {
|
|
...schema,
|
|
tsConfigName: schema.rootProject ? 'tsconfig.json' : 'tsconfig.base.json',
|
|
skipFormat: true,
|
|
});
|
|
tasks.push(jsInitTask);
|
|
tasks.push(ensureDependencies(tree, options));
|
|
|
|
addProjectConfiguration(tree, options.projectName, {
|
|
root: options.appProjectRoot,
|
|
projectType: 'application',
|
|
sourceRoot: `${options.appProjectRoot}/src`,
|
|
targets: {},
|
|
});
|
|
|
|
generateFiles(
|
|
tree,
|
|
joinPathFragments(__dirname, './files/base'),
|
|
options.appProjectRoot,
|
|
{
|
|
...options,
|
|
offsetFromRoot: projectOffsetFromRoot,
|
|
title: options.projectName,
|
|
dot: '.',
|
|
tmpl: '',
|
|
style: options.style,
|
|
projectRoot: options.appProjectRoot,
|
|
hasVitest: options.unitTestRunner === 'vitest',
|
|
}
|
|
);
|
|
|
|
generateFiles(
|
|
tree,
|
|
joinPathFragments(__dirname, './files/nx-welcome', onBoardingStatus),
|
|
options.appProjectRoot,
|
|
{
|
|
...options,
|
|
connectCloudUrl,
|
|
offsetFromRoot: projectOffsetFromRoot,
|
|
title: options.projectName,
|
|
dot: '.',
|
|
tmpl: '',
|
|
style: options.style,
|
|
projectRoot: options.appProjectRoot,
|
|
hasVitest: options.unitTestRunner === 'vitest',
|
|
}
|
|
);
|
|
|
|
if (options.style === 'none') {
|
|
tree.delete(
|
|
joinPathFragments(options.appProjectRoot, `src/assets/css/styles.none`)
|
|
);
|
|
}
|
|
|
|
createTsConfig(
|
|
tree,
|
|
{
|
|
projectRoot: options.appProjectRoot,
|
|
rootProject: options.rootProject,
|
|
unitTestRunner: options.unitTestRunner,
|
|
},
|
|
getRelativePathToRootTsConfig(tree, options.appProjectRoot)
|
|
);
|
|
|
|
updateGitIgnore(tree);
|
|
|
|
tasks.push(
|
|
await addLinting(tree, {
|
|
projectName: options.projectName,
|
|
projectRoot: options.appProjectRoot,
|
|
linter: options.linter ?? Linter.EsLint,
|
|
unitTestRunner: options.unitTestRunner,
|
|
rootProject: options.rootProject,
|
|
})
|
|
);
|
|
|
|
if (options.unitTestRunner === 'vitest') {
|
|
tasks.push(
|
|
addDependenciesToPackageJson(
|
|
tree,
|
|
{},
|
|
{
|
|
'@vue/test-utils': vueTestUtilsVersion,
|
|
'@vitejs/plugin-vue': vitePluginVueVersion,
|
|
}
|
|
)
|
|
);
|
|
|
|
tasks.push(await addVitest(tree, options));
|
|
}
|
|
|
|
const nuxtInitTask = await nuxtInitGenerator(tree, {
|
|
...options,
|
|
skipFormat: true,
|
|
});
|
|
tasks.push(nuxtInitTask);
|
|
|
|
tasks.push(await addE2e(tree, options));
|
|
|
|
if (options.js) toJS(tree);
|
|
|
|
if (!options.skipFormat) await formatFiles(tree);
|
|
|
|
tasks.push(() => {
|
|
try {
|
|
execSync(`npx -y nuxi prepare`, {
|
|
cwd: options.appProjectRoot,
|
|
|
|
windowsHide: false,
|
|
});
|
|
} catch (e) {
|
|
console.error(
|
|
`Failed to run \`nuxi prepare\` in "${options.appProjectRoot}". Please run the command manually.`
|
|
);
|
|
}
|
|
});
|
|
|
|
tasks.push(() => {
|
|
logShowProjectCommand(options.projectName);
|
|
});
|
|
|
|
return runTasksInSerial(...tasks);
|
|
}
|
|
|
|
export default applicationGenerator;
|