Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -152,6 +152,7 @@ export function runCreateWorkspace(
nextAppDir,
e2eTestRunner,
ssr,
framework,
}: {
preset: string;
appName?: string;
Expand All @@ -169,6 +170,7 @@ export function runCreateWorkspace(
nextAppDir?: boolean;
e2eTestRunner?: 'cypress' | 'playwright' | 'jest' | 'detox' | 'none';
ssr?: boolean;
framework?: string;
}
) {
projName = name;
Expand Down Expand Up @@ -218,6 +220,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
Loading