chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
import { logShowProjectCommand } from '@nx/devkit/internal';
|
||||
import {
|
||||
ensurePackage,
|
||||
formatFiles,
|
||||
GeneratorCallback,
|
||||
joinPathFragments,
|
||||
readProjectConfiguration,
|
||||
runTasksInSerial,
|
||||
Tree,
|
||||
updateJson,
|
||||
updateProjectConfiguration,
|
||||
updateTsConfigsToJs,
|
||||
} from '@nx/devkit';
|
||||
import { configurationGenerator } from '@nx/jest';
|
||||
import { initGenerator as jsInitGenerator } from '@nx/js';
|
||||
import {
|
||||
addProjectToTsSolutionWorkspace,
|
||||
getTsConfigBaseOptions,
|
||||
shouldConfigureTsSolutionSetup,
|
||||
updateTsconfigFiles,
|
||||
sortPackageJsonFields,
|
||||
} from '@nx/js/internal';
|
||||
import { assertSupportedFrameworkVersion } from '../../utils/assert-supported-framework-version';
|
||||
import { nxVersion } from '../../utils/versions';
|
||||
import { e2eProjectGenerator } from '../e2e-project/e2e-project';
|
||||
import { initGenerator } from '../init/init';
|
||||
import { setupDockerGenerator } from '../setup-docker/setup-docker';
|
||||
import { Schema } from './schema';
|
||||
import {
|
||||
addAppFiles,
|
||||
addLintingToApplication,
|
||||
addProject,
|
||||
addProjectDependencies,
|
||||
addProxy,
|
||||
normalizeOptions,
|
||||
NormalizedSchema,
|
||||
} from './lib';
|
||||
|
||||
function updateTsConfigOptions(tree: Tree, options: NormalizedSchema) {
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateJson(tree, `${options.appProjectRoot}/tsconfig.json`, (json) => {
|
||||
if (options.rootProject) {
|
||||
return {
|
||||
compilerOptions: {
|
||||
...getTsConfigBaseOptions(tree),
|
||||
...json.compilerOptions,
|
||||
esModuleInterop: true,
|
||||
},
|
||||
...json,
|
||||
extends: undefined,
|
||||
exclude: ['node_modules', 'tmp'],
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...json,
|
||||
compilerOptions: {
|
||||
...json.compilerOptions,
|
||||
esModuleInterop: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function applicationGenerator(tree: Tree, schema: Schema) {
|
||||
return await applicationGeneratorInternal(tree, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
|
||||
export async function applicationGeneratorInternal(tree: Tree, schema: Schema) {
|
||||
assertSupportedFrameworkVersion(tree, schema.framework);
|
||||
|
||||
const tasks: GeneratorCallback[] = [];
|
||||
|
||||
const addTsPlugin = shouldConfigureTsSolutionSetup(
|
||||
tree,
|
||||
schema.addPlugin,
|
||||
schema.useTsSolution
|
||||
);
|
||||
const jsInitTask = await jsInitGenerator(tree, {
|
||||
...schema,
|
||||
tsConfigName: schema.rootProject ? 'tsconfig.json' : 'tsconfig.base.json',
|
||||
skipFormat: true,
|
||||
addTsPlugin,
|
||||
});
|
||||
tasks.push(jsInitTask);
|
||||
|
||||
const options = await normalizeOptions(tree, schema);
|
||||
|
||||
if (options.framework === 'nest') {
|
||||
// nx-ignore-next-line
|
||||
const { applicationGenerator } = ensurePackage('@nx/nest', nxVersion);
|
||||
const nestTasks = await applicationGenerator(tree, {
|
||||
...options,
|
||||
skipFormat: true,
|
||||
});
|
||||
tasks.push(nestTasks);
|
||||
|
||||
if (options.docker) {
|
||||
const dockerTask = await setupDockerGenerator(tree, {
|
||||
...options,
|
||||
project: options.name,
|
||||
skipFormat: true,
|
||||
});
|
||||
tasks.push(dockerTask);
|
||||
}
|
||||
return runTasksInSerial(
|
||||
...[
|
||||
...tasks,
|
||||
() => {
|
||||
logShowProjectCommand(options.name);
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const initTask = await initGenerator(tree, {
|
||||
...schema,
|
||||
skipFormat: true,
|
||||
});
|
||||
tasks.push(initTask);
|
||||
|
||||
const { installTask, frameworkDependencies } = addProjectDependencies(
|
||||
tree,
|
||||
options
|
||||
);
|
||||
tasks.push(installTask);
|
||||
|
||||
if (options.bundler === 'webpack') {
|
||||
const { webpackInitGenerator } = ensurePackage<
|
||||
typeof import('@nx/webpack')
|
||||
>('@nx/webpack', nxVersion);
|
||||
const webpackInitTask = await webpackInitGenerator(tree, {
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
skipFormat: true,
|
||||
addPlugin: options.addPlugin,
|
||||
});
|
||||
tasks.push(webpackInitTask);
|
||||
if (!options.skipPackageJson) {
|
||||
// Use CommonJS `require` rather than a dynamic ESM `import`:
|
||||
// `ensurePackage` makes the on-demand-installed package available via
|
||||
// `Module._initPaths`, which `require()` honors but ESM resolution does
|
||||
// not. Under nodenext, a dynamic `import()` is preserved as a true ESM
|
||||
// dynamic import, so it can't see the temp install.
|
||||
const {
|
||||
ensureDependencies,
|
||||
}: typeof import('@nx/webpack/internal') = require('@nx/webpack/internal');
|
||||
tasks.push(
|
||||
ensureDependencies(tree, {
|
||||
uiFramework: options.isNest ? 'none' : 'react',
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
addAppFiles(tree, options);
|
||||
addProject(tree, options, frameworkDependencies);
|
||||
|
||||
// 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 addProjectToTsSolutionWorkspace(tree, options.appProjectRoot);
|
||||
}
|
||||
|
||||
updateTsConfigOptions(tree, options);
|
||||
|
||||
if (options.linter === 'eslint') {
|
||||
const lintTask = await addLintingToApplication(tree, options);
|
||||
tasks.push(lintTask);
|
||||
}
|
||||
|
||||
if (options.unitTestRunner === 'jest') {
|
||||
const jestTask = await configurationGenerator(tree, {
|
||||
...options,
|
||||
project: options.name,
|
||||
setupFile: 'none',
|
||||
skipSerializers: true,
|
||||
supportTsx: options.js,
|
||||
testEnvironment: 'node',
|
||||
compiler: options.swcJest ? 'swc' : 'tsc',
|
||||
skipFormat: true,
|
||||
});
|
||||
tasks.push(jestTask);
|
||||
// There are no tests by default, so set `--passWithNoTests` to avoid test failure on new project.
|
||||
const projectConfig = readProjectConfiguration(tree, options.name);
|
||||
projectConfig.targets ??= {};
|
||||
projectConfig.targets.test = {
|
||||
...projectConfig.targets.test,
|
||||
options: {
|
||||
...projectConfig.targets.test?.options,
|
||||
passWithNoTests: true,
|
||||
},
|
||||
};
|
||||
updateProjectConfiguration(tree, options.name, projectConfig);
|
||||
} else {
|
||||
// No need for default spec file if unit testing is not setup.
|
||||
tree.delete(
|
||||
joinPathFragments(options.appProjectRoot, 'src/app/app.spec.ts')
|
||||
);
|
||||
}
|
||||
|
||||
if (options.e2eTestRunner === 'jest') {
|
||||
const e2eTask = await e2eProjectGenerator(tree, {
|
||||
...options,
|
||||
projectType: options.framework === 'none' ? 'cli' : 'server',
|
||||
name: options.rootProject ? 'e2e' : `${options.name}-e2e`,
|
||||
directory: options.rootProject ? 'e2e' : `${options.appProjectRoot}-e2e`,
|
||||
project: options.name,
|
||||
port: options.port,
|
||||
isNest: options.isNest,
|
||||
skipFormat: true,
|
||||
});
|
||||
tasks.push(e2eTask);
|
||||
}
|
||||
|
||||
if (options.js) {
|
||||
updateTsConfigsToJs(tree, { projectRoot: options.appProjectRoot });
|
||||
}
|
||||
|
||||
if (options.frontendProject) {
|
||||
addProxy(tree, options);
|
||||
}
|
||||
|
||||
if (options.docker) {
|
||||
const dockerTask = await setupDockerGenerator(tree, {
|
||||
...options,
|
||||
project: options.name,
|
||||
skipFormat: true,
|
||||
skipDockerPlugin: options.skipDockerPlugin ?? false,
|
||||
});
|
||||
|
||||
tasks.push(dockerTask);
|
||||
}
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
updateTsconfigFiles(
|
||||
tree,
|
||||
options.appProjectRoot,
|
||||
'tsconfig.app.json',
|
||||
{
|
||||
module: 'nodenext',
|
||||
moduleResolution: 'nodenext',
|
||||
},
|
||||
options.linter === 'eslint'
|
||||
? ['eslint.config.js', 'eslint.config.cjs', 'eslint.config.mjs']
|
||||
: undefined
|
||||
);
|
||||
}
|
||||
|
||||
sortPackageJsonFields(tree, options.appProjectRoot);
|
||||
|
||||
if (!options.skipFormat) {
|
||||
await formatFiles(tree);
|
||||
}
|
||||
|
||||
tasks.push(() => {
|
||||
logShowProjectCommand(options.name);
|
||||
});
|
||||
|
||||
return runTasksInSerial(...tasks);
|
||||
}
|
||||
|
||||
export default applicationGenerator;
|
||||
Reference in New Issue
Block a user