Skip to content

Commit

Permalink
feat(vue): add nuxt as cnw vue framework (nrwl#20626)
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarini authored and meeroslav committed Dec 14, 2023
1 parent adff28a commit ee4790e
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 95 deletions.
2 changes: 1 addition & 1 deletion docs/generated/cli/create-nx-workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ Package manager to use

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ Package manager to use

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

Expand Down
6 changes: 6 additions & 0 deletions e2e/utils/create-project-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ export function runCreateWorkspace(
nextAppDir,
e2eTestRunner,
ssr,
framework,
}: {
preset: string;
appName?: string;
Expand All @@ -239,6 +240,7 @@ export function runCreateWorkspace(
nextAppDir?: boolean;
e2eTestRunner?: 'cypress' | 'playwright' | 'jest' | 'detox' | 'none';
ssr?: boolean;
framework?: string;
}
) {
projName = name;
Expand Down Expand Up @@ -288,6 +290,10 @@ export function runCreateWorkspace(
command += ` --e2eTestRunner=${e2eTestRunner}`;
}

if (framework) {
command += ` --framework=${framework}`;
}

if (extraArgs) {
command += ` ${extraArgs}`;
}
Expand Down
34 changes: 33 additions & 1 deletion e2e/workspace-create/src/create-nx-workspace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ describe('create-nx-workspace', () => {
expectCodeIsFormatted();
});

it('should be able to create an vue monorepo', () => {
it('should be able to create a vue monorepo', () => {
const wsName = uniq('vue');
const appName = uniq('app');
runCreateWorkspace(wsName, {
Expand All @@ -460,6 +460,38 @@ describe('create-nx-workspace', () => {
});
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', () => {
Expand Down
145 changes: 53 additions & 92 deletions packages/create-nx-workspace/bin/create-nx-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,7 @@ interface VueArguments extends BaseArguments {
stack: 'vue';
workspaceType: 'standalone' | 'integrated';
appName: string;
style: string;
e2eTestRunner: 'none' | 'cypress' | 'playwright';
}

interface NuxtArguments extends BaseArguments {
stack: 'nuxt';
workspaceType: 'standalone' | 'integrated';
appName: string;
framework: 'none' | 'nuxt';
style: string;
e2eTestRunner: 'none' | 'cypress' | 'playwright';
}
Expand All @@ -97,7 +90,6 @@ type Arguments =
| ReactArguments
| AngularArguments
| VueArguments
| NuxtArguments
| NodeArguments
| UnknownStackArguments;

Expand All @@ -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(
Preset
)
// TODO(katerina): Remove this option when @nx/nuxt is released.
.filter((p) => p !== Preset.NuxtStandalone && p !== Preset.Nuxt)
.map((p) => `"${p}"`)
.join(
', '
Expand Down Expand Up @@ -375,7 +365,7 @@ async function determineFolder(

async function determineStack(
parsedArgs: yargs.Arguments<Arguments>
): Promise<'none' | 'react' | 'angular' | 'vue' | 'node' | 'nuxt' | 'unknown'> {
): Promise<'none' | 'react' | 'angular' | 'vue' | 'node' | 'unknown'> {
if (parsedArgs.preset) {
switch (parsedArgs.preset) {
case Preset.Angular:
Expand All @@ -390,10 +380,9 @@ async function determineStack(
return 'react';
case Preset.VueStandalone:
case Preset.VueMonorepo:
return 'vue';
case Preset.NuxtStandalone:
case Preset.Nuxt:
return 'nuxt';
case Preset.NuxtStandalone:
return 'vue';
case Preset.Nest:
case Preset.NodeStandalone:
case Preset.Express:
Expand Down Expand Up @@ -429,7 +418,7 @@ async function determineStack(
},
{
name: `vue`,
message: `Vue: Configures a Vue application with modern tooling.`,
message: `Vue: Configures a Vue application with your framework of choice.`,
},
{
name: `angular`,
Expand Down Expand Up @@ -458,8 +447,6 @@ async function determinePresetOptions(
return determineAngularOptions(parsedArgs);
case 'vue':
return determineVueOptions(parsedArgs);
case 'nuxt':
return determineNuxtOptions(parsedArgs);
case 'node':
return determineNodeOptions(parsedArgs);
default:
Expand Down Expand Up @@ -640,83 +627,33 @@ async function determineVueOptions(

if (parsedArgs.preset) {
preset = parsedArgs.preset;
} else {
const workspaceType = await determineStandaloneOrMonorepo();

if (workspaceType === 'standalone') {
preset = Preset.VueStandalone;
if (preset === Preset.VueStandalone || preset === Preset.NuxtStandalone) {
appName = parsedArgs.appName ?? parsedArgs.name;
} else {
preset = Preset.VueMonorepo;
appName = await determineAppName(parsedArgs);
}
}

if (preset === Preset.VueStandalone) {
appName = parsedArgs.appName ?? parsedArgs.name;
} else {
appName = await determineAppName(parsedArgs);
}

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;
appName = parsedArgs.appName ?? parsedArgs.name;
} else {
preset = Preset.Nuxt;
appName = await determineAppName(parsedArgs);
}
}
const framework = await determineVueFramework(parsedArgs);

if (preset === Preset.NuxtStandalone) {
appName = parsedArgs.appName ?? parsedArgs.name;
} else {
appName = await determineAppName(parsedArgs);
if (framework === 'nuxt') {
if (workspaceType === 'standalone') {
preset = Preset.NuxtStandalone;
} else {
preset = Preset.Nuxt;
}
} else {
if (workspaceType === 'standalone') {
preset = Preset.VueStandalone;
} else {
preset = Preset.VueMonorepo;
}
}
}

e2eTestRunner = await determineE2eTestRunner(parsedArgs);
Expand Down Expand Up @@ -1021,11 +958,7 @@ async function determineStandaloneOrMonorepo(): Promise<

async function determineAppName(
parsedArgs: yargs.Arguments<
| ReactArguments
| AngularArguments
| NodeArguments
| VueArguments
| NuxtArguments
ReactArguments | AngularArguments | NodeArguments | VueArguments
>
): Promise<string> {
if (parsedArgs.appName) return parsedArgs.appName;
Expand Down Expand Up @@ -1133,6 +1066,34 @@ async function determineNextAppDir(
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(
parsedArgs: yargs.Arguments<NodeArguments>
): Promise<'express' | 'fastify' | 'koa' | 'nest' | 'none'> {
Expand Down

0 comments on commit ee4790e

Please sign in to comment.