Skip to content

Commit 776367e

Browse files
authored
fix(nuxt): tsconfig types and output dir (#21934)
1 parent 26ce6f6 commit 776367e

File tree

11 files changed

+196
-83
lines changed

11 files changed

+196
-83
lines changed

e2e/nuxt/src/nuxt.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ describe('Nuxt Plugin', () => {
3333
expect(result).toContain(
3434
`Successfully ran target build for project ${app}`
3535
);
36-
checkFilesExist(`dist/${app}/.nuxt/nuxt.d.ts`);
37-
checkFilesExist(`dist/${app}/.output/nitro.json`);
36+
checkFilesExist(`${app}/.nuxt/nuxt.d.ts`);
37+
checkFilesExist(`${app}/.output/nitro.json`);
3838
});
3939

4040
it('should test application', async () => {

packages/nuxt/src/generators/application/__snapshots__/application.spec.ts.snap

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ exports[`app generated files content - as-provided general application should ad
1313
exports[`app generated files content - as-provided general application should configure eslint correctly 1`] = `
1414
"{
1515
"extends": ["@nuxt/eslint-config", "../.eslintrc.json"],
16-
"ignorePatterns": ["!**/*"],
16+
"ignorePatterns": ["!**/*", ".nuxt/**", ".output/**", "node_modules"],
1717
"overrides": [
1818
{
1919
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
@@ -34,7 +34,6 @@ import { defineNuxtConfig } from 'nuxt/config';
3434
export default defineNuxtConfig({
3535
workspaceDir: '../',
3636
srcDir: 'src',
37-
buildDir: '../dist/my-app/.nuxt',
3837
devtools: { enabled: true },
3938
devServer: {
4039
host: 'localhost',
@@ -53,11 +52,6 @@ export default defineNuxtConfig({
5352
vite: {
5453
plugins: [nxViteTsPaths()],
5554
},
56-
nitro: {
57-
output: {
58-
dir: '../dist/my-app/.output',
59-
},
60-
},
6155
});
6256
"
6357
`;
@@ -77,7 +71,7 @@ exports[`app generated files content - as-provided general application should co
7771
"{
7872
"compilerOptions": {},
7973
"files": [],
80-
"include": [],
74+
"include": [".nuxt/nuxt.d.ts"],
8175
"references": [
8276
{
8377
"path": "./tsconfig.app.json"
@@ -161,7 +155,7 @@ exports[`app generated files content - as-provided general application should co
161155
"{
162156
"compilerOptions": {},
163157
"files": [],
164-
"include": [],
158+
"include": [".nuxt/nuxt.d.ts"],
165159
"references": [
166160
{
167161
"path": "./tsconfig.app.json"
@@ -222,7 +216,6 @@ import { defineNuxtConfig } from 'nuxt/config';
222216
export default defineNuxtConfig({
223217
workspaceDir: '../',
224218
srcDir: 'src',
225-
buildDir: '../dist/myapp1/.nuxt',
226219
devtools: { enabled: true },
227220
devServer: {
228221
host: 'localhost',
@@ -243,11 +236,6 @@ export default defineNuxtConfig({
243236
vite: {
244237
plugins: [nxViteTsPaths()],
245238
},
246-
nitro: {
247-
output: {
248-
dir: '../dist/myapp1/.output',
249-
},
250-
},
251239
});
252240
"
253241
`;
@@ -260,7 +248,6 @@ import { defineNuxtConfig } from 'nuxt/config';
260248
export default defineNuxtConfig({
261249
workspaceDir: '../',
262250
srcDir: 'src',
263-
buildDir: '../dist/myapp3/.nuxt',
264251
devtools: { enabled: true },
265252
devServer: {
266253
host: 'localhost',
@@ -281,11 +268,6 @@ export default defineNuxtConfig({
281268
vite: {
282269
plugins: [nxViteTsPaths()],
283270
},
284-
nitro: {
285-
output: {
286-
dir: '../dist/myapp3/.output',
287-
},
288-
},
289271
});
290272
"
291273
`;
@@ -298,7 +280,6 @@ import { defineNuxtConfig } from 'nuxt/config';
298280
export default defineNuxtConfig({
299281
workspaceDir: '../',
300282
srcDir: 'src',
301-
buildDir: '../dist/myapp2/.nuxt',
302283
devtools: { enabled: true },
303284
devServer: {
304285
host: 'localhost',
@@ -319,11 +300,6 @@ export default defineNuxtConfig({
319300
vite: {
320301
plugins: [nxViteTsPaths()],
321302
},
322-
nitro: {
323-
output: {
324-
dir: '../dist/myapp2/.output',
325-
},
326-
},
327303
});
328304
"
329305
`;
@@ -336,7 +312,6 @@ import { defineNuxtConfig } from 'nuxt/config';
336312
export default defineNuxtConfig({
337313
workspaceDir: '../',
338314
srcDir: 'src',
339-
buildDir: '../dist/myapp4/.nuxt',
340315
devtools: { enabled: true },
341316
devServer: {
342317
host: 'localhost',
@@ -355,11 +330,6 @@ export default defineNuxtConfig({
355330
vite: {
356331
plugins: [nxViteTsPaths()],
357332
},
358-
nitro: {
359-
output: {
360-
dir: '../dist/myapp4/.output',
361-
},
362-
},
363333
});
364334
"
365335
`;

packages/nuxt/src/generators/application/application.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
6666
tmpl: '',
6767
style: options.style,
6868
projectRoot: options.appProjectRoot,
69-
buildDirectory: joinPathFragments(`dist/${options.appProjectRoot}/.nuxt`),
70-
nitroOutputDir: joinPathFragments(
71-
`dist/${options.appProjectRoot}/.output`
72-
),
7369
hasVitest: options.unitTestRunner === 'vitest',
7470
}
7571
);

packages/nuxt/src/generators/application/files/nuxt.config.ts__tmpl__

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { defineNuxtConfig } from 'nuxt/config';
55
export default defineNuxtConfig({
66
workspaceDir: '<%= offsetFromRoot %>',
77
srcDir: 'src',
8-
buildDir: '<%= offsetFromRoot %><%= buildDirectory %>',
98
devtools: { enabled: true },
109
devServer: {
1110
host: 'localhost',
@@ -28,9 +27,4 @@ export default defineNuxtConfig({
2827
nxViteTsPaths()
2928
],
3029
},
31-
nitro: {
32-
output: {
33-
dir: '<%= offsetFromRoot %><%= nitroOutputDir %>',
34-
},
35-
},
3630
});
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import addIncludeToTsConfig from './add-include-tsconfig';
2+
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
3+
import { Tree, addProjectConfiguration, writeJson } from '@nx/devkit';
4+
5+
jest.mock('@nuxt/kit', () => ({
6+
loadNuxtConfig: jest.fn().mockImplementation(() => {
7+
return Promise.resolve({
8+
buildDir: '../dist/my-nuxt-app/.nuxt',
9+
});
10+
}),
11+
}));
12+
13+
jest.mock('../../utils/executor-utils', () => ({
14+
loadNuxtKitDynamicImport: jest.fn().mockResolvedValue({
15+
loadNuxtConfig: jest.fn().mockResolvedValue({
16+
buildDir: '../dist/my-nuxt-app/.nuxt',
17+
}),
18+
}),
19+
}));
20+
21+
describe('addIncludeToTsConfig', () => {
22+
let tree: Tree;
23+
24+
beforeAll(() => {
25+
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
26+
addProjectConfiguration(tree, 'my-nuxt-app', {
27+
root: `my-nuxt-app`,
28+
sourceRoot: `my-nuxt-app/src`,
29+
targets: {
30+
test: {
31+
executor: '@nx/vite:test',
32+
options: {},
33+
},
34+
},
35+
});
36+
37+
tree.write(
38+
`my-nuxt-app/nuxt.config.ts`,
39+
`
40+
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
41+
import { defineNuxtConfig } from 'nuxt/config';
42+
43+
// https://nuxt.com/docs/api/configuration/nuxt-config
44+
export default defineNuxtConfig({
45+
workspaceDir: '../../',
46+
srcDir: 'src',
47+
buildDir: '../dist/my-nuxt-app/.nuxt',
48+
css: ['~/assets/css/styles.css'],
49+
vite: {
50+
plugins: [nxViteTsPaths()],
51+
},
52+
});
53+
`
54+
);
55+
56+
writeJson(tree, 'my-nuxt-app/tsconfig.json', {
57+
compilerOptions: {},
58+
files: [],
59+
include: [],
60+
references: [
61+
{
62+
path: './tsconfig.app.json',
63+
},
64+
{
65+
path: './tsconfig.spec.json',
66+
},
67+
],
68+
extends: '../tsconfig.base.json',
69+
});
70+
});
71+
72+
it('should add include to tsconfig', async () => {
73+
await addIncludeToTsConfig(tree);
74+
const tsConfig = tree.read('my-nuxt-app/tsconfig.json', 'utf-8');
75+
const tsconfigJson = JSON.parse(tsConfig);
76+
expect(tsconfigJson.include).toMatchObject([
77+
'../dist/my-nuxt-app/.nuxt/nuxt.d.ts',
78+
]);
79+
});
80+
});
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import {
2+
Tree,
3+
formatFiles,
4+
getProjects,
5+
joinPathFragments,
6+
updateJson,
7+
workspaceRoot,
8+
} from '@nx/devkit';
9+
import { loadNuxtKitDynamicImport } from '../../utils/executor-utils';
10+
import { basename } from 'path';
11+
12+
export default async function (tree: Tree) {
13+
const projects = getProjects(tree);
14+
15+
for (const project of projects.values()) {
16+
const nuxtConfigPath = findNuxtConfig(tree, project.root);
17+
18+
if (!nuxtConfigPath) {
19+
continue;
20+
}
21+
22+
const nuxtConfig = await getInfoFromNuxtConfig(
23+
nuxtConfigPath,
24+
project.root
25+
);
26+
27+
const buildDir = nuxtConfig.buildDir ?? '.nuxt';
28+
29+
const tsConfigPath = joinPathFragments(project.root, 'tsconfig.json');
30+
31+
if (tree.exists(tsConfigPath)) {
32+
updateJson(tree, tsConfigPath, (json) => {
33+
if (!json.include) {
34+
json.include = [];
35+
}
36+
37+
if (!json.include.includes(buildDir + '/nuxt.d.ts')) {
38+
json.include.push(buildDir + '/nuxt.d.ts');
39+
}
40+
41+
return json;
42+
});
43+
}
44+
}
45+
46+
await formatFiles(tree);
47+
}
48+
49+
function findNuxtConfig(tree: Tree, projectRoot: string): string | undefined {
50+
const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
51+
52+
for (const ext of allowsExt) {
53+
if (tree.exists(joinPathFragments(projectRoot, `nuxt.config.${ext}`))) {
54+
return joinPathFragments(projectRoot, `nuxt.config.${ext}`);
55+
}
56+
}
57+
}
58+
59+
async function getInfoFromNuxtConfig(
60+
configFilePath: string,
61+
projectRoot: string
62+
): Promise<{
63+
buildDir: string;
64+
}> {
65+
const { loadNuxtConfig } = await loadNuxtKitDynamicImport();
66+
67+
const config = await loadNuxtConfig({
68+
cwd: joinPathFragments(workspaceRoot, projectRoot),
69+
configFile: basename(configFilePath),
70+
});
71+
72+
return {
73+
buildDir: config?.buildDir,
74+
};
75+
}

packages/nuxt/src/plugins/plugin.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,7 @@ async function buildNuxtTargets(
9393
buildDir: string;
9494
} = await getInfoFromNuxtConfig(configFilePath, context, projectRoot);
9595

96-
const { buildOutputs } = getOutputs(
97-
nuxtConfig,
98-
99-
projectRoot
100-
);
96+
const { buildOutputs } = getOutputs(nuxtConfig, projectRoot);
10197

10298
const namedInputs = getNamedInputs(projectRoot, context);
10399

@@ -179,16 +175,14 @@ function getOutputs(
179175
} {
180176
let nuxtBuildDir = nuxtConfig?.buildDir;
181177
if (nuxtConfig?.buildDir && basename(nuxtConfig?.buildDir) === '.nuxt') {
182-
// buildDir will most probably be `../dist/my-app/.nuxt`
183-
// we want the "general" outputPath to be `../dist/my-app`
178+
// if buildDir exists, it will be `something/something/.nuxt`
179+
// we want the "general" outputPath to be `something/something`
184180
nuxtBuildDir = nuxtConfig.buildDir.replace(
185181
basename(nuxtConfig.buildDir),
186182
''
187183
);
188184
}
189-
const buildOutputPath =
190-
normalizeOutputPath(nuxtBuildDir, projectRoot) ??
191-
'{workspaceRoot}/dist/{projectRoot}';
185+
const buildOutputPath = normalizeOutputPath(nuxtBuildDir, projectRoot);
192186

193187
return {
194188
buildOutputs: [buildOutputPath],
@@ -198,12 +192,12 @@ function getOutputs(
198192
function normalizeOutputPath(
199193
outputPath: string | undefined,
200194
projectRoot: string
201-
): string | undefined {
195+
): string {
202196
if (!outputPath) {
203197
if (projectRoot === '.') {
204-
return `{projectRoot}/dist`;
198+
return `{projectRoot}`;
205199
} else {
206-
return `{workspaceRoot}/dist/{projectRoot}`;
200+
return `{workspaceRoot}/{projectRoot}`;
207201
}
208202
} else {
209203
if (isAbsolute(outputPath)) {

0 commit comments

Comments
 (0)