From ac50f3ca5dbe8ea06083091f209d04ab663b11f1 Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Mon, 30 Oct 2023 11:30:32 +0200 Subject: [PATCH] feat(vue): nuxt executors --- package.json | 1 + packages/nuxt/.eslintrc.json | 3 +- packages/nuxt/docs/build-examples.md | 4 +++ packages/nuxt/docs/serve-examples.md | 4 +++ packages/nuxt/executors.json | 13 ++++++- packages/nuxt/package.json | 1 + packages/nuxt/src/executors/.gitkeep | 0 .../nuxt/src/executors/build/build.impl.ts | 33 +++++++++++++++++ packages/nuxt/src/executors/build/compat.ts | 4 +++ packages/nuxt/src/executors/build/schema.d.ts | 5 +++ packages/nuxt/src/executors/build/schema.json | 36 +++++++++++++++++++ packages/nuxt/src/executors/serve/compat.ts | 4 +++ packages/nuxt/src/executors/serve/schema.d.ts | 4 +++ packages/nuxt/src/executors/serve/schema.json | 29 +++++++++++++++ .../nuxt/src/executors/serve/serve.impl.ts | 29 +++++++++++++++ packages/nuxt/src/generators/.gitkeep | 0 .../__snapshots__/application.spec.ts.snap | 14 +++----- .../generators/application/lib/add-targets.ts | 14 +++----- .../preset/__snapshots__/preset.spec.ts.snap | 7 ++-- pnpm-lock.yaml | 32 +++++++++++++---- 20 files changed, 203 insertions(+), 34 deletions(-) create mode 100644 packages/nuxt/docs/build-examples.md create mode 100644 packages/nuxt/docs/serve-examples.md delete mode 100644 packages/nuxt/src/executors/.gitkeep create mode 100644 packages/nuxt/src/executors/build/build.impl.ts create mode 100644 packages/nuxt/src/executors/build/compat.ts create mode 100644 packages/nuxt/src/executors/build/schema.d.ts create mode 100644 packages/nuxt/src/executors/build/schema.json create mode 100644 packages/nuxt/src/executors/serve/compat.ts create mode 100644 packages/nuxt/src/executors/serve/schema.d.ts create mode 100644 packages/nuxt/src/executors/serve/schema.json create mode 100644 packages/nuxt/src/executors/serve/serve.impl.ts delete mode 100644 packages/nuxt/src/generators/.gitkeep diff --git a/package.json b/package.json index 73bfcc20b84094..568ea27d980fb3 100644 --- a/package.json +++ b/package.json @@ -227,6 +227,7 @@ "ng-packagr": "~16.2.0", "node-fetch": "^2.6.7", "npm-package-arg": "11.0.1", + "nuxi": "^3.9.1", "nx": "17.0.0-rc.2", "octokit": "^2.0.14", "open": "^8.4.0", diff --git a/packages/nuxt/.eslintrc.json b/packages/nuxt/.eslintrc.json index de85e34ac952c9..45b7d04f888906 100644 --- a/packages/nuxt/.eslintrc.json +++ b/packages/nuxt/.eslintrc.json @@ -33,7 +33,8 @@ "nx", "typescript", "@nx/cypress", - "@nx/playwright" + "@nx/playwright", + "@nx/jest" ] } ] diff --git a/packages/nuxt/docs/build-examples.md b/packages/nuxt/docs/build-examples.md new file mode 100644 index 00000000000000..0190294e217f23 --- /dev/null +++ b/packages/nuxt/docs/build-examples.md @@ -0,0 +1,4 @@ +--- +title: Nuxt build executor examples +description: This page contains examples for the @nx/nuxt:build executor. +--- diff --git a/packages/nuxt/docs/serve-examples.md b/packages/nuxt/docs/serve-examples.md new file mode 100644 index 00000000000000..0c076e6ffd2008 --- /dev/null +++ b/packages/nuxt/docs/serve-examples.md @@ -0,0 +1,4 @@ +--- +title: Nuxt serve executor examples +description: This page contains examples for the @nx/nuxt:serve executor. +--- diff --git a/packages/nuxt/executors.json b/packages/nuxt/executors.json index 3a64718e93cb08..c58e015e238000 100644 --- a/packages/nuxt/executors.json +++ b/packages/nuxt/executors.json @@ -1,3 +1,14 @@ { - "executors": {} + "executors": { + "build": { + "implementation": "./src/executors/build/build.impl", + "schema": "./src/executors/build/schema.json", + "description": "Build with Nuxt." + }, + "serve": { + "implementation": "./src/executors/serve/serve.impl", + "schema": "./src/executors/serve/schema.json", + "description": "Serve with Nuxt." + } + } } diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 7cbf5f04142b01..1383cc9cb3ad5f 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -28,6 +28,7 @@ "migrations": "./migrations.json" }, "dependencies": { + "nuxi": "^3.9.1", "tslib": "^2.3.0", "@nx/devkit": "file:../devkit", "@nx/js": "file:../js", diff --git a/packages/nuxt/src/executors/.gitkeep b/packages/nuxt/src/executors/.gitkeep deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/packages/nuxt/src/executors/build/build.impl.ts b/packages/nuxt/src/executors/build/build.impl.ts new file mode 100644 index 00000000000000..ebfaa131b004d7 --- /dev/null +++ b/packages/nuxt/src/executors/build/build.impl.ts @@ -0,0 +1,33 @@ +import { ExecutorContext } from '@nx/devkit'; +import { NuxtBuildExecutorOptions } from './schema'; + +// Required because dep is ESM package. Changing moduleResolution to NodeNext causes other issues unfortunately. +export function loadNuxiDynamicImport() { + return Function('return import("nuxi")')() as Promise; +} + +export async function* nuxtBuildExecutor( + options: NuxtBuildExecutorOptions, + context: ExecutorContext +) { + const projectRoot = + context.projectsConfigurations.projects[context.projectName].root; + const { runCommand } = await loadNuxiDynamicImport(); + try { + await runCommand('build', [projectRoot], { + overrides: { + typescript: { + builder: 'shared', + }, + imports: { + autoImport: false, + }, + }, + }); + return { success: true }; + } catch (e) { + return { success: false, error: e }; + } +} + +export default nuxtBuildExecutor; diff --git a/packages/nuxt/src/executors/build/compat.ts b/packages/nuxt/src/executors/build/compat.ts new file mode 100644 index 00000000000000..d493d198bef9b0 --- /dev/null +++ b/packages/nuxt/src/executors/build/compat.ts @@ -0,0 +1,4 @@ +import { convertNxExecutor } from '@nx/devkit'; +import nuxtBuildExecutor from './build.impl'; + +export default convertNxExecutor(nuxtBuildExecutor); diff --git a/packages/nuxt/src/executors/build/schema.d.ts b/packages/nuxt/src/executors/build/schema.d.ts new file mode 100644 index 00000000000000..f9a34270a35ece --- /dev/null +++ b/packages/nuxt/src/executors/build/schema.d.ts @@ -0,0 +1,5 @@ +export interface NuxtBuildExecutorOptions { + rootDir: string; + prerender?: boolean; + dotenv?: string; +} diff --git a/packages/nuxt/src/executors/build/schema.json b/packages/nuxt/src/executors/build/schema.json new file mode 100644 index 00000000000000..2fff2549af18af --- /dev/null +++ b/packages/nuxt/src/executors/build/schema.json @@ -0,0 +1,36 @@ +{ + "version": 2, + "outputCapture": "direct-nodejs", + "title": "Nuxt Prod Builder", + "cli": "nx", + "description": "Builds a Nuxt application for production.", + "type": "object", + "presets": [ + { + "name": "Default minimum setup", + "keys": [] + } + ], + "properties": { + "rootDir": { + "type": "string", + "description": "The root directory of the application to bundle.", + "x-completion-type": "directory", + "x-priority": "important", + "default": "." + }, + "prerender": { + "description": "Pre-render every route of your application. (note: This is an experimental flag. The behavior might be changed.)", + "type": "boolean", + "default": false + }, + "dotenv": { + "description": "Point to another .env file to load, relative to the root directory.", + "type": "string", + "default": "." + } + }, + "definitions": {}, + "required": [], + "examplesFile": "../../../docs/build-examples.md" +} diff --git a/packages/nuxt/src/executors/serve/compat.ts b/packages/nuxt/src/executors/serve/compat.ts new file mode 100644 index 00000000000000..faadb34d372a5c --- /dev/null +++ b/packages/nuxt/src/executors/serve/compat.ts @@ -0,0 +1,4 @@ +import { convertNxExecutor } from '@nx/devkit'; +import nuxtServeExecutor from './serve.impl'; + +export default convertNxExecutor(nuxtServeExecutor); diff --git a/packages/nuxt/src/executors/serve/schema.d.ts b/packages/nuxt/src/executors/serve/schema.d.ts new file mode 100644 index 00000000000000..2a50707087a5ef --- /dev/null +++ b/packages/nuxt/src/executors/serve/schema.d.ts @@ -0,0 +1,4 @@ +export interface NuxtServeExecutorOptions { + rootDir: string; + dotenv?: string; +} diff --git a/packages/nuxt/src/executors/serve/schema.json b/packages/nuxt/src/executors/serve/schema.json new file mode 100644 index 00000000000000..243e51e6f588ba --- /dev/null +++ b/packages/nuxt/src/executors/serve/schema.json @@ -0,0 +1,29 @@ +{ + "version": 2, + "outputCapture": "direct-nodejs", + "title": "Nuxt Server", + "cli": "nx", + "description": "Serves a Nuxt application for development.", + "type": "object", + "presets": [ + { + "name": "Default minimum setup", + "keys": [] + } + ], + "properties": { + "host": { + "type": "string", + "description": "Dev server listening host.", + "default": "" + }, + "port": { + "type": "number", + "description": "Dev server listening port", + "default": 3000 + } + }, + "definitions": {}, + "required": [], + "examplesFile": "../../../docs/serve-examples.md" +} diff --git a/packages/nuxt/src/executors/serve/serve.impl.ts b/packages/nuxt/src/executors/serve/serve.impl.ts new file mode 100644 index 00000000000000..2f57c6ab5134bf --- /dev/null +++ b/packages/nuxt/src/executors/serve/serve.impl.ts @@ -0,0 +1,29 @@ +import { ExecutorContext } from '@nx/devkit'; +import { NuxtServeExecutorOptions } from './schema'; +import { createAsyncIterable } from '@nx/devkit/src/utils/async-iterable'; + +// Required because dep is ESM package. Changing moduleResolution to NodeNext causes other issues unfortunately. +export function loadNuxiDynamicImport() { + return Function('return import("nuxi")')() as Promise; +} + +export async function* nuxtServeExecutor( + options: NuxtServeExecutorOptions, + context: ExecutorContext +) { + const projectRoot = + context.projectsConfigurations.projects[context.projectName].root; + yield* createAsyncIterable<{ success: boolean }>(async ({ next, error }) => { + try { + const { runCommand } = await loadNuxiDynamicImport(); + await runCommand('dev', [projectRoot]); + next({ + success: true, + }); + } catch (err) { + error(new Error(`Nuxt app exited with message ${err.message}`)); + } + }); +} + +export default nuxtServeExecutor; diff --git a/packages/nuxt/src/generators/.gitkeep b/packages/nuxt/src/generators/.gitkeep deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/packages/nuxt/src/generators/application/__snapshots__/application.spec.ts.snap b/packages/nuxt/src/generators/application/__snapshots__/application.spec.ts.snap index 1b975fb0e66802..1f4de077ebf14a 100644 --- a/packages/nuxt/src/generators/application/__snapshots__/application.spec.ts.snap +++ b/packages/nuxt/src/generators/application/__snapshots__/application.spec.ts.snap @@ -49,26 +49,20 @@ exports[`app generated files content - as-provided should configure tsconfig and "sourceRoot": "my-app/src", "targets": { "serve": { - "executor": "nx:run-commands", + "executor": "@nx/nuxt:serve", "outputs": [ "{workspaceRoot}/{projectRoot}/.output", "{workspaceRoot}/{projectRoot}/.nuxt" ], - "options": { - "command": "npx nuxi dev --port=4200", - "cwd": "my-app" - } + "options": {} }, "build": { - "executor": "nx:run-commands", + "executor": "@nx/nuxt:build", "outputs": [ "{workspaceRoot}/{projectRoot}/.output", "{workspaceRoot}/{projectRoot}/.nuxt" ], - "options": { - "command": "npx nuxi build", - "cwd": "my-app" - } + "options": {} }, "lint": { "executor": "@nx/eslint:lint", diff --git a/packages/nuxt/src/generators/application/lib/add-targets.ts b/packages/nuxt/src/generators/application/lib/add-targets.ts index 220ab4c19cedcd..afa97ab4d9cf59 100644 --- a/packages/nuxt/src/generators/application/lib/add-targets.ts +++ b/packages/nuxt/src/generators/application/lib/add-targets.ts @@ -12,15 +12,12 @@ export function addServeTarget( ) { const projectConfig = readProjectConfiguration(tree, projectName); projectConfig.targets['serve'] = { - executor: 'nx:run-commands', + executor: '@nx/nuxt:serve', outputs: [ '{workspaceRoot}/{projectRoot}/.output', '{workspaceRoot}/{projectRoot}/.nuxt', ], - options: { - command: 'npx nuxi dev --port=4200', - cwd: joinPathFragments(projectRoot), - }, + options: {}, }; updateProjectConfiguration(tree, projectName, projectConfig); } @@ -32,15 +29,12 @@ export function addBuildTarget( ) { const projectConfig = readProjectConfiguration(tree, projectName); projectConfig.targets['build'] = { - executor: 'nx:run-commands', + executor: '@nx/nuxt:build', outputs: [ '{workspaceRoot}/{projectRoot}/.output', '{workspaceRoot}/{projectRoot}/.nuxt', ], - options: { - command: 'npx nuxi build', - cwd: joinPathFragments(projectRoot), - }, + options: {}, }; updateProjectConfiguration(tree, projectName, projectConfig); } diff --git a/packages/workspace/src/generators/preset/__snapshots__/preset.spec.ts.snap b/packages/workspace/src/generators/preset/__snapshots__/preset.spec.ts.snap index 6016dd635d5e28..aa403dc4eddef7 100644 --- a/packages/workspace/src/generators/preset/__snapshots__/preset.spec.ts.snap +++ b/packages/workspace/src/generators/preset/__snapshots__/preset.spec.ts.snap @@ -38,11 +38,8 @@ exports[`preset should create files (preset = angular-monorepo) 3`] = ` exports[`preset should create files (preset = nuxt-standalone) 1`] = ` { - "executor": "nx:run-commands", - "options": { - "command": "npx nuxi dev --port=4200", - "cwd": ".", - }, + "executor": "@nx/nuxt:serve", + "options": {}, "outputs": [ "{workspaceRoot}/{projectRoot}/.output", "{workspaceRoot}/{projectRoot}/.nuxt", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bade028c22f069..150589278ae546 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -757,6 +757,9 @@ devDependencies: npm-package-arg: specifier: 11.0.1 version: 11.0.1 + nuxi: + specifier: ^3.9.1 + version: 3.9.1 nx: specifier: 17.0.0-rc.2 version: 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86) @@ -12627,7 +12630,7 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -16009,6 +16012,13 @@ packages: requiresBuild: true optional: true + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + optional: true + /fstream@1.0.12: resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} engines: {node: '>=0.6'} @@ -17800,7 +17810,7 @@ packages: micromatch: 4.0.5 walker: 1.0.8 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /jest-leak-detector@29.5.0: @@ -19342,7 +19352,7 @@ packages: nullthrows: 1.1.1 walker: 1.0.8 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 transitivePeerDependencies: - supports-color dev: true @@ -20525,6 +20535,14 @@ packages: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} dev: true + /nuxi@3.9.1: + resolution: {integrity: sha512-4R4tcC2uQ5QCnHxyKoX5nZm/YUesCcQM3bZBKYU/8ZWrWjK6aPG6Q5zOQG1aLPkAotyahNsqtSiU/CrRoenEgA==} + engines: {node: ^14.18.0 || >=16.10.0} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + /nwsapi@2.2.2: resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==} dev: true @@ -23728,14 +23746,14 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 /rollup@3.28.0: resolution: {integrity: sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /rrweb-cssom@0.6.0: @@ -26623,7 +26641,7 @@ packages: rollup: 3.21.0 sass: 1.55.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: false /vite@4.4.7(@types/node@18.16.9)(less@4.1.3)(sass@1.64.1)(terser@5.19.2): @@ -26662,7 +26680,7 @@ packages: sass: 1.64.1 terser: 5.19.2 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /vitest@0.32.0(less@4.1.3)(sass@1.55.0):