fix(nuxt): tsconfig types and output dir (#21934)

This commit is contained in:
Katerina Skroumpelou 2024-02-23 15:22:18 +02:00 committed by GitHub
parent 26ce6f6f64
commit 776367e882
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 196 additions and 83 deletions

View File

@ -33,8 +33,8 @@ describe('Nuxt Plugin', () => {
expect(result).toContain(
`Successfully ran target build for project ${app}`
);
checkFilesExist(`dist/${app}/.nuxt/nuxt.d.ts`);
checkFilesExist(`dist/${app}/.output/nitro.json`);
checkFilesExist(`${app}/.nuxt/nuxt.d.ts`);
checkFilesExist(`${app}/.output/nitro.json`);
});
it('should test application', async () => {

View File

@ -13,7 +13,7 @@ exports[`app generated files content - as-provided general application should ad
exports[`app generated files content - as-provided general application should configure eslint correctly 1`] = `
"{
"extends": ["@nuxt/eslint-config", "../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"ignorePatterns": ["!**/*", ".nuxt/**", ".output/**", "node_modules"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
@ -34,7 +34,6 @@ import { defineNuxtConfig } from 'nuxt/config';
export default defineNuxtConfig({
workspaceDir: '../',
srcDir: 'src',
buildDir: '../dist/my-app/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
@ -53,11 +52,6 @@ export default defineNuxtConfig({
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: '../dist/my-app/.output',
},
},
});
"
`;
@ -77,7 +71,7 @@ exports[`app generated files content - as-provided general application should co
"{
"compilerOptions": {},
"files": [],
"include": [],
"include": [".nuxt/nuxt.d.ts"],
"references": [
{
"path": "./tsconfig.app.json"
@ -161,7 +155,7 @@ exports[`app generated files content - as-provided general application should co
"{
"compilerOptions": {},
"files": [],
"include": [],
"include": [".nuxt/nuxt.d.ts"],
"references": [
{
"path": "./tsconfig.app.json"
@ -222,7 +216,6 @@ import { defineNuxtConfig } from 'nuxt/config';
export default defineNuxtConfig({
workspaceDir: '../',
srcDir: 'src',
buildDir: '../dist/myapp1/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
@ -243,11 +236,6 @@ export default defineNuxtConfig({
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: '../dist/myapp1/.output',
},
},
});
"
`;
@ -260,7 +248,6 @@ import { defineNuxtConfig } from 'nuxt/config';
export default defineNuxtConfig({
workspaceDir: '../',
srcDir: 'src',
buildDir: '../dist/myapp3/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
@ -281,11 +268,6 @@ export default defineNuxtConfig({
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: '../dist/myapp3/.output',
},
},
});
"
`;
@ -298,7 +280,6 @@ import { defineNuxtConfig } from 'nuxt/config';
export default defineNuxtConfig({
workspaceDir: '../',
srcDir: 'src',
buildDir: '../dist/myapp2/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
@ -319,11 +300,6 @@ export default defineNuxtConfig({
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: '../dist/myapp2/.output',
},
},
});
"
`;
@ -336,7 +312,6 @@ import { defineNuxtConfig } from 'nuxt/config';
export default defineNuxtConfig({
workspaceDir: '../',
srcDir: 'src',
buildDir: '../dist/myapp4/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
@ -355,11 +330,6 @@ export default defineNuxtConfig({
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: '../dist/myapp4/.output',
},
},
});
"
`;

View File

@ -66,10 +66,6 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
tmpl: '',
style: options.style,
projectRoot: options.appProjectRoot,
buildDirectory: joinPathFragments(`dist/${options.appProjectRoot}/.nuxt`),
nitroOutputDir: joinPathFragments(
`dist/${options.appProjectRoot}/.output`
),
hasVitest: options.unitTestRunner === 'vitest',
}
);

View File

@ -5,7 +5,6 @@ import { defineNuxtConfig } from 'nuxt/config';
export default defineNuxtConfig({
workspaceDir: '<%= offsetFromRoot %>',
srcDir: 'src',
buildDir: '<%= offsetFromRoot %><%= buildDirectory %>',
devtools: { enabled: true },
devServer: {
host: 'localhost',
@ -28,9 +27,4 @@ export default defineNuxtConfig({
nxViteTsPaths()
],
},
nitro: {
output: {
dir: '<%= offsetFromRoot %><%= nitroOutputDir %>',
},
},
});

View File

@ -0,0 +1,80 @@
import addIncludeToTsConfig from './add-include-tsconfig';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Tree, addProjectConfiguration, writeJson } from '@nx/devkit';
jest.mock('@nuxt/kit', () => ({
loadNuxtConfig: jest.fn().mockImplementation(() => {
return Promise.resolve({
buildDir: '../dist/my-nuxt-app/.nuxt',
});
}),
}));
jest.mock('../../utils/executor-utils', () => ({
loadNuxtKitDynamicImport: jest.fn().mockResolvedValue({
loadNuxtConfig: jest.fn().mockResolvedValue({
buildDir: '../dist/my-nuxt-app/.nuxt',
}),
}),
}));
describe('addIncludeToTsConfig', () => {
let tree: Tree;
beforeAll(() => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
addProjectConfiguration(tree, 'my-nuxt-app', {
root: `my-nuxt-app`,
sourceRoot: `my-nuxt-app/src`,
targets: {
test: {
executor: '@nx/vite:test',
options: {},
},
},
});
tree.write(
`my-nuxt-app/nuxt.config.ts`,
`
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import { defineNuxtConfig } from 'nuxt/config';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
workspaceDir: '../../',
srcDir: 'src',
buildDir: '../dist/my-nuxt-app/.nuxt',
css: ['~/assets/css/styles.css'],
vite: {
plugins: [nxViteTsPaths()],
},
});
`
);
writeJson(tree, 'my-nuxt-app/tsconfig.json', {
compilerOptions: {},
files: [],
include: [],
references: [
{
path: './tsconfig.app.json',
},
{
path: './tsconfig.spec.json',
},
],
extends: '../tsconfig.base.json',
});
});
it('should add include to tsconfig', async () => {
await addIncludeToTsConfig(tree);
const tsConfig = tree.read('my-nuxt-app/tsconfig.json', 'utf-8');
const tsconfigJson = JSON.parse(tsConfig);
expect(tsconfigJson.include).toMatchObject([
'../dist/my-nuxt-app/.nuxt/nuxt.d.ts',
]);
});
});

View File

@ -0,0 +1,75 @@
import {
Tree,
formatFiles,
getProjects,
joinPathFragments,
updateJson,
workspaceRoot,
} from '@nx/devkit';
import { loadNuxtKitDynamicImport } from '../../utils/executor-utils';
import { basename } from 'path';
export default async function (tree: Tree) {
const projects = getProjects(tree);
for (const project of projects.values()) {
const nuxtConfigPath = findNuxtConfig(tree, project.root);
if (!nuxtConfigPath) {
continue;
}
const nuxtConfig = await getInfoFromNuxtConfig(
nuxtConfigPath,
project.root
);
const buildDir = nuxtConfig.buildDir ?? '.nuxt';
const tsConfigPath = joinPathFragments(project.root, 'tsconfig.json');
if (tree.exists(tsConfigPath)) {
updateJson(tree, tsConfigPath, (json) => {
if (!json.include) {
json.include = [];
}
if (!json.include.includes(buildDir + '/nuxt.d.ts')) {
json.include.push(buildDir + '/nuxt.d.ts');
}
return json;
});
}
}
await formatFiles(tree);
}
function findNuxtConfig(tree: Tree, projectRoot: string): string | undefined {
const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
for (const ext of allowsExt) {
if (tree.exists(joinPathFragments(projectRoot, `nuxt.config.${ext}`))) {
return joinPathFragments(projectRoot, `nuxt.config.${ext}`);
}
}
}
async function getInfoFromNuxtConfig(
configFilePath: string,
projectRoot: string
): Promise<{
buildDir: string;
}> {
const { loadNuxtConfig } = await loadNuxtKitDynamicImport();
const config = await loadNuxtConfig({
cwd: joinPathFragments(workspaceRoot, projectRoot),
configFile: basename(configFilePath),
});
return {
buildDir: config?.buildDir,
};
}

View File

@ -93,11 +93,7 @@ async function buildNuxtTargets(
buildDir: string;
} = await getInfoFromNuxtConfig(configFilePath, context, projectRoot);
const { buildOutputs } = getOutputs(
nuxtConfig,
projectRoot
);
const { buildOutputs } = getOutputs(nuxtConfig, projectRoot);
const namedInputs = getNamedInputs(projectRoot, context);
@ -179,16 +175,14 @@ function getOutputs(
} {
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`
// if buildDir exists, it will be `something/something/.nuxt`
// we want the "general" outputPath to be `something/something`
nuxtBuildDir = nuxtConfig.buildDir.replace(
basename(nuxtConfig.buildDir),
''
);
}
const buildOutputPath =
normalizeOutputPath(nuxtBuildDir, projectRoot) ??
'{workspaceRoot}/dist/{projectRoot}';
const buildOutputPath = normalizeOutputPath(nuxtBuildDir, projectRoot);
return {
buildOutputs: [buildOutputPath],
@ -198,12 +192,12 @@ function getOutputs(
function normalizeOutputPath(
outputPath: string | undefined,
projectRoot: string
): string | undefined {
): string {
if (!outputPath) {
if (projectRoot === '.') {
return `{projectRoot}/dist`;
return `{projectRoot}`;
} else {
return `{workspaceRoot}/dist/{projectRoot}`;
return `{workspaceRoot}/{projectRoot}`;
}
} else {
if (isAbsolute(outputPath)) {

View File

@ -7,8 +7,8 @@ import {
runTasksInSerial,
updateJson,
} from '@nx/devkit';
import { extendNuxtEslintJson, extraEslintDependencies } from './lint';
import { editEslintConfigFiles } from '@nx/vue';
import { nuxtEslintConfigVersion } from './versions';
export async function addLinting(
host: Tree,
@ -33,19 +33,36 @@ export async function addLinting(
});
tasks.push(lintTask);
editEslintConfigFiles(host, options.projectRoot, options.rootProject);
updateJson(
host,
joinPathFragments(options.projectRoot, '.eslintrc.json'),
extendNuxtEslintJson
);
(json) => {
const {
extends: pluginExtends,
ignorePatterns: pluginIgnorePatters,
...config
} = json;
editEslintConfigFiles(host, options.projectRoot, options.rootProject);
return {
extends: ['@nuxt/eslint-config', ...(pluginExtends || [])],
ignorePatterns: [
...(pluginIgnorePatters || []),
'.nuxt/**',
'.output/**',
'node_modules',
],
...config,
};
}
);
const installTask = addDependenciesToPackageJson(
host,
extraEslintDependencies.dependencies,
{},
{
...extraEslintDependencies.devDependencies,
'@nuxt/eslint-config': nuxtEslintConfigVersion,
}
);
tasks.push(installTask);

View File

@ -14,7 +14,7 @@ export function createTsConfig(
const json = {
compilerOptions: {},
files: [],
include: [],
include: ['.nuxt/nuxt.d.ts'],
references: [
{
path: './tsconfig.app.json',

View File

@ -1,18 +0,0 @@
import { nuxtEslintConfigVersion } from './versions';
export const extraEslintDependencies = {
dependencies: {},
devDependencies: {
'@nuxt/eslint-config': nuxtEslintConfigVersion,
},
};
export const extendNuxtEslintJson = (json: any) => {
const { extends: pluginExtends, ...config } = json;
return {
extends: ['@nuxt/eslint-config', ...(pluginExtends || [])],
ignorePatterns: ['.nuxt', 'node_modules', '.output'],
...config,
};
};

View File

@ -420,6 +420,11 @@ export function updateLintConfig(tree: Tree, schema: StorybookConfigureSchema) {
}
}
const ignorePatterns = json.ignorePatterns || [];
if (!ignorePatterns.includes('storybook-static')) {
ignorePatterns.push('storybook-static');
}
return json;
});
}