fix(vite): include vitest config in nodes plugin (#20887)
This commit is contained in:
parent
d99e8e6aa5
commit
f7d179522f
@ -36,9 +36,7 @@
|
|||||||
"@nx/eslint": "file:../eslint",
|
"@nx/eslint": "file:../eslint",
|
||||||
"@nx/vue": "file:../vue"
|
"@nx/vue": "file:../vue"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {},
|
||||||
"vite": "^5.0.0"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,8 +124,7 @@ describe('app', () => {
|
|||||||
const projectConfi = readProjectConfiguration(tree, name);
|
const projectConfi = readProjectConfiguration(tree, name);
|
||||||
expect(projectConfi.targets.build).toBeUndefined();
|
expect(projectConfi.targets.build).toBeUndefined();
|
||||||
expect(projectConfi.targets.serve).toBeUndefined();
|
expect(projectConfi.targets.serve).toBeUndefined();
|
||||||
// TODO(katerina): Enable once `@nx/vite/plugin` is released
|
expect(projectConfi.targets.test).toBeUndefined();
|
||||||
// expect(projectConfi.targets.test).toBeUndefined();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -32,6 +32,10 @@ describe('init', () => {
|
|||||||
options: { buildTargetName: 'build', serveTargetName: 'serve' },
|
options: { buildTargetName: 'build', serveTargetName: 'serve' },
|
||||||
plugin: '@nx/nuxt/plugin',
|
plugin: '@nx/nuxt/plugin',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
options: { testTargetName: 'test' },
|
||||||
|
plugin: '@nx/vite/plugin',
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -24,7 +24,7 @@ import { InitSchema } from '../schema';
|
|||||||
export function updateDependencies(host: Tree, schema: InitSchema) {
|
export function updateDependencies(host: Tree, schema: InitSchema) {
|
||||||
let devDependencies: { [key: string]: string } = {
|
let devDependencies: { [key: string]: string } = {
|
||||||
'@nx/nuxt': nxVersion,
|
'@nx/nuxt': nxVersion,
|
||||||
'@nx/vite': nxVersion, // needed for the nxViteTsPaths plugin
|
'@nx/vite': nxVersion, // needed for the nxViteTsPaths plugin and @nx/vite/plugin
|
||||||
'@nuxt/devtools': nuxtDevtoolsVersion,
|
'@nuxt/devtools': nuxtDevtoolsVersion,
|
||||||
'@nuxt/kit': nuxtVersion,
|
'@nuxt/kit': nuxtVersion,
|
||||||
'@nuxt/ui-templates': nuxtUiTemplatesVersion,
|
'@nuxt/ui-templates': nuxtUiTemplatesVersion,
|
||||||
@ -64,23 +64,44 @@ export function addPlugin(tree: Tree) {
|
|||||||
const nxJson = readNxJson(tree);
|
const nxJson = readNxJson(tree);
|
||||||
nxJson.plugins ??= [];
|
nxJson.plugins ??= [];
|
||||||
|
|
||||||
|
let hasNxNuxtPlugin = false;
|
||||||
|
let hasNxVitePlugin = false;
|
||||||
|
|
||||||
for (const plugin of nxJson.plugins) {
|
for (const plugin of nxJson.plugins) {
|
||||||
if (
|
if (
|
||||||
typeof plugin === 'string'
|
typeof plugin === 'string'
|
||||||
? plugin === '@nx/nuxt/plugin'
|
? plugin === '@nx/nuxt/plugin'
|
||||||
: plugin.plugin === '@nx/nuxt/plugin'
|
: plugin.plugin === '@nx/nuxt/plugin'
|
||||||
) {
|
) {
|
||||||
return;
|
hasNxNuxtPlugin = true;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
typeof plugin === 'string'
|
||||||
|
? plugin === '@nx/vite/plugin'
|
||||||
|
: plugin.plugin === '@nx/vite/plugin'
|
||||||
|
) {
|
||||||
|
hasNxVitePlugin = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasNxNuxtPlugin) {
|
||||||
nxJson.plugins.push({
|
nxJson.plugins.push({
|
||||||
plugin: '@nx/nuxt/plugin',
|
plugin: '@nx/nuxt/plugin',
|
||||||
options: {
|
options: {
|
||||||
buildTargetName: 'build',
|
buildTargetName: 'build',
|
||||||
testTargetName: 'test',
|
|
||||||
serveTargetName: 'serve',
|
serveTargetName: 'serve',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasNxVitePlugin) {
|
||||||
|
nxJson.plugins.push({
|
||||||
|
plugin: '@nx/vite/plugin',
|
||||||
|
options: {
|
||||||
|
testTargetName: 'test',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
updateNxJson(tree, nxJson);
|
updateNxJson(tree, nxJson);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,25 +34,6 @@ exports[`@nx/nuxt/plugin not root project should create nodes 1`] = `
|
|||||||
"cwd": "my-app",
|
"cwd": "my-app",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"test": {
|
|
||||||
"cache": true,
|
|
||||||
"command": "vitest run",
|
|
||||||
"inputs": [
|
|
||||||
"default",
|
|
||||||
"^production",
|
|
||||||
{
|
|
||||||
"externalDependencies": [
|
|
||||||
"vitest",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"options": {
|
|
||||||
"cwd": "my-app",
|
|
||||||
},
|
|
||||||
"outputs": [
|
|
||||||
"{workspaceRoot}/coverage/{projectRoot}",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -93,25 +74,6 @@ exports[`@nx/nuxt/plugin root project should create nodes 1`] = `
|
|||||||
"cwd": ".",
|
"cwd": ".",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"test": {
|
|
||||||
"cache": true,
|
|
||||||
"command": "vitest run",
|
|
||||||
"inputs": [
|
|
||||||
"default",
|
|
||||||
"^production",
|
|
||||||
{
|
|
||||||
"externalDependencies": [
|
|
||||||
"vitest",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"options": {
|
|
||||||
"cwd": ".",
|
|
||||||
},
|
|
||||||
"outputs": [
|
|
||||||
"{projectRoot}/coverage",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,16 +2,6 @@ import { CreateNodesContext } from '@nx/devkit';
|
|||||||
import { createNodes } from './plugin';
|
import { createNodes } from './plugin';
|
||||||
import { TempFs } from 'nx/src/internal-testing-utils/temp-fs';
|
import { TempFs } from 'nx/src/internal-testing-utils/temp-fs';
|
||||||
|
|
||||||
jest.mock('vite', () => ({
|
|
||||||
loadConfigFromFile: jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
path: 'vite.config.ts',
|
|
||||||
config: {},
|
|
||||||
dependencies: [],
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('@nuxt/kit', () => ({
|
jest.mock('@nuxt/kit', () => ({
|
||||||
loadNuxtConfig: jest.fn().mockImplementation(() => {
|
loadNuxtConfig: jest.fn().mockImplementation(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
|
|||||||
@ -16,7 +16,6 @@ import { existsSync, readdirSync } from 'fs';
|
|||||||
import { loadNuxtKitDynamicImport } from '../utils/executor-utils';
|
import { loadNuxtKitDynamicImport } from '../utils/executor-utils';
|
||||||
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
||||||
import { getLockFileName } from '@nx/js';
|
import { getLockFileName } from '@nx/js';
|
||||||
import { loadConfigFromFile, UserConfig } from 'vite';
|
|
||||||
|
|
||||||
const cachePath = join(projectGraphCacheDirectory, 'nuxt.hash');
|
const cachePath = join(projectGraphCacheDirectory, 'nuxt.hash');
|
||||||
const targetsCache = existsSync(cachePath) ? readTargetsCache() : {};
|
const targetsCache = existsSync(cachePath) ? readTargetsCache() : {};
|
||||||
@ -47,7 +46,6 @@ export const createDependencies: CreateDependencies = () => {
|
|||||||
export interface NuxtPluginOptions {
|
export interface NuxtPluginOptions {
|
||||||
buildTargetName?: string;
|
buildTargetName?: string;
|
||||||
serveTargetName?: string;
|
serveTargetName?: string;
|
||||||
testTargetName?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createNodes: CreateNodes<NuxtPluginOptions> = [
|
export const createNodes: CreateNodes<NuxtPluginOptions> = [
|
||||||
@ -91,34 +89,13 @@ async function buildNuxtTargets(
|
|||||||
options: NuxtPluginOptions,
|
options: NuxtPluginOptions,
|
||||||
context: CreateNodesContext
|
context: CreateNodesContext
|
||||||
) {
|
) {
|
||||||
let viteConfig:
|
|
||||||
| {
|
|
||||||
path: string;
|
|
||||||
config: UserConfig;
|
|
||||||
dependencies: string[];
|
|
||||||
}
|
|
||||||
| undefined;
|
|
||||||
if (
|
|
||||||
existsSync(
|
|
||||||
joinPathFragments(context.workspaceRoot, projectRoot, 'vitest.config.ts')
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
viteConfig = await loadConfigFromFile(
|
|
||||||
{
|
|
||||||
command: 'build',
|
|
||||||
mode: 'production',
|
|
||||||
},
|
|
||||||
joinPathFragments(context.workspaceRoot, projectRoot, 'vitest.config.ts')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const nuxtConfig: {
|
const nuxtConfig: {
|
||||||
buildDir: string;
|
buildDir: string;
|
||||||
} = await getInfoFromNuxtConfig(configFilePath, context, projectRoot);
|
} = await getInfoFromNuxtConfig(configFilePath, context, projectRoot);
|
||||||
|
|
||||||
const { buildOutputs, testOutputs } = getOutputs(
|
const { buildOutputs } = getOutputs(
|
||||||
nuxtConfig,
|
nuxtConfig,
|
||||||
viteConfig?.config,
|
|
||||||
projectRoot
|
projectRoot
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -135,12 +112,6 @@ async function buildNuxtTargets(
|
|||||||
|
|
||||||
targets[options.serveTargetName] = serveTarget(projectRoot);
|
targets[options.serveTargetName] = serveTarget(projectRoot);
|
||||||
|
|
||||||
targets[options.testTargetName] = testTarget(
|
|
||||||
namedInputs,
|
|
||||||
testOutputs,
|
|
||||||
projectRoot
|
|
||||||
);
|
|
||||||
|
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,30 +152,6 @@ function serveTarget(projectRoot: string) {
|
|||||||
return targetConfig;
|
return targetConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
function testTarget(
|
|
||||||
namedInputs: {
|
|
||||||
[inputName: string]: any[];
|
|
||||||
},
|
|
||||||
outputs: string[],
|
|
||||||
projectRoot: string
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
command: `vitest run`,
|
|
||||||
options: { cwd: projectRoot },
|
|
||||||
cache: true,
|
|
||||||
inputs: [
|
|
||||||
...('production' in namedInputs
|
|
||||||
? ['default', '^production']
|
|
||||||
: ['default', '^default']),
|
|
||||||
|
|
||||||
{
|
|
||||||
externalDependencies: ['vitest'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
outputs,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getInfoFromNuxtConfig(
|
async function getInfoFromNuxtConfig(
|
||||||
configFilePath: string,
|
configFilePath: string,
|
||||||
context: CreateNodesContext,
|
context: CreateNodesContext,
|
||||||
@ -226,18 +173,10 @@ async function getInfoFromNuxtConfig(
|
|||||||
|
|
||||||
function getOutputs(
|
function getOutputs(
|
||||||
nuxtConfig: { buildDir: string },
|
nuxtConfig: { buildDir: string },
|
||||||
viteConfig: UserConfig,
|
|
||||||
projectRoot: string
|
projectRoot: string
|
||||||
): {
|
): {
|
||||||
buildOutputs: string[];
|
buildOutputs: string[];
|
||||||
testOutputs: string[];
|
|
||||||
} {
|
} {
|
||||||
const reportsDirectory = normalizeOutputPath(
|
|
||||||
viteConfig?.['test']?.coverage?.reportsDirectory,
|
|
||||||
projectRoot,
|
|
||||||
'coverage'
|
|
||||||
);
|
|
||||||
|
|
||||||
let nuxtBuildDir = nuxtConfig?.buildDir;
|
let nuxtBuildDir = nuxtConfig?.buildDir;
|
||||||
if (nuxtConfig?.buildDir && basename(nuxtConfig?.buildDir) === '.nuxt') {
|
if (nuxtConfig?.buildDir && basename(nuxtConfig?.buildDir) === '.nuxt') {
|
||||||
// buildDir will most probably be `../dist/my-app/.nuxt`
|
// buildDir will most probably be `../dist/my-app/.nuxt`
|
||||||
@ -248,25 +187,23 @@ function getOutputs(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
const buildOutputPath =
|
const buildOutputPath =
|
||||||
normalizeOutputPath(nuxtBuildDir, projectRoot, 'dist') ??
|
normalizeOutputPath(nuxtBuildDir, projectRoot) ??
|
||||||
'{workspaceRoot}/dist/{projectRoot}';
|
'{workspaceRoot}/dist/{projectRoot}';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
buildOutputs: [buildOutputPath],
|
buildOutputs: [buildOutputPath],
|
||||||
testOutputs: [reportsDirectory],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeOutputPath(
|
function normalizeOutputPath(
|
||||||
outputPath: string | undefined,
|
outputPath: string | undefined,
|
||||||
projectRoot: string,
|
projectRoot: string
|
||||||
path: 'coverage' | 'dist'
|
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
if (!outputPath) {
|
if (!outputPath) {
|
||||||
if (projectRoot === '.') {
|
if (projectRoot === '.') {
|
||||||
return `{projectRoot}/${path}`;
|
return `{projectRoot}/dist`;
|
||||||
} else {
|
} else {
|
||||||
return `{workspaceRoot}/${path}/{projectRoot}`;
|
return `{workspaceRoot}/dist/{projectRoot}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isAbsolute(outputPath)) {
|
if (isAbsolute(outputPath)) {
|
||||||
@ -285,6 +222,5 @@ function normalizeOptions(options: NuxtPluginOptions): NuxtPluginOptions {
|
|||||||
options ??= {};
|
options ??= {};
|
||||||
options.buildTargetName ??= 'build';
|
options.buildTargetName ??= 'build';
|
||||||
options.serveTargetName ??= 'serve';
|
options.serveTargetName ??= 'serve';
|
||||||
options.testTargetName ??= 'test';
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`@nx/vite/plugin root project should create nodes 1`] = `
|
||||||
|
{
|
||||||
|
"projects": {
|
||||||
|
".": {
|
||||||
|
"root": ".",
|
||||||
|
"targets": {
|
||||||
|
"test": {
|
||||||
|
"cache": true,
|
||||||
|
"command": "vitest run",
|
||||||
|
"inputs": [
|
||||||
|
"default",
|
||||||
|
"^production",
|
||||||
|
{
|
||||||
|
"externalDependencies": [
|
||||||
|
"vitest",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": ".",
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
"{projectRoot}/coverage",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
48
packages/vite/src/plugins/plugin-vitest.spec.ts
Normal file
48
packages/vite/src/plugins/plugin-vitest.spec.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { CreateNodesContext } from '@nx/devkit';
|
||||||
|
import { createNodes } from './plugin';
|
||||||
|
import { TempFs } from 'nx/src/internal-testing-utils/temp-fs';
|
||||||
|
|
||||||
|
jest.mock('vite', () => ({
|
||||||
|
loadConfigFromFile: jest.fn().mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
path: 'vitest.config.ts',
|
||||||
|
config: {},
|
||||||
|
dependencies: [],
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('@nx/vite/plugin', () => {
|
||||||
|
let createNodesFunction = createNodes[1];
|
||||||
|
let context: CreateNodesContext;
|
||||||
|
describe('root project', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
context = {
|
||||||
|
nxJsonConfiguration: {
|
||||||
|
targetDefaults: {},
|
||||||
|
namedInputs: {
|
||||||
|
default: ['{projectRoot}/**/*'],
|
||||||
|
production: ['!{projectRoot}/**/*.spec.ts'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
workspaceRoot: '',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create nodes', async () => {
|
||||||
|
const nodes = await createNodesFunction(
|
||||||
|
'vitest.config.ts',
|
||||||
|
{
|
||||||
|
testTargetName: 'test',
|
||||||
|
},
|
||||||
|
context
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(nodes).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -52,7 +52,7 @@ export const createDependencies: CreateDependencies = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const createNodes: CreateNodes<VitePluginOptions> = [
|
export const createNodes: CreateNodes<VitePluginOptions> = [
|
||||||
'**/vite.config.{js,ts}',
|
'**/{vite,vitest}.config.{js,ts}',
|
||||||
async (configFilePath, options, context) => {
|
async (configFilePath, options, context) => {
|
||||||
const projectRoot = dirname(configFilePath);
|
const projectRoot = dirname(configFilePath);
|
||||||
// Do not create a project if package.json and project.json isn't there.
|
// Do not create a project if package.json and project.json isn't there.
|
||||||
@ -109,6 +109,7 @@ async function buildViteTargets(
|
|||||||
|
|
||||||
const targets: Record<string, TargetConfiguration> = {};
|
const targets: Record<string, TargetConfiguration> = {};
|
||||||
|
|
||||||
|
if (!configFilePath.includes('vitest.config')) {
|
||||||
targets[options.buildTargetName] = await buildTarget(
|
targets[options.buildTargetName] = await buildTarget(
|
||||||
options.buildTargetName,
|
options.buildTargetName,
|
||||||
namedInputs,
|
namedInputs,
|
||||||
@ -120,14 +121,15 @@ async function buildViteTargets(
|
|||||||
|
|
||||||
targets[options.previewTargetName] = previewTarget(projectRoot);
|
targets[options.previewTargetName] = previewTarget(projectRoot);
|
||||||
|
|
||||||
|
targets[options.serveStaticTargetName] = serveStaticTarget(options) as {};
|
||||||
|
}
|
||||||
|
|
||||||
targets[options.testTargetName] = await testTarget(
|
targets[options.testTargetName] = await testTarget(
|
||||||
namedInputs,
|
namedInputs,
|
||||||
testOutputs,
|
testOutputs,
|
||||||
projectRoot
|
projectRoot
|
||||||
);
|
);
|
||||||
|
|
||||||
targets[options.serveStaticTargetName] = serveStaticTarget(options) as {};
|
|
||||||
|
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user