feat(vue): add nuxt as cnw vue framework (#20626)

This commit is contained in:
Katerina Skroumpelou 2023-12-11 10:50:56 +02:00 committed by GitHub
parent 410c1369c9
commit cec0994cd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 94 additions and 95 deletions

View File

@ -139,7 +139,7 @@ Package manager to use
Type: `string` Type: `string`
Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "vue-monorepo", "vue-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "vue-monorepo", "vue-standalone", "nuxt", "nuxt-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
### routing ### routing

View File

@ -139,7 +139,7 @@ Package manager to use
Type: `string` Type: `string`
Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "vue-monorepo", "vue-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "vue-monorepo", "vue-standalone", "nuxt", "nuxt-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
### routing ### routing

View File

@ -222,6 +222,7 @@ export function runCreateWorkspace(
nextAppDir, nextAppDir,
e2eTestRunner, e2eTestRunner,
ssr, ssr,
framework,
}: { }: {
preset: string; preset: string;
appName?: string; appName?: string;
@ -239,6 +240,7 @@ export function runCreateWorkspace(
nextAppDir?: boolean; nextAppDir?: boolean;
e2eTestRunner?: 'cypress' | 'playwright' | 'jest' | 'detox' | 'none'; e2eTestRunner?: 'cypress' | 'playwright' | 'jest' | 'detox' | 'none';
ssr?: boolean; ssr?: boolean;
framework?: string;
} }
) { ) {
projName = name; projName = name;
@ -288,6 +290,10 @@ export function runCreateWorkspace(
command += ` --e2eTestRunner=${e2eTestRunner}`; command += ` --e2eTestRunner=${e2eTestRunner}`;
} }
if (framework) {
command += ` --framework=${framework}`;
}
if (extraArgs) { if (extraArgs) {
command += ` ${extraArgs}`; command += ` ${extraArgs}`;
} }

View File

@ -448,7 +448,7 @@ describe('create-nx-workspace', () => {
expectCodeIsFormatted(); expectCodeIsFormatted();
}); });
it('should be able to create an vue monorepo', () => { it('should be able to create a vue monorepo', () => {
const wsName = uniq('vue'); const wsName = uniq('vue');
const appName = uniq('app'); const appName = uniq('app');
runCreateWorkspace(wsName, { runCreateWorkspace(wsName, {
@ -460,6 +460,38 @@ describe('create-nx-workspace', () => {
}); });
expectCodeIsFormatted(); expectCodeIsFormatted();
}); });
it('should create a workspace with a single nuxt app at the root', () => {
const wsName = uniq('nuxt');
runCreateWorkspace(wsName, {
preset: 'nuxt-standalone',
appName: wsName,
style: 'css',
packageManager,
e2eTestRunner: 'none',
});
checkFilesExist('package.json');
checkFilesExist('project.json');
checkFilesExist('nuxt.config.ts');
checkFilesExist('src/app.vue');
checkFilesExist('src/pages/index.vue');
expectCodeIsFormatted();
});
it('should be able to create a nuxt monorepo', () => {
const wsName = uniq('nuxt');
const appName = uniq('app');
runCreateWorkspace(wsName, {
preset: 'nuxt',
appName,
style: 'css',
packageManager,
e2eTestRunner: 'none',
});
expectCodeIsFormatted();
});
}); });
describe('create-nx-workspace parent folder', () => { describe('create-nx-workspace parent folder', () => {

View File

@ -68,14 +68,7 @@ interface VueArguments extends BaseArguments {
stack: 'vue'; stack: 'vue';
workspaceType: 'standalone' | 'integrated'; workspaceType: 'standalone' | 'integrated';
appName: string; appName: string;
style: string; framework: 'none' | 'nuxt';
e2eTestRunner: 'none' | 'cypress' | 'playwright';
}
interface NuxtArguments extends BaseArguments {
stack: 'nuxt';
workspaceType: 'standalone' | 'integrated';
appName: string;
style: string; style: string;
e2eTestRunner: 'none' | 'cypress' | 'playwright'; e2eTestRunner: 'none' | 'cypress' | 'playwright';
} }
@ -97,7 +90,6 @@ type Arguments =
| ReactArguments | ReactArguments
| AngularArguments | AngularArguments
| VueArguments | VueArguments
| NuxtArguments
| NodeArguments | NodeArguments
| UnknownStackArguments; | UnknownStackArguments;
@ -122,8 +114,6 @@ export const commandsObject: yargs.Argv<Arguments> = yargs
describe: chalk.dim`Customizes the initial content of your workspace. Default presets include: [${Object.values( describe: chalk.dim`Customizes the initial content of your workspace. Default presets include: [${Object.values(
Preset Preset
) )
// TODO(katerina): Remove this option when @nx/nuxt is released.
.filter((p) => p !== Preset.NuxtStandalone && p !== Preset.Nuxt)
.map((p) => `"${p}"`) .map((p) => `"${p}"`)
.join( .join(
', ' ', '
@ -375,7 +365,7 @@ async function determineFolder(
async function determineStack( async function determineStack(
parsedArgs: yargs.Arguments<Arguments> parsedArgs: yargs.Arguments<Arguments>
): Promise<'none' | 'react' | 'angular' | 'vue' | 'node' | 'nuxt' | 'unknown'> { ): Promise<'none' | 'react' | 'angular' | 'vue' | 'node' | 'unknown'> {
if (parsedArgs.preset) { if (parsedArgs.preset) {
switch (parsedArgs.preset) { switch (parsedArgs.preset) {
case Preset.Angular: case Preset.Angular:
@ -390,10 +380,9 @@ async function determineStack(
return 'react'; return 'react';
case Preset.VueStandalone: case Preset.VueStandalone:
case Preset.VueMonorepo: case Preset.VueMonorepo:
return 'vue';
case Preset.NuxtStandalone:
case Preset.Nuxt: case Preset.Nuxt:
return 'nuxt'; case Preset.NuxtStandalone:
return 'vue';
case Preset.Nest: case Preset.Nest:
case Preset.NodeStandalone: case Preset.NodeStandalone:
case Preset.Express: case Preset.Express:
@ -429,7 +418,7 @@ async function determineStack(
}, },
{ {
name: `vue`, name: `vue`,
message: `Vue: Configures a Vue application with modern tooling.`, message: `Vue: Configures a Vue application with your framework of choice.`,
}, },
{ {
name: `angular`, name: `angular`,
@ -458,8 +447,6 @@ async function determinePresetOptions(
return determineAngularOptions(parsedArgs); return determineAngularOptions(parsedArgs);
case 'vue': case 'vue':
return determineVueOptions(parsedArgs); return determineVueOptions(parsedArgs);
case 'nuxt':
return determineNuxtOptions(parsedArgs);
case 'node': case 'node':
return determineNodeOptions(parsedArgs); return determineNodeOptions(parsedArgs);
default: default:
@ -640,85 +627,35 @@ async function determineVueOptions(
if (parsedArgs.preset) { if (parsedArgs.preset) {
preset = parsedArgs.preset; preset = parsedArgs.preset;
if (preset === Preset.VueStandalone || preset === Preset.NuxtStandalone) {
appName = parsedArgs.appName ?? parsedArgs.name;
} else {
appName = await determineAppName(parsedArgs);
}
} else { } else {
const workspaceType = await determineStandaloneOrMonorepo(); const workspaceType = await determineStandaloneOrMonorepo();
if (workspaceType === 'standalone') { if (workspaceType === 'standalone') {
preset = Preset.VueStandalone; appName = parsedArgs.appName ?? parsedArgs.name;
} else { } else {
preset = Preset.VueMonorepo; appName = await determineAppName(parsedArgs);
} }
} const framework = await determineVueFramework(parsedArgs);
if (preset === Preset.VueStandalone) { if (framework === 'nuxt') {
appName = parsedArgs.appName ?? parsedArgs.name; if (workspaceType === 'standalone') {
} else { preset = Preset.NuxtStandalone;
appName = await determineAppName(parsedArgs); } else {
} preset = Preset.Nuxt;
}
e2eTestRunner = await determineE2eTestRunner(parsedArgs);
if (parsedArgs.style) {
style = parsedArgs.style;
} else {
const reply = await enquirer.prompt<{ style: string }>([
{
name: 'style',
message: `Default stylesheet format`,
initial: 'css' as any,
type: 'autocomplete',
choices: [
{
name: 'css',
message: 'CSS',
},
{
name: 'scss',
message: 'SASS(.scss) [ http://sass-lang.com ]',
},
{
name: 'less',
message: 'LESS [ http://lesscss.org ]',
},
{
name: 'none',
message: 'None',
},
],
},
]);
style = reply.style;
}
return { preset, style, appName, e2eTestRunner };
}
async function determineNuxtOptions(
parsedArgs: yargs.Arguments<NuxtArguments>
): Promise<Partial<Arguments>> {
let preset: Preset;
let style: undefined | string = undefined;
let appName: string;
let e2eTestRunner: undefined | 'none' | 'cypress' | 'playwright' = undefined;
if (parsedArgs.preset) {
preset = parsedArgs.preset;
} else {
const workspaceType = await determineStandaloneOrMonorepo();
if (workspaceType === 'standalone') {
preset = Preset.NuxtStandalone;
} else { } else {
preset = Preset.Nuxt; if (workspaceType === 'standalone') {
preset = Preset.VueStandalone;
} else {
preset = Preset.VueMonorepo;
}
} }
} }
if (preset === Preset.NuxtStandalone) {
appName = parsedArgs.appName ?? parsedArgs.name;
} else {
appName = await determineAppName(parsedArgs);
}
e2eTestRunner = await determineE2eTestRunner(parsedArgs); e2eTestRunner = await determineE2eTestRunner(parsedArgs);
if (parsedArgs.style) { if (parsedArgs.style) {
@ -1021,11 +958,7 @@ async function determineStandaloneOrMonorepo(): Promise<
async function determineAppName( async function determineAppName(
parsedArgs: yargs.Arguments< parsedArgs: yargs.Arguments<
| ReactArguments ReactArguments | AngularArguments | NodeArguments | VueArguments
| AngularArguments
| NodeArguments
| VueArguments
| NuxtArguments
> >
): Promise<string> { ): Promise<string> {
if (parsedArgs.appName) return parsedArgs.appName; if (parsedArgs.appName) return parsedArgs.appName;
@ -1133,6 +1066,34 @@ async function determineNextAppDir(
return reply.nextAppDir === 'Yes'; return reply.nextAppDir === 'Yes';
} }
async function determineVueFramework(
parsedArgs: yargs.Arguments<VueArguments>
): Promise<'none' | 'nuxt'> {
if (!!parsedArgs.framework) return parsedArgs.framework;
const reply = await enquirer.prompt<{
framework: 'none' | 'nuxt';
}>([
{
name: 'framework',
message: 'What framework would you like to use?',
type: 'autocomplete',
choices: [
{
name: 'none',
message: 'None',
hint: ' I only want vue',
},
{
name: 'nuxt',
message: 'Nuxt [ https://nuxt.com/ ]',
},
],
initial: 'none' as any,
},
]);
return reply.framework;
}
async function determineNodeFramework( async function determineNodeFramework(
parsedArgs: yargs.Arguments<NodeArguments> parsedArgs: yargs.Arguments<NodeArguments>
): Promise<'express' | 'fastify' | 'koa' | 'nest' | 'none'> { ): Promise<'express' | 'fastify' | 'koa' | 'nest' | 'none'> {