diff --git a/packages/nuxt/src/plugins/__snapshots__/plugin.spec.ts.snap b/packages/nuxt/src/plugins/__snapshots__/plugin.spec.ts.snap index 6a4bbc5d0fa46a..511102357c4e07 100644 --- a/packages/nuxt/src/plugins/__snapshots__/plugin.spec.ts.snap +++ b/packages/nuxt/src/plugins/__snapshots__/plugin.spec.ts.snap @@ -13,7 +13,7 @@ exports[`@nx/nuxt/plugin not root project should create nodes 1`] = ` "^build-something", ], "inputs": [ - "default", + "production", "^production", { "externalDependencies": [ @@ -25,7 +25,7 @@ exports[`@nx/nuxt/plugin not root project should create nodes 1`] = ` "cwd": "my-app", }, "outputs": [ - "{options.outputPath}", + "../dist/my-app/", ], }, "my-serve": { @@ -50,8 +50,7 @@ exports[`@nx/nuxt/plugin not root project should create nodes 1`] = ` "cwd": "my-app", }, "outputs": [ - "{options.reportsDirectory}", - "{workspaceRoot}/coverage/my-app", + "{workspaceRoot}/coverage/{projectRoot}", ], }, }, @@ -73,7 +72,7 @@ exports[`@nx/nuxt/plugin root project should create nodes 1`] = ` "^build", ], "inputs": [ - "default", + "production", "^production", { "externalDependencies": [ @@ -85,7 +84,7 @@ exports[`@nx/nuxt/plugin root project should create nodes 1`] = ` "cwd": ".", }, "outputs": [ - "{options.outputPath}", + "../dist/my-app/", ], }, "serve": { @@ -110,8 +109,7 @@ exports[`@nx/nuxt/plugin root project should create nodes 1`] = ` "cwd": ".", }, "outputs": [ - "{options.reportsDirectory}", - "{projectRoot}/coverage", + "{workspaceRoot}/coverage/{projectRoot}", ], }, }, diff --git a/packages/nuxt/src/plugins/plugin.spec.ts b/packages/nuxt/src/plugins/plugin.spec.ts index a7774aff08044b..4ec899fe921936 100644 --- a/packages/nuxt/src/plugins/plugin.spec.ts +++ b/packages/nuxt/src/plugins/plugin.spec.ts @@ -5,8 +5,10 @@ import { TempFs } from 'nx/src/internal-testing-utils/temp-fs'; jest.mock('@nuxt/kit', () => ({ loadNuxtConfig: jest.fn().mockImplementation(() => { return Promise.resolve({ - path: 'nuxt.config.ts', - config: {}, + path: 'my-app/nuxt.config.ts', + config: { + buildDir: '../dist/my-app/.nuxt', + }, dependencies: [], }); }), @@ -15,16 +17,18 @@ jest.mock('@nuxt/kit', () => ({ jest.mock('../utils/executor-utils', () => ({ loadNuxtKitDynamicImport: jest.fn().mockResolvedValue({ loadNuxtConfig: jest.fn().mockResolvedValue({ - path: 'nuxt.config.ts', - config: {}, + path: 'my-app/nuxt.config.ts', + config: { + buildDir: '../dist/my-app/.nuxt', + }, dependencies: [], }), }), })); - describe('@nx/nuxt/plugin', () => { let createNodesFunction = createNodes[1]; let context: CreateNodesContext; + describe('root project', () => { beforeEach(async () => { context = { diff --git a/packages/nuxt/src/plugins/plugin.ts b/packages/nuxt/src/plugins/plugin.ts index 29116dabb99499..ab47e9718142ba 100644 --- a/packages/nuxt/src/plugins/plugin.ts +++ b/packages/nuxt/src/plugins/plugin.ts @@ -4,12 +4,12 @@ import { CreateNodesContext, detectPackageManager, joinPathFragments, - offsetFromRoot, readJsonFile, TargetConfiguration, + workspaceRoot, writeJsonFile, } from '@nx/devkit'; -import { basename, dirname, join } from 'path'; +import { basename, dirname, isAbsolute, join, relative } from 'path'; import { projectGraphCacheDirectory } from 'nx/src/utils/cache-directory'; import { getNamedInputs } from '@nx/devkit/src/utils/get-named-inputs'; import { existsSync, readdirSync } from 'fs'; @@ -94,7 +94,7 @@ async function buildNuxtTargets( buildDir: string; } = await getInfoFromNuxtConfig(configFilePath, context, projectRoot); - const { buildOutputs, testOutputs } = getOutputs(projectRoot, nuxtConfig); + const { buildOutputs, testOutputs } = getOutputs(nuxtConfig); const namedInputs = getNamedInputs(projectRoot, context); @@ -133,7 +133,7 @@ function buildTarget( dependsOn: [`^${buildTargetName}`], inputs: [ ...('production' in namedInputs - ? ['default', '^production'] + ? ['production', '^production'] : ['default', '^default']), { @@ -187,6 +187,18 @@ async function getInfoFromNuxtConfig( buildDir: string; }> { const { loadNuxtConfig } = await loadNuxtKitDynamicImport(); + + /** + * loadNuxtConfig returns wrong type as NuxtOptions + * + * The actual return object is of type: + * { + * path: string; + * config: NuxtOptions; + * dependencies: string[]; + * } + */ + const config = await loadNuxtConfig({ cwd: joinPathFragments(context.workspaceRoot, projectRoot), configFile: basename(configFilePath), @@ -195,51 +207,42 @@ async function getInfoFromNuxtConfig( return { // to preserve only the relative path from the workspace root // because nuxt automatically prepends the rootDir to buildDir - buildDir: config?.buildDir?.replace(config?.rootDir, ''), + buildDir: config?.['config']?.buildDir?.replace(config?.rootDir, ''), }; } -function getOutputs( - projectRoot: string, - nuxtConfig: { - buildDir: string; - } -): { +function getOutputs(nuxtConfig: { buildDir: string }): { buildOutputs: string[]; - outputPath: string; testOutputs: string[]; - reportsDirectory: string; } { - const buildOutputs = ['{options.outputPath}']; - const testOutputs = ['{options.reportsDirectory}']; - - function getOutput(path: string, projectRoot: string): string { - if (path.startsWith('..')) { - return join('{workspaceRoot}', join(projectRoot, path)); - } else { - return join('{projectRoot}', path); - } - } - - let distPath = undefined; + const reportsDirectory = '{workspaceRoot}/coverage/{projectRoot}'; + let nuxtBuildDir = nuxtConfig?.buildDir; if (nuxtConfig?.buildDir && basename(nuxtConfig?.buildDir) === '.nuxt') { // buildDir will most probably be `../dist/my-app/.nuxt` // we want the "general" outputPath to be `../dist/my-app` - distPath = nuxtConfig.buildDir.replace(basename(nuxtConfig.buildDir), ''); - buildOutputs.push(getOutput(distPath, projectRoot)); + nuxtBuildDir = nuxtConfig.buildDir.replace( + basename(nuxtConfig.buildDir), + '' + ); } + const buildOutputPath = + normalizeOutputPath(nuxtBuildDir) ?? '{workspaceRoot}/dist/{projectRoot}'; - const outputPath = distPath ?? joinPathFragments('dist', projectRoot); - - const reportsDirectory = joinPathFragments( - offsetFromRoot(projectRoot), - 'coverage', - projectRoot - ); - - testOutputs.push(getOutput(reportsDirectory, projectRoot)); + return { + buildOutputs: [buildOutputPath], + testOutputs: [reportsDirectory], + }; +} - return { buildOutputs, outputPath, testOutputs, reportsDirectory }; +function normalizeOutputPath( + outputPath: string | undefined +): string | undefined { + if (!outputPath) return undefined; + if (isAbsolute(outputPath)) { + return `{workspaceRoot}/${relative(workspaceRoot, outputPath)}`; + } else { + return outputPath; + } } function normalizeOptions(options: NuxtPluginOptions): NuxtPluginOptions { diff --git a/packages/vite/src/plugins/__snapshots__/plugin.spec.ts.snap b/packages/vite/src/plugins/__snapshots__/plugin.spec.ts.snap index 33412087850cec..693e374b8492ca 100644 --- a/packages/vite/src/plugins/__snapshots__/plugin.spec.ts.snap +++ b/packages/vite/src/plugins/__snapshots__/plugin.spec.ts.snap @@ -25,7 +25,7 @@ exports[`@nx/vite/plugin not root project should create nodes 1`] = ` "cwd": "my-app", }, "outputs": [ - "{options.outputPath}", + "{workspaceRoot}/dist/{projectRoot}", ], }, "my-serve": { @@ -62,7 +62,7 @@ exports[`@nx/vite/plugin not root project should create nodes 1`] = ` "cwd": "my-app", }, "outputs": [ - "{options.reportsDirectory}", + "{workspaceRoot}/coverage/{projectRoot}", ], }, }, @@ -96,7 +96,7 @@ exports[`@nx/vite/plugin root project should create nodes 1`] = ` "cwd": ".", }, "outputs": [ - "{options.outputPath}", + "{workspaceRoot}/dist/{projectRoot}", ], }, "preview": { @@ -133,7 +133,7 @@ exports[`@nx/vite/plugin root project should create nodes 1`] = ` "cwd": ".", }, "outputs": [ - "{options.reportsDirectory}", + "{workspaceRoot}/coverage/{projectRoot}", ], }, }, diff --git a/packages/vite/src/plugins/plugin.ts b/packages/vite/src/plugins/plugin.ts index 71ef40f80db057..18bcd32d3f41b2 100644 --- a/packages/vite/src/plugins/plugin.ts +++ b/packages/vite/src/plugins/plugin.ts @@ -9,7 +9,7 @@ import { workspaceRoot, writeJsonFile, } from '@nx/devkit'; -import { dirname, isAbsolute, join, relative, resolve } from 'path'; +import { dirname, isAbsolute, join, relative } from 'path'; import { getNamedInputs } from '@nx/devkit/src/utils/get-named-inputs'; import { loadConfigFromFile, UserConfig } from 'vite'; import { existsSync, readdirSync } from 'fs'; @@ -100,10 +100,7 @@ async function buildViteTargets( configFilePath ); - const { buildOutputs, testOutputs } = getOutputs( - projectRoot, - viteConfig?.config - ); + const { buildOutputs, testOutputs } = getOutputs(viteConfig?.config); const namedInputs = getNamedInputs(projectRoot, context); @@ -212,36 +209,34 @@ function serveStaticTarget(options: VitePluginOptions) { return targetConfig; } -function getOutputs( - projectRoot: string, - viteConfig: UserConfig -): { +function getOutputs(viteConfig: UserConfig): { buildOutputs: string[]; testOutputs: string[]; } { const { build, test } = viteConfig; - const buildOutputs = ['{options.outputPath}']; - const testOutputs = ['{options.reportsDirectory}']; - - function getOutput(path: string, projectRoot: string): string { - if (path.startsWith('..')) { - return join('{workspaceRoot}', join(projectRoot, path)); - } else if (isAbsolute(resolve(path))) { - return `{workspaceRoot}/${relative(workspaceRoot, path)}`; - } else { - return join('{projectRoot}', path); - } - } - if (build?.outDir) { - buildOutputs.push(getOutput(build.outDir, projectRoot)); - } + const buildOutputPath = + normalizeOutputPath(build?.outDir) ?? '{workspaceRoot}/dist/{projectRoot}'; - if (test?.coverage?.reportsDirectory) { - testOutputs.push(getOutput(test.coverage.reportsDirectory, projectRoot)); - } + const reportsDirectoryPath = + normalizeOutputPath(test?.coverage?.reportsDirectory) ?? + '{workspaceRoot}/coverage/{projectRoot}'; - return { buildOutputs, testOutputs }; + return { + buildOutputs: [buildOutputPath], + testOutputs: [reportsDirectoryPath], + }; +} + +function normalizeOutputPath( + outputPath: string | undefined +): string | undefined { + if (!outputPath) return undefined; + if (isAbsolute(outputPath)) { + return `{workspaceRoot}/${relative(workspaceRoot, outputPath)}`; + } else { + return outputPath; + } } function normalizeOptions(options: VitePluginOptions): VitePluginOptions {