Skip to content

Commit

Permalink
feat(nuxt): init, app, component, page generators (#19509)
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarini authored Oct 10, 2023
1 parent f4c7ee2 commit 5366d49
Show file tree
Hide file tree
Showing 51 changed files with 2,636 additions and 134 deletions.
33 changes: 33 additions & 0 deletions e2e/nuxt/src/nuxt.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
cleanupProject,
killPorts,
newProject,
runCLI,
uniq,
} from '@nx/e2e/utils';

describe('Nuxt Plugin', () => {
let proj: string;

beforeAll(() => {
proj = newProject({
unsetProjectNameAndRootFormat: false,
});
});

afterAll(() => {
killPorts();
cleanupProject();
});

it('should build application', async () => {
const app = uniq('app');

runCLI(`generate @nx/nuxt:app ${app} --unitTestRunner=none`);

const result = runCLI(`build ${app}`);
expect(result).toContain(
`Successfully ran target build for project ${app}`
);
});
});
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
"@ngrx/router-store": "~16.0.0",
"@ngrx/store": "~16.0.0",
"@nguniversal/builders": "~16.2.0",
"@nuxt/kit": "^3.7.4",
"@nuxt/schema": "^3.7.4",
"@nx/angular": "16.10.0-beta.1",
"@nx/cypress": "16.10.0-beta.1",
"@nx/devkit": "16.10.0-beta.1",
Expand Down Expand Up @@ -156,6 +158,7 @@
"cytoscape-popper": "^2.0.0",
"cz-git": "^1.4.0",
"czg": "^1.4.0",
"defu": "^6.1.2",
"detect-port": "^1.5.1",
"dotenv": "~16.3.1",
"dotenv-expand": "^10.0.0",
Expand Down
34 changes: 34 additions & 0 deletions packages/nuxt/docs/application-examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: Nuxt application generator examples
description: This page contains examples for the @nx/nuxt:app generator.
---

## Examples

{% tabs %}
{% tab label="Create app in a directory" %}

{% callout type="note" title="Directory Flag Behavior Changes" %}
The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [workspace layout documentation](/reference/nx-json#workspace-layout) for more details.
{% /callout %}

```shell
nx g app myapp --directory=apps/nested/myapp
```

{% /tab %}
{% tab label="Use a custom Express server" %}

```shell
nx g app myapp --custom-server
```

{% /tab %}
{% tab label="Use plain JavaScript (not TypeScript)" %}

```shell
nx g app myapp --js
```

{% /tab %}
{% /tabs %}
29 changes: 28 additions & 1 deletion packages/nuxt/generators.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
{
"name": "Nx Nuxt",
"version": "0.1",
"generators": {}
"generators": {
"init": {
"factory": "./src/generators/init/init",
"schema": "./src/generators/init/schema.json",
"description": "Initialize the `@nx/nuxt` plugin.",
"aliases": ["ng-add"],
"hidden": true
},
"application": {
"factory": "./src/generators/application/application",
"schema": "./src/generators/application/schema.json",
"aliases": ["app"],
"description": "Create a Nuxt application."
},
"component": {
"factory": "./src/generators/component/component",
"schema": "./src/generators/component/schema.json",
"aliases": ["c"],
"x-type": "component",
"description": "Create a Vue component for your Nuxt application."
},
"page": {
"factory": "./src/generators/page/page",
"schema": "./src/generators/page/schema.json",
"x-type": "page",
"description": "Create a new page for your Nuxt application."
}
}
}
4 changes: 4 additions & 0 deletions packages/nuxt/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export * from './src/utils/versions';
export { applicationGenerator } from './src/generators/application/application';
export { type InitSchema } from './src/generators/init/schema';
export { nuxtInitGenerator } from './src/generators/init/init';
export * from './plugins/with-nuxt';
12 changes: 11 additions & 1 deletion packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,17 @@
"migrations": "./migrations.json"
},
"dependencies": {
"tslib": "^2.3.0"
"defu": "^6.1.2",
"fs-extra": "^11.1.0",
"tslib": "^2.3.0",
"@nx/devkit": "file:../devkit",
"@nx/js": "file:../js",
"@nx/linter": "file:../linter",
"@nx/vue": "file:../vue",
"@nx/cypress": "file:../cypress",
"@nx/playwright": "file:../playwright",
"@nuxt/kit": "^3.7.4",
"@nuxt/schema": "^3.7.4"
},
"publishConfig": {
"access": "public"
Expand Down
49 changes: 49 additions & 0 deletions packages/nuxt/plugins/with-nuxt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { join, resolve } from 'path';
import { workspaceRoot } from '@nx/devkit';
import { existsSync } from 'fs-extra';
import { defineNuxtModule } from '@nuxt/kit';
import { defu } from 'defu';
import { NuxtModule } from '@nuxt/schema';

export const NxNuxtModule: NuxtModule = defineNuxtModule({
meta: { name: '@nx/nuxt/module', configKey: 'nx' },
setup(_options, nuxt) {
nuxt.options.alias = defu(nuxt.options.alias, nxTsPaths());
},
});

/**
* read the compilerOptions.paths option from a tsconfig and return as aliases for Nuxt
**/
function nxTsPaths() {
const tsConfigPath = getTsConfig(join(workspaceRoot, 'tsconfig.base.json'));
const tsPaths = require(tsConfigPath)?.compilerOptions?.paths as Record<
string,
string[]
>;

const alias: Record<string, string> = {};
if (tsPaths) {
for (const p in tsPaths) {
// '@org/something/*': ['libs/something/src/*'] => '@org/something': '{pathToWorkspaceRoot}/libs/something/src'
alias[p.replace(/\/\*$/, '')] = join(
workspaceRoot,
tsPaths[p][0].replace(/\/\*$/, '')
);
}
}

return alias;
}

function getTsConfig(preferredTsConfigPath: string): string {
return [
resolve(preferredTsConfigPath),
resolve(join(workspaceRoot, 'tsconfig.base.json')),
resolve(join(workspaceRoot, 'tsconfig.json')),
].find((tsPath) => {
if (existsSync(tsPath)) {
return tsPath;
}
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`app generated files content - as-provided should add nuxt entries in .gitignore 1`] = `
"
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache"
`;

exports[`app generated files content - as-provided should configure eslint correctly 1`] = `
"{
"extends": ["@nuxt/eslint-config", "../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
"rules": {}
}
]
}
"
`;

exports[`app generated files content - as-provided should configure nuxt correctly 1`] = `
"import { NxNuxtModule } from '@nx/nuxt';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: [NxNuxtModule],
srcDir: 'src',
devtools: { enabled: true },
css: ['~/assets/css/styles.css'],
});
"
`;

exports[`app generated files content - as-provided should configure tsconfig and project.json correctly 1`] = `
"{
"name": "my-app",
"$schema": "../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "my-app/src",
"targets": {
"serve": {
"executor": "nx:run-commands",
"outputs": [
"{workspaceRoot}/{projectRoot}/.output",
"{workspaceRoot}/{projectRoot}/.nuxt"
],
"options": {
"command": "npx nuxi dev --port=4200",
"cwd": "my-app"
}
},
"build": {
"executor": "nx:run-commands",
"outputs": [
"{workspaceRoot}/{projectRoot}/.output",
"{workspaceRoot}/{projectRoot}/.nuxt"
],
"options": {
"command": "npx nuxi build",
"cwd": "my-app"
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["my-app/**/*.{ts,tsx,js,jsx,vue}"]
}
},
"test": {
"executor": "@nx/vite:test",
"outputs": ["{options.reportsDirectory}"],
"options": {
"passWithNoTests": true,
"reportsDirectory": "../coverage/my-app"
}
}
}
}
"
`;

exports[`app generated files content - as-provided should configure tsconfig and project.json correctly 2`] = `
"{
"compilerOptions": {},
"files": [],
"include": [],
"references": [
{
"path": "./.nuxt/tsconfig.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"extends": "../tsconfig.base.json"
}
"
`;

exports[`app generated files content - as-provided should create all new files in the correct location 1`] = `
[
".prettierrc",
"package.json",
"nx.json",
"tsconfig.base.json",
".prettierignore",
"my-app/project.json",
"my-app/.npmrc",
"my-app/nuxt.config.ts",
"my-app/src/app.vue",
"my-app/src/assets/css/styles.css",
"my-app/src/components/NxWelcome.vue",
"my-app/src/pages/about.vue",
"my-app/src/pages/index.vue",
"my-app/src/public/.gitkeep",
"my-app/src/public/favicon.ico",
"my-app/src/server/api/greet.ts",
"my-app/src/server/tsconfig.json",
"my-app/tsconfig.json",
".gitignore",
".eslintrc.json",
".eslintignore",
"my-app/.eslintrc.json",
"my-app/vite.config.ts",
"my-app/tsconfig.spec.json",
"my-app-e2e/cypress.config.ts",
"my-app-e2e/src/e2e/app.cy.ts",
"my-app-e2e/src/fixtures/example.json",
"my-app-e2e/src/support/app.po.ts",
"my-app-e2e/src/support/commands.ts",
"my-app-e2e/src/support/e2e.ts",
"my-app-e2e/tsconfig.json",
"my-app-e2e/project.json",
"my-app-e2e/.eslintrc.json",
]
`;
39 changes: 39 additions & 0 deletions packages/nuxt/src/generators/application/application.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Tree } from '@nx/devkit';
import { applicationGenerator } from './application';

describe('app', () => {
let tree: Tree;
const name = 'my-app';

describe('generated files content - as-provided', () => {
beforeAll(async () => {
tree = createTreeWithEmptyWorkspace();
await applicationGenerator(tree, {
name,
projectNameAndRootFormat: 'as-provided',
});
});
it('should create all new files in the correct location', async () => {
const newFiles = tree.listChanges().map((change) => change.path);
expect(newFiles).toMatchSnapshot();
});

it('should add nuxt entries in .gitignore', () => {
expect(tree.read('.gitignore', 'utf-8')).toMatchSnapshot();
});

it('should configure nuxt correctly', () => {
expect(tree.read('my-app/nuxt.config.ts', 'utf-8')).toMatchSnapshot();
});

it('should configure eslint correctly', () => {
expect(tree.read('my-app/.eslintrc.json', 'utf-8')).toMatchSnapshot();
});

it('should configure tsconfig and project.json correctly', () => {
expect(tree.read('my-app/project.json', 'utf-8')).toMatchSnapshot();
expect(tree.read('my-app/tsconfig.json', 'utf-8')).toMatchSnapshot();
});
});
});
Loading

1 comment on commit 5366d49

@vercel
Copy link

@vercel vercel bot commented on 5366d49 Oct 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-five.vercel.app
nx-dev-git-master-nrwl.vercel.app
nx-dev-nrwl.vercel.app
nx.dev

Please sign in to comment.