diff --git a/scripts/monorepo/src/getDependencies.d.ts b/scripts/monorepo/src/getDependencies.d.ts
index 710fff0fdd16cc..443defe0a1fb57 100644
--- a/scripts/monorepo/src/getDependencies.d.ts
+++ b/scripts/monorepo/src/getDependencies.d.ts
@@ -2,16 +2,19 @@
// - modules(projects) written in TS not having enabled `checkJS:true` wont infer types from .js files, thus the API will have `any` type.
// This errors in strict ts check mode.
-///
export declare function getDependencies(packageName: string): Promise<{
dependencies: Dependency[];
devDependencies: Dependency[];
all: Dependency[];
- projectGraph: import('lerna/utils').ProjectGraphWithPackages;
+ projectGraph: import('@nx/devkit').ProjectGraph;
+ getProjectPackageJsonInfo: (
+ project: string,
+ projectGraph: import('@nx/devkit').ProjectGraph,
+ ) => import('./types').PackageJson & { absoluteRootPath: string };
}>;
type Dependency = {
name: string;
isTopLevel: boolean;
- dependencyType: import('lerna/utils').ProjectGraphWorkspacePackageDependency['dependencyCollection'];
+ dependencyType: 'dependencies' | 'devDependencies' | 'optionalDependencies' | null;
};
diff --git a/scripts/monorepo/src/getDependencies.js b/scripts/monorepo/src/getDependencies.js
index 75d44dab5b1f34..3bdaa9a4abc98e 100644
--- a/scripts/monorepo/src/getDependencies.js
+++ b/scripts/monorepo/src/getDependencies.js
@@ -1,17 +1,96 @@
-const lernaUtils = require('lerna/utils');
+const fs = require('node:fs');
+
+const { createProjectGraphAsync, joinPathFragments, workspaceRoot } = require('@nx/devkit');
/**
* @typedef {{
name: string,
isTopLevel: boolean,
- dependencyType: lernaUtils.ProjectGraphWorkspacePackageDependency['dependencyCollection'],
+ dependencyType: 'dependencies' | 'devDependencies' | 'optionalDependencies' | null,
}} Dependency
*/
+/** @typedef {import('./types').PackageJson & {absoluteRootPath:string}} PackageJsonInfoData */
+
+/**
+ * @type {Record}
+ */
+const packageJsonInfo = {};
+
/**
*
* @param {string} project
- * @param {lernaUtils.ProjectGraphWithPackages} projectGraph
+ * @param {import('@nx/devkit').ProjectGraph} projectGraph
+ */
+function getProjectPackageJsonInfo(project, projectGraph) {
+ const cachedInfo = packageJsonInfo[project];
+ if (cachedInfo) {
+ return cachedInfo;
+ }
+
+ const metadata = projectGraph.nodes[project];
+ const absoluteRootPath = joinPathFragments(workspaceRoot, metadata.data.root);
+ const pkgJsonContent = fs.readFileSync(joinPathFragments(workspaceRoot, metadata.data.root, 'package.json'), 'utf-8');
+
+ /** @type {PackageJsonInfoData} */
+ const pkgJson = JSON.parse(pkgJsonContent);
+ pkgJson.absoluteRootPath = absoluteRootPath;
+
+ // store in cache
+ packageJsonInfo[project] = pkgJson;
+
+ return pkgJson;
+}
+
+/**
+ * Returns local dependencies of provided project. Local means dependency from within workspace
+ * @param {string} project
+ * @param {import('@nx/devkit').ProjectGraph} projectGraph
+ */
+function getLocalDeps(project, projectGraph) {
+ const deps = projectGraph.dependencies[project];
+ const pkgJson = getProjectPackageJsonInfo(project, projectGraph);
+
+ /**
+ * @type {Array<{target:string;dependencyType:ReturnType}>}
+ */
+ const localDeps = [];
+ for (const dep of deps) {
+ if (!dep.target.startsWith('npm:')) {
+ const dependencyType = getDepType(dep.target, pkgJson);
+ localDeps.push({ target: dep.target, dependencyType });
+ }
+ }
+
+ if (localDeps.length > 0) {
+ return localDeps;
+ }
+
+ return null;
+}
+/**
+ *
+ * @param {string} pkgName
+ * @param {import('./types').PackageJson} json
+ * @returns
+ */
+function getDepType(pkgName, json) {
+ if (json.dependencies?.[pkgName]) {
+ return 'dependencies';
+ }
+ if (json.devDependencies?.[pkgName]) {
+ return 'devDependencies';
+ }
+ if (json.optionalDependencies?.[pkgName]) {
+ return 'optionalDependencies';
+ }
+ return null;
+}
+
+/**
+ *
+ * @param {string} project
+ * @param {import('@nx/devkit').ProjectGraph} projectGraph
* @param {*} options
* @param {Dependency[]} _acc
* @param {boolean} _areTopLevelDeps
@@ -27,28 +106,26 @@ function collectDependencies(
_acc = [],
_areTopLevelDeps = true,
) {
- if (!projectGraph.localPackageDependencies[project]) {
+ const localDeps = getLocalDeps(project, projectGraph);
+
+ if (!localDeps) {
return _acc;
}
- projectGraph.localPackageDependencies[project].forEach(dependency => {
+ localDeps.forEach(dependency => {
const isDependencyAlreadyCollected = _acc.some(dep => dep.name === dependency.target);
if (isDependencyAlreadyCollected) {
return;
}
- if (
- options.dependenciesOnly &&
- dependency.dependencyCollection &&
- dependency.dependencyCollection !== 'dependencies'
- ) {
+ if (options.dependenciesOnly && dependency.dependencyType && dependency.dependencyType !== 'dependencies') {
return;
}
_acc.push({
name: dependency.target,
- dependencyType: dependency.dependencyCollection,
+ dependencyType: dependency.dependencyType,
isTopLevel: _areTopLevelDeps,
});
@@ -65,7 +142,7 @@ function collectDependencies(
* @param {string} packageName - including `@fluentui/` prefix
*/
async function getDependencies(packageName) {
- const { projectGraph } = await lernaUtils.detectProjects();
+ const projectGraph = await createProjectGraphAsync();
const allDepsGraph = collectDependencies(packageName, projectGraph, { shallow: false, dependenciesOnly: false });
const depsGraph = collectDependencies(packageName, projectGraph, { shallow: false, dependenciesOnly: true });
@@ -76,6 +153,7 @@ async function getDependencies(packageName) {
devDependencies: devDepsGraph,
all: allDepsGraph,
projectGraph,
+ getProjectPackageJsonInfo,
};
}
diff --git a/scripts/monorepo/src/getDependencies.spec.js b/scripts/monorepo/src/getDependencies.spec.js
index 4fc69c2f41ff26..5f6d84263c5828 100644
--- a/scripts/monorepo/src/getDependencies.spec.js
+++ b/scripts/monorepo/src/getDependencies.spec.js
@@ -96,13 +96,13 @@ describe(`#getDependencies`, () => {
`);
});
- it(`should provide similar api like 'new Project(root).getPackages()'`, async () => {
- const { projectGraph } = await getDependencies(packageName);
- const packageInfo = projectGraph.nodes[packageName].package;
+ it(`should provide access to package.json`, async () => {
+ const { projectGraph, getProjectPackageJsonInfo } = await getDependencies(packageName);
+ const packageInfo = getProjectPackageJsonInfo(packageName, projectGraph);
- expect(packageInfo?.location).toEqual(expect.stringContaining('packages/react-components/react-text'));
+ expect(packageInfo.absoluteRootPath).toEqual(expect.stringContaining('packages/react-components/react-text'));
expect(packageInfo?.dependencies).toEqual(expect.any(Object));
- expect(packageInfo?.get('main')).toEqual('lib-commonjs/index.js');
- expect(packageInfo?.get('module')).toEqual('lib/index.js');
+ expect(packageInfo?.main).toEqual('lib-commonjs/index.js');
+ expect(packageInfo?.module).toEqual('lib/index.js');
});
});
diff --git a/scripts/projects-test/src/packPackages.ts b/scripts/projects-test/src/packPackages.ts
index 30176ff5ccb58e..40e94665e0cec7 100644
--- a/scripts/projects-test/src/packPackages.ts
+++ b/scripts/projects-test/src/packPackages.ts
@@ -32,7 +32,7 @@ export async function packProjectPackages(logger: Function, project: string): Pr
packedPackages = {};
- const { dependencies: projectDependencies, projectGraph } = await getDependencies(project);
+ const { dependencies: projectDependencies, projectGraph, getProjectPackageJsonInfo } = await getDependencies(project);
// add provided package to be packaged
projectDependencies.unshift({
name: project,
@@ -51,13 +51,13 @@ export async function packProjectPackages(logger: Function, project: string): Pr
await Promise.all(
projectDependencies.map(async projectConfig => {
const packageName = projectConfig.name;
- const packageInfo = projectGraph.nodes[packageName].package;
+ const packageInfo = getProjectPackageJsonInfo(packageName, projectGraph);
if (!packageInfo) {
throw new Error(`Package ${packageName} doesn't exist`);
}
- const packagePath = packageInfo.location;
- const packageMain = packageInfo.get('main') as string | undefined;
+ const packagePath = packageInfo.absoluteRootPath;
+ const packageMain = packageInfo.main;
const entryPointPath = packageMain ? path.join(packagePath, packageMain) : '';
if (!fs.existsSync(entryPointPath)) {
throw new Error(
diff --git a/typings/lerna/index.d.ts b/typings/lerna/index.d.ts
deleted file mode 100644
index 791c6ee22eb007..00000000000000
--- a/typings/lerna/index.d.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-// Type definitions for lerna 7.0.0
-
-// NOTE: types taken from @see https://github.com/lerna/lerna/blob/main/libs/core/src/lib/project-graph-with-packages.ts
-// ISSUE: https://github.com/lerna/lerna/issues/3851
-
-declare module 'lerna/utils' {
- import type { ProjectFileMap, ProjectGraph, ProjectGraphDependency, ProjectGraphProjectNode } from '@nx/devkit';
-
- interface RawManifest {
- name: string;
- version: string;
- description?: string;
- private?: boolean;
- bin?: Record | string;
- scripts?: Record;
- dependencies?: Record;
- devDependencies?: Record;
- optionalDependencies?: Record;
- peerDependencies?: Record;
- publishConfig?: Record<'directory' | 'registry' | 'tag', string>;
- workspaces?: string[];
- nx?: Record;
- gitHead?: string;
- lerna?: RawManifestLernaConfig;
- }
-
- interface RawManifestLernaConfig {
- command?: {
- publish?: {
- directory?: string;
- assets?: AssetDefinition[];
- };
- };
- }
- type AssetDefinition = string | { from: string; to: string };
-
- interface Package extends Omit {
- /**
- * Map-like retrieval of arbitrary values from package.json
- */
- get(key: string): unknown;
- binLocation: string;
-
- resolved: Record;
- /**
- * path to package.json
- */
- manifestLocation: string;
- location: string;
- lernaConfig: RawManifest['lerna'] | undefined;
- }
-
- type ExtendedNpaResult = {
- workspaceSpec?: string;
- workspaceAlias?: string;
- };
-
- interface ProjectGraphProjectNodeWithPackage extends ProjectGraphProjectNode {
- package: Package | null;
- }
- interface ProjectGraphWorkspacePackageDependency extends ProjectGraphDependency {
- targetVersionMatchesDependencyRequirement: boolean;
- targetResolvedNpaResult: ExtendedNpaResult;
- dependencyCollection: 'dependencies' | 'devDependencies' | 'optionalDependencies'; // lerna doesn't manage peer dependencies
- }
- export interface ProjectGraphWithPackages extends ProjectGraph {
- nodes: Record;
- localPackageDependencies: Record;
- }
-
- export function detectProjects(): Promise<{
- projectGraph: ProjectGraphWithPackages;
- projectFileMap: ProjectFileMap;
- }>;
-}
diff --git a/typings/lerna/tsconfig.json b/typings/lerna/tsconfig.json
deleted file mode 100644
index c6f8b0a935c4c2..00000000000000
--- a/typings/lerna/tsconfig.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {},
- "include": ["*.d.ts"]
-}
diff --git a/typings/tsconfig.json b/typings/tsconfig.json
index 66aabec9b543cb..d2324f1f1c570d 100644
--- a/typings/tsconfig.json
+++ b/typings/tsconfig.json
@@ -30,9 +30,6 @@
},
{
"path": "./find-free-port/tsconfig.json"
- },
- {
- "path": "./lerna/tsconfig.json"
}
]
}