Skip to content

Commit

Permalink
feat(core): support reading projects under new pnpm workspaces entry …
Browse files Browse the repository at this point in the history
…+ 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
  • Loading branch information
jaysoo authored Jan 21, 2025
1 parent 7f3ca1f commit cf206c3
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 10 deletions.
41 changes: 41 additions & 0 deletions packages/nx/src/generators/utils/project-configuration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,5 +329,46 @@ describe('project configuration', () => {
`);
expect(tree.exists('proj/project.json')).toBeFalsy();
});

it('should avoid writing empty nx property', () => {
writeJson(tree, 'proj/package.json', {
name: 'proj',
});

updateProjectConfiguration(tree, 'proj', {
root: 'proj',
});

const updatedProj = readProjectConfiguration(tree, 'proj');
expect(updatedProj).toEqual({
name: 'proj',
root: 'proj',
});

expect(tree.read('proj/package.json', 'utf-8')).toMatchInlineSnapshot(`
"{
"name": "proj"
}
"
`);
expect(tree.exists('proj/project.json')).toBeFalsy();

// Adding tags will add nx property
updateProjectConfiguration(tree, 'proj', {
root: 'proj',
tags: ['test'],
});
expect(tree.read('proj/package.json', 'utf-8')).toMatchInlineSnapshot(`
"{
"name": "proj",
"nx": {
"tags": [
"test"
]
}
}
"
`);
});
});
});
24 changes: 20 additions & 4 deletions packages/nx/src/generators/utils/project-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,19 @@ function updateProjectConfigurationInPackageJson(
packageJson.nx = {
...packageJson.nx,
...projectConfiguration,
root: undefined,
};

writeJson(tree, packageJsonFile, packageJson);
// We don't want to ever this since it is inferred
delete packageJson.nx.root;

// Only set `nx` property in `package.json` if it is a root project (necessary to mark it as Nx project),
// or if there are properties to be set. If it is empty, then avoid it so we don't add unnecessary boilerplate.
if (
projectConfiguration.root === '.' ||
Object.keys(packageJson.nx).length > 0
) {
writeJson(tree, packageJsonFile, packageJson);
}
}

function updateProjectConfigurationInProjectJson(
Expand Down Expand Up @@ -245,8 +254,15 @@ function readAndCombineAllProjectConfigurations(tree: Tree): {
const patterns = [
'**/project.json',
'project.json',
...getGlobPatternsFromPackageManagerWorkspaces(tree.root, (p) =>
readJson(tree, p, { expectComments: true })
...getGlobPatternsFromPackageManagerWorkspaces(
tree.root,
(p) => readJson(tree, p, { expectComments: true }),
<T extends Object>(p) => {
const content = tree.read(p, 'utf-8');
const { load } = require('@zkochan/js-yaml');
return load(content, { filename: p }) as T;
},
(p) => tree.exists(p)
),
];
const globbedFiles = globWithWorkspaceContextSync(tree.root, patterns);
Expand Down
16 changes: 10 additions & 6 deletions packages/nx/src/plugins/package-json/create-nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,14 @@ export function buildProjectConfigurationFromPackageJson(
*/
export function getGlobPatternsFromPackageManagerWorkspaces(
root: string,
readJson: <T extends Object>(path: string) => T = <T extends Object>(path) =>
readJsonFile<T>(join(root, path)) // making this an arg allows us to reuse in devkit
// allow overwriting these args so we can use them in devkit
readJson: <T extends Object>(path: string) => T = <T extends Object>(
path: string
) => readJsonFile<T>(join(root, path)),
readYaml: <T extends Object>(path: string) => T = <T extends Object>(
path: string
) => readYamlFile<T>(join(root, path)),
exists: (path: string) => boolean = (p) => existsSync(join(root, p))
): string[] {
try {
const patterns: string[] = [];
Expand All @@ -252,12 +258,10 @@ export function getGlobPatternsFromPackageManagerWorkspaces(
)
);

if (existsSync(join(root, 'pnpm-workspace.yaml'))) {
if (exists('pnpm-workspace.yaml')) {
try {
const { packages } =
readYamlFile<{ packages: string[] }>(
join(root, 'pnpm-workspace.yaml')
) ?? {};
readYaml<{ packages: string[] }>('pnpm-workspace.yaml') ?? {};
patterns.push(...normalizePatterns(packages || []));
} catch (e: unknown) {
output.warn({
Expand Down

0 comments on commit cf206c3

Please # to comment.