Skip to content

Commit

Permalink
fix(core): require.resolve(m/package.json) is not guarunteed to work …
Browse files Browse the repository at this point in the history
…for modern module format
  • Loading branch information
AgentEnder committed May 27, 2022
1 parent fea7e39 commit 4d9ed07
Show file tree
Hide file tree
Showing 17 changed files with 111 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Schema } from './schema';
import { watch } from 'chokidar';
import { platform } from 'os';
import { resolve } from 'path';
import { readModulePackageJson } from 'nx/src/utils/package-json';

// platform specific command name
const pmCmd = platform() === 'win32' ? `npx.cmd` : 'npx';
Expand Down Expand Up @@ -153,7 +154,7 @@ export default async function* fileServerExecutor(
const outputPath = getBuildTargetOutputPath(options, context);
const args = getHttpServerArgs(options);

const pathToHttpServerPkgJson = require.resolve('http-server/package.json');
const pathToHttpServerPkgJson = readModulePackageJson('http-server').path;
const pathToHttpServerBin = readJsonFile(pathToHttpServerPkgJson).bin[
'http-server'
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { resolveUserExistingPrettierConfig } from '@nrwl/workspace/src/utilities
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
import { prettierVersion } from '@nrwl/workspace/src/utils/versions';
import { readFileSync } from 'fs';
import { readModulePackageJson } from 'nx/src/utils/package-json';
import { dirname, join } from 'path';
import { angularDevkitVersion, nxVersion } from '../../../utils/versions';
import { GeneratorOptions } from '../schema';
Expand Down Expand Up @@ -82,7 +83,7 @@ export function createNxJson(
}

export function decorateAngularCli(tree: Tree): void {
const nrwlWorkspacePath = require.resolve('@nrwl/workspace/package.json');
const nrwlWorkspacePath = readModulePackageJson('@nrwl/workspace').path;
const decorateCli = readFileSync(
join(
dirname(nrwlWorkspacePath),
Expand Down
5 changes: 2 additions & 3 deletions packages/angular/src/utils/mfe/mfe-webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
readTsConfig,
} from '@nrwl/workspace/src/utilities/typescript';
import { existsSync, lstatSync, readdirSync } from 'fs';
import { readModulePackageJson } from 'nx/src/utils/package-json';
import { dirname, join, normalize, relative } from 'path';
import { ParsedCommandLine } from 'typescript';
import { NormalModuleReplacementPlugin } from 'webpack';
Expand Down Expand Up @@ -143,9 +144,7 @@ function collectPackageSecondaryEntryPoints(
): void {
let pathToPackage: string;
try {
const packageJsonPath = require.resolve(`${pkgName}/package.json`, {
paths: [workspaceRoot],
});
const packageJsonPath = readModulePackageJson(pkgName).path;
pathToPackage = dirname(packageJsonPath);
} catch {
// the package.json might not resolve if the package has the "exports"
Expand Down
6 changes: 2 additions & 4 deletions packages/make-angular-cli-faster/src/utilities/migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from '@nrwl/devkit';
import { execSync } from 'child_process';
import { prompt } from 'enquirer';
import { readModulePackageJson } from 'nx/src/utils/package-json';
import { lt, lte, major, satisfies } from 'semver';
import { resolvePackageVersion } from './package-manager';
import { MigrationDefinition } from './types';
Expand Down Expand Up @@ -173,10 +174,7 @@ async function promptForVersion(version: string): Promise<boolean> {
}

function getInstalledAngularVersion(): string {
const packageJsonPath = require.resolve('@angular/core/package.json', {
paths: [workspaceRoot],
});
return readJsonFile(packageJsonPath).version;
return readModulePackageJson('@angular/core').packageJson.version;
}

async function normalizeVersion(version: string): Promise<string> {
Expand Down
5 changes: 2 additions & 3 deletions packages/nx/src/adapter/ngcli-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
WorkspaceJsonConfiguration,
} from '../config/workspace-json-project-json';
import { readNxJson } from '../generators/utils/project-configuration';
import { readModulePackageJson } from '../utils/package-json';

export async function scheduleTarget(
root: string,
Expand Down Expand Up @@ -891,9 +892,7 @@ function resolveMigrationsCollection(name: string): string {
} else {
let packageJsonPath;
try {
packageJsonPath = require.resolve(join(name, 'package.json'), {
paths: [process.cwd()],
});
packageJsonPath = readModulePackageJson(name, [process.cwd()]).path;
} catch (e) {
// workaround for a bug in node 12
packageJsonPath = require.resolve(
Expand Down
15 changes: 7 additions & 8 deletions packages/nx/src/command-line/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
NxMigrationsConfiguration,
PackageGroup,
PackageJson,
readModulePackageJson,
} from '../utils/package-json';
import {
createTempNpmDirectory,
Expand Down Expand Up @@ -466,10 +467,8 @@ function versions(root: string, from: Record<string, string>) {
}

if (!cache[packageName]) {
const packageJsonPath = require.resolve(`${packageName}/package.json`, {
paths: [root],
});
cache[packageName] = readJsonFile(packageJsonPath).version;
const { packageJson } = readModulePackageJson(packageName, [root]);
cache[packageName] = packageJson.version;
}

return cache[packageName];
Expand Down Expand Up @@ -713,11 +712,11 @@ function readPackageMigrationConfig(
packageName: string,
dir: string
): PackageMigrationConfig {
const packageJsonPath = require.resolve(`${packageName}/package.json`, {
paths: [dir],
});
const { path: packageJsonPath, packageJson: json } = readModulePackageJson(
packageName,
[dir]
);

const json = readJsonFile<PackageJson>(packageJsonPath);
const migrationConfigOrFile = json['nx-migrations'] || json['ng-update'];

if (!migrationConfigOrFile) {
Expand Down
15 changes: 7 additions & 8 deletions packages/nx/src/command-line/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getPackageManagerVersion,
} from '../utils/package-manager';
import { readJsonFile } from '../utils/fileutils';
import { PackageJson, readModulePackageJson } from '../utils/package-json';

export const packagesWeCareAbout = [
'nx',
Expand Down Expand Up @@ -77,19 +78,16 @@ export function reportHandler() {
});
}

export function readPackageJson(p: string) {
export function readPackageJson(p: string): PackageJson | null {
try {
const packageJsonPath = require.resolve(`${p}/package.json`, {
paths: [workspaceRoot],
});
return readJsonFile(packageJsonPath);
return readModulePackageJson(p).packageJson;
} catch {
return {};
return null;
}
}

export function readPackageVersion(p: string): string {
return readPackageJson(p).version || 'Not Found';
return readPackageJson(p)?.version || 'Not Found';
}

export function findInstalledCommunityPlugins(): {
Expand All @@ -116,7 +114,8 @@ export function findInstalledCommunityPlugins(): {
return arr;
}
try {
const depPackageJson = readPackageJson(nextDep);
const depPackageJson: Partial<PackageJson> =
readPackageJson(nextDep) || {};
if (
[
'ng-update',
Expand Down
12 changes: 6 additions & 6 deletions packages/nx/src/utils/nx-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Workspaces } from '../config/workspaces';

import { workspaceRoot } from '../utils/app-root';
import { readJsonFile } from '../utils/fileutils';
import { PackageJson } from './package-json';
import { PackageJson, readModulePackageJson } from './package-json';
import { registerTsProject } from './register';
import {
ProjectConfiguration,
Expand Down Expand Up @@ -117,11 +117,12 @@ export function readPluginPackageJson(
path: string;
json: PackageJson;
} {
let packageJsonPath: string;
try {
packageJsonPath = require.resolve(`${pluginName}/package.json`, {
paths,
});
const result = readModulePackageJson(pluginName, paths);
return {
json: result.packageJson,
path: result.path,
};
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND') {
const localPluginPath = resolveLocalNxPlugin(pluginName);
Expand All @@ -138,7 +139,6 @@ export function readPluginPackageJson(
}
throw e;
}
return { json: readJsonFile(packageJsonPath), path: packageJsonPath };
}

/**
Expand Down
20 changes: 20 additions & 0 deletions packages/nx/src/utils/package-json.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { join } from 'path';
import { workspaceRoot } from './app-root';
import { readJsonFile } from './fileutils';
import {
buildTargetFromScript,
PackageJson,
PackageJsonTargetConfiguration,
readModulePackageJson,
} from './package-json';

describe('buildTargetFromScript', () => {
Expand Down Expand Up @@ -38,3 +43,18 @@ describe('buildTargetFromScript', () => {
expect(target.executor).toEqual('nx:run-script');
});
});

const rootPackageJson: PackageJson = readJsonFile(
join(workspaceRoot, 'package.json')
);

const dependencies = [
...Object.keys(rootPackageJson.dependencies),
...Object.keys(rootPackageJson.devDependencies),
];

describe('readModulePackageJson', () => {
it.each(dependencies)(`should be able to find %s`, (s) => {
expect(() => readModulePackageJson(s)).not.toThrow();
});
});
44 changes: 44 additions & 0 deletions packages/nx/src/utils/package-json.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { existsSync } from 'fs';
import { dirname, join } from 'path';
import { TargetConfiguration } from '../config/workspace-json-project-json';
import { workspaceRoot } from './app-root';
import { readJsonFile } from './fileutils';

export type PackageJsonTargetConfiguration = Omit<
TargetConfiguration,
Expand Down Expand Up @@ -69,3 +73,43 @@ export function buildTargetFromScript(
},
};
}

export function readModulePackageJson(
moduleSpecifier: string,
requirePaths = [workspaceRoot]
): {
packageJson: PackageJson;
path: string;
} {
let packageJsonPath: string;
try {
packageJsonPath = require.resolve(`${moduleSpecifier}/package.json`, {
paths: requirePaths,
});
} catch (e) {
console.log(e);
const entryPoint = require.resolve(moduleSpecifier, {
paths: requirePaths,
});
let moduleRootPath = dirname(entryPoint);
packageJsonPath = join(moduleRootPath, 'package.json');

while (!existsSync(packageJsonPath)) {
moduleRootPath = dirname(moduleRootPath);
packageJsonPath = join(moduleRootPath, 'package.json');
}
}

const packageJson = readJsonFile(packageJsonPath);

if (!(packageJson.name === moduleSpecifier)) {
throw new Error(
`Found module ${packageJson.name} while trying to locate ${moduleSpecifier}/package.json`
);
}

return {
packageJson,
path: packageJsonPath,
};
}
8 changes: 3 additions & 5 deletions packages/nx/src/utils/package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { dirname, join } from 'path';
import { dirSync } from 'tmp';
import { promisify } from 'util';
import { readJsonFile, writeJsonFile } from './fileutils';
import { PackageJson } from './package-json';
import { PackageJson, readModulePackageJson } from './package-json';
import { gte, lt } from 'semver';

const execAsync = promisify(exec);
Expand Down Expand Up @@ -198,11 +198,9 @@ export async function resolvePackageVersionUsingInstallation(
const pmc = getPackageManagerCommand();
await execAsync(`${pmc.add} ${packageName}@${version}`, { cwd: dir });

const packageJsonPath = require.resolve(`${packageName}/package.json`, {
paths: [dir],
});
const { packageJson } = readModulePackageJson(packageName, [dir]);

return readJsonFile<PackageJson>(packageJsonPath).version;
return packageJson.version;
} finally {
await cleanup();
}
Expand Down
3 changes: 2 additions & 1 deletion packages/nx/src/utils/plugins/installed-plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { CommunityPlugin, CorePlugin, PluginCapabilities } from './models';
import { getPluginCapabilities } from './plugin-capabilities';
import { hasElements } from './shared';
import { readJsonFile } from '../fileutils';
import { readModulePackageJson } from '../package-json';

export function getInstalledPluginsFromPackageJson(
workspaceRoot: string,
Expand All @@ -25,7 +26,7 @@ export function getInstalledPluginsFromPackageJson(
try {
// Check for `package.json` existence instead of requiring the module itself
// because malformed entries like `main`, may throw false exceptions.
require.resolve(`${name}/package.json`, { paths: [workspaceRoot] });
readModulePackageJson(name, [workspaceRoot]);
return true;
} catch {
return false;
Expand Down
7 changes: 3 additions & 4 deletions packages/nx/src/utils/plugins/plugin-capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { PluginCapabilities } from './models';
import { hasElements } from './shared';
import { readJsonFile } from '../fileutils';
import { getPackageManagerCommand } from '../package-manager';
import { readModulePackageJson } from '../package-json';

function tryGetCollection<T extends object>(
packageJsonPath: string,
Expand All @@ -29,10 +30,8 @@ export function getPluginCapabilities(
pluginName: string
): PluginCapabilities | null {
try {
const packageJsonPath = require.resolve(`${pluginName}/package.json`, {
paths: [workspaceRoot],
});
const packageJson = readJsonFile(packageJsonPath);
const { packageJson, path: packageJsonPath } =
readModulePackageJson(pluginName);
return {
name: pluginName,
generators:
Expand Down
3 changes: 2 additions & 1 deletion packages/web/src/executors/file-server/file-server.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Schema } from './schema';
import { watch } from 'chokidar';
import { platform } from 'os';
import { resolve } from 'path';
import { readModulePackageJson } from 'nx/src/utils/package-json';

// platform specific command name
const pmCmd = platform() === 'win32' ? `npx.cmd` : 'npx';
Expand Down Expand Up @@ -153,7 +154,7 @@ export default async function* fileServerExecutor(
const outputPath = getBuildTargetOutputPath(options, context);
const args = getHttpServerArgs(options);

const pathToHttpServerPkgJson = require.resolve('http-server/package.json');
const pathToHttpServerPkgJson = readModulePackageJson('http-server').path;
const pathToHttpServerBin = readJsonFile(pathToHttpServerPkgJson).bin[
'http-server'
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { output } from '../output';
import type { CommunityPlugin, CorePlugin, PluginCapabilities } from './models';
import { getPluginCapabilities } from './plugin-capabilities';
import { hasElements } from './shared';
import { readModulePackageJson } from 'nx/src/utils/package-json';

export function getInstalledPluginsFromPackageJson(
workspaceRoot: string,
Expand All @@ -25,7 +26,7 @@ export function getInstalledPluginsFromPackageJson(
try {
// Check for `package.json` existence instead of requiring the module itself
// because malformed entries like `main`, may throw false exceptions.
require.resolve(`${name}/package.json`, { paths: [workspaceRoot] });
readModulePackageJson(name);
return true;
} catch {
return false;
Expand Down

0 comments on commit 4d9ed07

Please sign in to comment.