feat(nx): improve the dev ergonomics of create-nx-workspace
This commit is contained in:
parent
6d6cbf8b0f
commit
6fd181f348
@ -11,6 +11,12 @@ ng generate ng-new ...
|
|||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
|
### appName
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Application name.
|
||||||
|
|
||||||
### commit
|
### commit
|
||||||
|
|
||||||
Default: `true`
|
Default: `true`
|
||||||
|
|||||||
@ -11,6 +11,12 @@ ng generate tao-new ...
|
|||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
|
### appName
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Application name.
|
||||||
|
|
||||||
### commit
|
### commit
|
||||||
|
|
||||||
Default: `true`
|
Default: `true`
|
||||||
|
|||||||
@ -40,7 +40,10 @@ const nxVersion = 'NX_VERSION';
|
|||||||
const angularCliVersion = 'ANGULAR_CLI_VERSION';
|
const angularCliVersion = 'ANGULAR_CLI_VERSION';
|
||||||
|
|
||||||
const parsedArgs = yargsParser(process.argv, {
|
const parsedArgs = yargsParser(process.argv, {
|
||||||
string: ['cli', 'preset'],
|
string: ['cli', 'preset', 'appName'],
|
||||||
|
alias: {
|
||||||
|
appName: 'app-name'
|
||||||
|
},
|
||||||
boolean: ['help']
|
boolean: ['help']
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -48,15 +51,18 @@ if (parsedArgs.help) {
|
|||||||
showHelp();
|
showHelp();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
validateInput(parsedArgs);
|
|
||||||
const packageManager = determinePackageManager();
|
const packageManager = determinePackageManager();
|
||||||
determinePreset(parsedArgs).then(preset => {
|
determineWorkspaceName(parsedArgs).then(name => {
|
||||||
|
determinePreset(parsedArgs).then(preset => {
|
||||||
|
return determineAppName(preset, parsedArgs).then(appName => {
|
||||||
return determineCli(preset, parsedArgs).then(cli => {
|
return determineCli(preset, parsedArgs).then(cli => {
|
||||||
const tmpDir = createSandbox(packageManager, cli);
|
const tmpDir = createSandbox(packageManager, cli);
|
||||||
createApp(tmpDir, cli, parsedArgs, preset);
|
createApp(tmpDir, cli, parsedArgs, name, preset, appName);
|
||||||
showNxWarning();
|
showNxWarning();
|
||||||
showCliWarning(preset, parsedArgs);
|
showCliWarning(preset, parsedArgs);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function showHelp() {
|
function showHelp() {
|
||||||
@ -73,6 +79,8 @@ function showHelp() {
|
|||||||
.map(o => '"' + o.value + '"')
|
.map(o => '"' + o.value + '"')
|
||||||
.join(', ')})
|
.join(', ')})
|
||||||
|
|
||||||
|
appName the name of the application created by some presets
|
||||||
|
|
||||||
cli CLI to power the Nx workspace (options: "nx", "angular")
|
cli CLI to power the Nx workspace (options: "nx", "angular")
|
||||||
|
|
||||||
[new workspace options] any 'new workspace' options
|
[new workspace options] any 'new workspace' options
|
||||||
@ -103,32 +111,46 @@ function determinePackageManager() {
|
|||||||
return packageManager;
|
return packageManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateInput(parsedArgs: any) {
|
function determineWorkspaceName(parsedArgs: any) {
|
||||||
const projectName = parsedArgs._[2];
|
const workspaceName = parsedArgs._[2];
|
||||||
|
|
||||||
if (!projectName) {
|
if (workspaceName) {
|
||||||
|
return Promise.resolve(workspaceName);
|
||||||
|
} else {
|
||||||
|
return inquirer
|
||||||
|
.prompt([
|
||||||
|
{
|
||||||
|
name: 'WorkspaceName',
|
||||||
|
message: `Workspace name (e.g., org name) `,
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.then(a => {
|
||||||
|
if (!a.WorkspaceName) {
|
||||||
output.error({
|
output.error({
|
||||||
title: 'A project name is required when creating a new workspace',
|
title: 'Invalid workspace name',
|
||||||
bodyLines: [
|
bodyLines: [`Workspace name cannot be empty`]
|
||||||
output.colors.gray('For example:'),
|
|
||||||
'',
|
|
||||||
`${output.colors.gray('>')} create-nx-workspace my-new-workspace`
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
return a.WorkspaceName;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return projectName;
|
return workspaceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
function determinePreset(parsedArgs: any): Promise<string> {
|
function determinePreset(parsedArgs: any): Promise<string> {
|
||||||
if (parsedArgs.preset) {
|
if (parsedArgs.preset) {
|
||||||
if (presetOptions.map(o => o.value).indexOf(parsedArgs.preset) === -1) {
|
if (presetOptions.map(o => o.value).indexOf(parsedArgs.preset) === -1) {
|
||||||
console.error(
|
output.error({
|
||||||
`Invalid preset. It must be one of the following: ${presetOptions
|
title: 'Invalid preset',
|
||||||
.map(o => '"' + o.value + '"')
|
bodyLines: [
|
||||||
.join(', ')}.`
|
`It must be one of the following:`,
|
||||||
);
|
'',
|
||||||
|
...presetOptions.map(o => o.value)
|
||||||
|
]
|
||||||
|
});
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve(parsedArgs.preset);
|
return Promise.resolve(parsedArgs.preset);
|
||||||
@ -148,6 +170,35 @@ function determinePreset(parsedArgs: any): Promise<string> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function determineAppName(preset: string, parsedArgs: any): Promise<string> {
|
||||||
|
if (preset === 'empty') {
|
||||||
|
return Promise.resolve('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsedArgs.appName) {
|
||||||
|
return Promise.resolve(parsedArgs.appName);
|
||||||
|
} else {
|
||||||
|
return inquirer
|
||||||
|
.prompt([
|
||||||
|
{
|
||||||
|
name: 'AppName',
|
||||||
|
message: `Application name `,
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.then(a => {
|
||||||
|
if (!a.AppName) {
|
||||||
|
output.error({
|
||||||
|
title: 'Invalid name',
|
||||||
|
bodyLines: [`Name cannot be empty`]
|
||||||
|
});
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
return a.AppName;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function determineCli(preset: string, parsedArgs: any) {
|
function determineCli(preset: string, parsedArgs: any) {
|
||||||
const angular = {
|
const angular = {
|
||||||
package: '@angular/cli',
|
package: '@angular/cli',
|
||||||
@ -163,9 +214,10 @@ function determineCli(preset: string, parsedArgs: any) {
|
|||||||
|
|
||||||
if (parsedArgs.cli) {
|
if (parsedArgs.cli) {
|
||||||
if (['nx', 'angular'].indexOf(parsedArgs.cli) === -1) {
|
if (['nx', 'angular'].indexOf(parsedArgs.cli) === -1) {
|
||||||
console.error(
|
output.error({
|
||||||
`Invalid cli. It must be one of the following: "nx", "angular".`
|
title: 'Invalid cli',
|
||||||
);
|
bodyLines: [`It must be one of the following:`, '', 'nx', 'angular']
|
||||||
|
});
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
return Promise.resolve(parsedArgs.cli === 'angular' ? angular : nx);
|
return Promise.resolve(parsedArgs.cli === 'angular' ? angular : nx);
|
||||||
@ -231,16 +283,22 @@ function createApp(
|
|||||||
tmpDir: string,
|
tmpDir: string,
|
||||||
cli: { command: string },
|
cli: { command: string },
|
||||||
parsedArgs: any,
|
parsedArgs: any,
|
||||||
preset: string
|
name: string,
|
||||||
|
preset: string,
|
||||||
|
appName: string
|
||||||
) {
|
) {
|
||||||
// creating the app itself
|
// creating the app itself
|
||||||
const args = process.argv
|
const args = [
|
||||||
.slice(2)
|
name,
|
||||||
|
...process.argv
|
||||||
|
.slice(parsedArgs._[2] ? 3 : 2)
|
||||||
.filter(a => !a.startsWith('--cli')) // not used by the new command
|
.filter(a => !a.startsWith('--cli')) // not used by the new command
|
||||||
.map(a => `"${a}"`)
|
.map(a => `"${a}"`)
|
||||||
.join(' ');
|
].join(' ');
|
||||||
|
|
||||||
const presetArg = parsedArgs.preset ? '' : ` --preset=${preset}`;
|
const presetArg = parsedArgs.preset
|
||||||
|
? ''
|
||||||
|
: ` --preset=${preset} --appName=${appName}`;
|
||||||
|
|
||||||
console.log(`new ${args}${presetArg} --collection=@nrwl/workspace`);
|
console.log(`new ${args}${presetArg} --collection=@nrwl/workspace`);
|
||||||
execSync(
|
execSync(
|
||||||
|
|||||||
@ -117,6 +117,10 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"appName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Application name."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -132,7 +132,7 @@ function connectFrontendAndApi(options: Schema) {
|
|||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const scope = options.npmScope ? options.npmScope : options.name;
|
const scope = options.npmScope;
|
||||||
const style = options.style ? options.style : 'css';
|
const style = options.style ? options.style : 'css';
|
||||||
host.overwrite(
|
host.overwrite(
|
||||||
`apps/${options.name}/src/app/app.component.ts`,
|
`apps/${options.name}/src/app/app.component.ts`,
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import { platform } from 'os';
|
|||||||
export interface Schema {
|
export interface Schema {
|
||||||
directory: string;
|
directory: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
appName: string;
|
||||||
npmScope?: string;
|
npmScope?: string;
|
||||||
skipInstall?: boolean;
|
skipInstall?: boolean;
|
||||||
skipGit?: boolean;
|
skipGit?: boolean;
|
||||||
@ -62,11 +63,15 @@ function createPresetTaskExecutor(cli: string, opts: Schema) {
|
|||||||
const args = [
|
const args = [
|
||||||
`g`,
|
`g`,
|
||||||
`@nrwl/workspace:preset`,
|
`@nrwl/workspace:preset`,
|
||||||
`--name=${opts.name}`,
|
`--name=${opts.appName}`,
|
||||||
opts.style ? `--style=${opts.style}` : null,
|
opts.style ? `--style=${opts.style}` : null,
|
||||||
opts.npmScope ? `--npmScope=${opts.npmScope}` : null,
|
opts.npmScope
|
||||||
|
? `--npmScope=${opts.npmScope}`
|
||||||
|
: `--npmScope=${opts.name}`,
|
||||||
opts.preset ? `--preset=${opts.preset}` : null
|
opts.preset ? `--preset=${opts.preset}` : null
|
||||||
].filter(e => !!e);
|
].filter(e => !!e);
|
||||||
|
|
||||||
|
console.log('here', path.join(process.cwd(), opts.directory));
|
||||||
return new Observable(obs => {
|
return new Observable(obs => {
|
||||||
spawn(executable, args, spawnOptions).on('close', (code: number) => {
|
spawn(executable, args, spawnOptions).on('close', (code: number) => {
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
|
|||||||
@ -117,6 +117,10 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"appName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Application name."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user