Skip to content

Commit 9456a9d

Browse files
fix(qwik-nx): vite plugin exclude its project as a vendor root (#113)
1 parent a8ebc42 commit 9456a9d

File tree

2 files changed

+98
-12
lines changed

2 files changed

+98
-12
lines changed

packages/qwik-nx/src/plugins/qwik-nx-vite.plugin.spec.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,22 @@ describe('qwik-nx-vite plugin', () => {
7878
jest.spyOn(fs, 'readFileSync').mockReturnValue(tsConfigString1);
7979

8080
const getDecoratedPaths = async (
81-
options?: QwikNxVitePluginOptions
81+
options?: QwikNxVitePluginOptions,
82+
rootDir?: string
8283
): Promise<string[]> => {
83-
const plugin = qwikNxVite(options);
84+
const plugin = qwikNxVite({
85+
...options,
86+
// do not exclude any projects by setting "currentProjectName" to a not valid value
87+
currentProjectName:
88+
options?.currentProjectName || rootDir
89+
? options?.currentProjectName
90+
: 'mock',
91+
});
8492
const vendorRoots: string[] = [];
8593
const qwikViteMock = {
8694
name: 'vite-plugin-qwik',
8795
api: {
88-
getOptions: () => ({ vendorRoots }),
96+
getOptions: () => ({ vendorRoots, rootDir }),
8997
},
9098
};
9199
await (plugin.configResolved as any)({ plugins: [qwikViteMock] });
@@ -104,6 +112,31 @@ describe('qwik-nx-vite plugin', () => {
104112
]);
105113
});
106114

115+
describe('Should not include current porject as a vendor root for itself', () => {
116+
it('with project name specified', async () => {
117+
const paths = await getDecoratedPaths({
118+
currentProjectName: 'tmp-test-lib-a',
119+
});
120+
121+
expect(paths).toEqual([
122+
`${workspaceRoot}/libs/test-lib-b/src`,
123+
`${workspaceRoot}/libs/test-lib-c/nested-1/src`,
124+
`${workspaceRoot}/libs/test-lib-c/nested-2/src`,
125+
`${workspaceRoot}/libs/other/test-lib-a/src`,
126+
]);
127+
});
128+
it('implicitly by project path', async () => {
129+
const paths = await getDecoratedPaths(undefined, 'libs/test-lib-b');
130+
131+
expect(paths).toEqual([
132+
`${workspaceRoot}/libs/test-lib-a/src`,
133+
`${workspaceRoot}/libs/test-lib-c/nested-1/src`,
134+
`${workspaceRoot}/libs/test-lib-c/nested-2/src`,
135+
`${workspaceRoot}/libs/other/test-lib-a/src`,
136+
]);
137+
});
138+
});
139+
107140
describe('Name filter', () => {
108141
describe('As string', () => {
109142
it('Exclude', async () => {

packages/qwik-nx/src/plugins/qwik-nx-vite.plugin.ts

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
import { type Plugin } from 'vite';
2-
import { join } from 'path';
2+
import { join, relative } from 'path';
33
import { readWorkspaceConfig } from 'nx/src/project-graph/file-utils';
4-
import { ProjectConfiguration, workspaceRoot } from '@nrwl/devkit';
4+
import {
5+
createProjectRootMappingsFromProjectConfigurations,
6+
findProjectForPath,
7+
} from 'nx/src/project-graph/utils/find-project-for-path';
8+
import {
9+
ProjectConfiguration,
10+
ProjectsConfigurations,
11+
workspaceRoot,
12+
} from '@nrwl/devkit';
513
import { readFileSync } from 'fs';
614

715
interface QwikVitePluginStub {
816
api: {
9-
getOptions: () => { vendorRoots: string[] };
17+
getOptions: () => QwikVitePluginOptionsStub;
1018
};
1119
}
1220

21+
interface QwikVitePluginOptionsStub {
22+
vendorRoots: string[];
23+
rootDir: string;
24+
debug: boolean;
25+
}
26+
1327
export interface ProjectFilter {
1428
name?: string[] | RegExp;
1529
path?: RegExp;
@@ -18,6 +32,7 @@ export interface ProjectFilter {
1832
}
1933

2034
export interface QwikNxVitePluginOptions {
35+
currentProjectName?: string;
2136
includeProjects?: ProjectFilter;
2237
excludeProjects?: ProjectFilter;
2338
debug?: boolean;
@@ -30,7 +45,7 @@ export interface QwikNxVitePluginOptions {
3045
*
3146
* By default `qwikNxVite` plugin will provide Qwik with paths of all Nx projects, that are specified in the tsconfig.base.json.
3247
* However, this behavior might not be always suitable, especially in cases when you have code that you don't want the optimizer to go through.
33-
* It is possible to use specifically exclude or include certain projects using plugin options.
48+
* It is possible to specifically exclude or include certain projects using plugin options.
3449
*/
3550
export function qwikNxVite(options?: QwikNxVitePluginOptions): Plugin {
3651
const vitePlugin: Plugin = {
@@ -45,17 +60,49 @@ export function qwikNxVite(options?: QwikNxVitePluginOptions): Plugin {
4560
throw new Error('Missing vite-plugin-qwik');
4661
}
4762

48-
const vendorRoots = getVendorRoots(options);
63+
const pluginOptions = qwikPlugin.api.getOptions();
4964

50-
qwikPlugin.api.getOptions().vendorRoots.push(...vendorRoots);
65+
const vendorRoots = getVendorRoots(options, pluginOptions);
66+
67+
pluginOptions.vendorRoots.push(...vendorRoots);
5168
},
5269
};
5370

5471
return vitePlugin;
5572
}
5673

74+
function getCurrentProjectName(
75+
projectsConfigurations: ProjectsConfigurations,
76+
projectRootDir: string
77+
): string {
78+
const projectRootMappings =
79+
createProjectRootMappingsFromProjectConfigurations(
80+
projectsConfigurations.projects
81+
);
82+
const relativeDirname = relative(workspaceRoot, projectRootDir);
83+
const currentProjectName = findProjectForPath(
84+
relativeDirname,
85+
projectRootMappings
86+
);
87+
88+
if (!currentProjectName) {
89+
throw new Error(
90+
`Could not resolve the project name for path "${projectRootDir}"`
91+
);
92+
}
93+
return currentProjectName;
94+
}
95+
5796
/** Retrieves vendor roots and applies necessary filtering */
58-
function getVendorRoots(options?: QwikNxVitePluginOptions): string[] {
97+
function getVendorRoots(
98+
options: QwikNxVitePluginOptions | undefined,
99+
qwikOptions: QwikVitePluginOptionsStub
100+
): string[] {
101+
const log = (...str: unknown[]) => {
102+
(options?.debug || qwikOptions.debug) &&
103+
console.debug(`[QWIK-NX-VITE PLUGIN:]`, ...str);
104+
};
105+
59106
const workspaceConfig = readWorkspaceConfig({ format: 'nx' });
60107

61108
const baseTsConfig = JSON.parse(
@@ -67,13 +114,19 @@ function getVendorRoots(options?: QwikNxVitePluginOptions): string[] {
67114

68115
let projects = Object.values(workspaceConfig.projects);
69116

117+
const currentProjectName =
118+
options?.currentProjectName ??
119+
getCurrentProjectName(workspaceConfig, qwikOptions.rootDir);
120+
121+
projects = projects.filter((p) => p.name !== currentProjectName);
122+
70123
projects.forEach((p) => (p.sourceRoot ??= p.root));
71124

72125
projects = filterProjects(projects, options?.excludeProjects, true);
73126
projects = filterProjects(projects, options?.includeProjects, false);
74127

75128
if (options?.debug) {
76-
console.log(
129+
log(
77130
'Projects after applying include\\exclude filters:',
78131
projects.map((p) => p.name)
79132
);
@@ -84,7 +137,7 @@ function getVendorRoots(options?: QwikNxVitePluginOptions): string[] {
84137
);
85138

86139
if (options?.debug) {
87-
console.log(
140+
log(
88141
'Projects after excluding those not in tsconfig.base.json:',
89142
projects.map((p) => p.name)
90143
);

0 commit comments

Comments
 (0)