Skip to content

Commit cf206c3

Browse files
authored
feat(core): support reading projects under new pnpm workspaces entry + skip writing empty nx property to pacakge.json for non-root projects (#29707)
This PR is a prerequisite to removing `nx` property from `package.json` files in the new TS setup. It fixes two issues: 1. We always write `nx` property in `package.json` even if it is empty. This should be done for root projects. 2. Adding an entry to `pnpm-workspace.yaml` is not picked up because `readProjectConfiguration` only reads the file from disk, not from virtual `Tree` This is the next PR to remove the property: #29705
1 parent 7f3ca1f commit cf206c3

File tree

3 files changed

+71
-10
lines changed

3 files changed

+71
-10
lines changed

packages/nx/src/generators/utils/project-configuration.spec.ts

+41
Original file line numberDiff line numberDiff line change
@@ -329,5 +329,46 @@ describe('project configuration', () => {
329329
`);
330330
expect(tree.exists('proj/project.json')).toBeFalsy();
331331
});
332+
333+
it('should avoid writing empty nx property', () => {
334+
writeJson(tree, 'proj/package.json', {
335+
name: 'proj',
336+
});
337+
338+
updateProjectConfiguration(tree, 'proj', {
339+
root: 'proj',
340+
});
341+
342+
const updatedProj = readProjectConfiguration(tree, 'proj');
343+
expect(updatedProj).toEqual({
344+
name: 'proj',
345+
root: 'proj',
346+
});
347+
348+
expect(tree.read('proj/package.json', 'utf-8')).toMatchInlineSnapshot(`
349+
"{
350+
"name": "proj"
351+
}
352+
"
353+
`);
354+
expect(tree.exists('proj/project.json')).toBeFalsy();
355+
356+
// Adding tags will add nx property
357+
updateProjectConfiguration(tree, 'proj', {
358+
root: 'proj',
359+
tags: ['test'],
360+
});
361+
expect(tree.read('proj/package.json', 'utf-8')).toMatchInlineSnapshot(`
362+
"{
363+
"name": "proj",
364+
"nx": {
365+
"tags": [
366+
"test"
367+
]
368+
}
369+
}
370+
"
371+
`);
372+
});
332373
});
333374
});

packages/nx/src/generators/utils/project-configuration.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,19 @@ function updateProjectConfigurationInPackageJson(
130130
packageJson.nx = {
131131
...packageJson.nx,
132132
...projectConfiguration,
133-
root: undefined,
134133
};
135134

136-
writeJson(tree, packageJsonFile, packageJson);
135+
// We don't want to ever this since it is inferred
136+
delete packageJson.nx.root;
137+
138+
// Only set `nx` property in `package.json` if it is a root project (necessary to mark it as Nx project),
139+
// or if there are properties to be set. If it is empty, then avoid it so we don't add unnecessary boilerplate.
140+
if (
141+
projectConfiguration.root === '.' ||
142+
Object.keys(packageJson.nx).length > 0
143+
) {
144+
writeJson(tree, packageJsonFile, packageJson);
145+
}
137146
}
138147

139148
function updateProjectConfigurationInProjectJson(
@@ -245,8 +254,15 @@ function readAndCombineAllProjectConfigurations(tree: Tree): {
245254
const patterns = [
246255
'**/project.json',
247256
'project.json',
248-
...getGlobPatternsFromPackageManagerWorkspaces(tree.root, (p) =>
249-
readJson(tree, p, { expectComments: true })
257+
...getGlobPatternsFromPackageManagerWorkspaces(
258+
tree.root,
259+
(p) => readJson(tree, p, { expectComments: true }),
260+
<T extends Object>(p) => {
261+
const content = tree.read(p, 'utf-8');
262+
const { load } = require('@zkochan/js-yaml');
263+
return load(content, { filename: p }) as T;
264+
},
265+
(p) => tree.exists(p)
250266
),
251267
];
252268
const globbedFiles = globWithWorkspaceContextSync(tree.root, patterns);

packages/nx/src/plugins/package-json/create-nodes.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,14 @@ export function buildProjectConfigurationFromPackageJson(
237237
*/
238238
export function getGlobPatternsFromPackageManagerWorkspaces(
239239
root: string,
240-
readJson: <T extends Object>(path: string) => T = <T extends Object>(path) =>
241-
readJsonFile<T>(join(root, path)) // making this an arg allows us to reuse in devkit
240+
// allow overwriting these args so we can use them in devkit
241+
readJson: <T extends Object>(path: string) => T = <T extends Object>(
242+
path: string
243+
) => readJsonFile<T>(join(root, path)),
244+
readYaml: <T extends Object>(path: string) => T = <T extends Object>(
245+
path: string
246+
) => readYamlFile<T>(join(root, path)),
247+
exists: (path: string) => boolean = (p) => existsSync(join(root, p))
242248
): string[] {
243249
try {
244250
const patterns: string[] = [];
@@ -252,12 +258,10 @@ export function getGlobPatternsFromPackageManagerWorkspaces(
252258
)
253259
);
254260

255-
if (existsSync(join(root, 'pnpm-workspace.yaml'))) {
261+
if (exists('pnpm-workspace.yaml')) {
256262
try {
257263
const { packages } =
258-
readYamlFile<{ packages: string[] }>(
259-
join(root, 'pnpm-workspace.yaml')
260-
) ?? {};
264+
readYaml<{ packages: string[] }>('pnpm-workspace.yaml') ?? {};
261265
patterns.push(...normalizePatterns(packages || []));
262266
} catch (e: unknown) {
263267
output.warn({

0 commit comments

Comments
 (0)