diff --git a/packages/angular/cli/lib/init.ts b/packages/angular/cli/lib/init.ts index ce4014a4db80..401fb06485a2 100644 --- a/packages/angular/cli/lib/init.ts +++ b/packages/angular/cli/lib/init.ts @@ -9,6 +9,7 @@ import 'symbol-observable'; // symbol polyfill must go first import { promises as fs } from 'fs'; +import { createRequire } from 'module'; import * as path from 'path'; import { SemVer, major } from 'semver'; import { colors } from '../src/utilities/color'; @@ -47,7 +48,8 @@ let forceExit = false; try { // No error implies a projectLocalCli, which will load whatever // version of ng-cli you have installed in a local package.json - const projectLocalCli = require.resolve('@angular/cli', { paths: [process.cwd()] }); + const cwdRequire = createRequire(process.cwd() + '/'); + const projectLocalCli = cwdRequire.resolve('@angular/cli'); cli = await import(projectLocalCli); const globalVersion = new SemVer(VERSION.full); diff --git a/packages/angular/cli/src/command-builder/utilities/schematic-engine-host.ts b/packages/angular/cli/src/command-builder/utilities/schematic-engine-host.ts index 19af7c6bb8ed..0007ffe2f673 100644 --- a/packages/angular/cli/src/command-builder/utilities/schematic-engine-host.ts +++ b/packages/angular/cli/src/command-builder/utilities/schematic-engine-host.ts @@ -10,7 +10,7 @@ import { RuleFactory, SchematicsException, Tree } from '@angular-devkit/schemati import { FileSystemCollectionDesc, NodeModulesEngineHost } from '@angular-devkit/schematics/tools'; import { readFileSync } from 'fs'; import { parse as parseJson } from 'jsonc-parser'; -import nodeModule from 'module'; +import { createRequire } from 'module'; import { dirname, resolve } from 'path'; import { Script } from 'vm'; import { assertIsError } from '../../utilities/error'; @@ -63,7 +63,8 @@ export class SchematicEngineHost extends NodeModulesEngineHost { // Mimic behavior of ExportStringRef class used in default behavior const fullPath = path[0] === '.' ? resolve(parentPath ?? process.cwd(), path) : path; - const schematicFile = require.resolve(fullPath, { paths: [parentPath] }); + const referenceRequire = createRequire(__filename); + const schematicFile = referenceRequire.resolve(fullPath, { paths: [parentPath] }); if (shouldWrapSchematic(schematicFile, !!collectionDescription?.encapsulation)) { const schematicPath = dirname(schematicFile); @@ -128,8 +129,8 @@ function wrap( moduleCache: Map, exportName?: string, ): () => unknown { - const hostRequire = nodeModule.createRequire(__filename); - const schematicRequire = nodeModule.createRequire(schematicFile); + const hostRequire = createRequire(__filename); + const schematicRequire = createRequire(schematicFile); const customRequire = function (id: string) { if (legacyModules[id]) { diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index d65cd78e4278..3e62345b9b89 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -8,6 +8,7 @@ import { analytics, tags } from '@angular-devkit/core'; import { NodePackageDoesNotSupportSchematics } from '@angular-devkit/schematics/tools'; +import { createRequire } from 'module'; import npa from 'npm-package-arg'; import { dirname, join } from 'path'; import { compare, intersects, prerelease, satisfies, valid } from 'semver'; @@ -61,6 +62,7 @@ export class AddCommandModule longDescriptionPath = join(__dirname, 'long-description.md'); protected override allowPrivateSchematics = true; private readonly schematicName = 'ng-add'; + private rootRequire = createRequire(this.context.root + '/'); override async builder(argv: Argv): Promise> { const localYargs = (await super.builder(argv)) @@ -276,9 +278,8 @@ export class AddCommandModule packageIdentifier.raw, registry ? [`--registry="${registry}"`] : undefined, ); - const resolvedCollectionPath = require.resolve(join(collectionName, 'package.json'), { - paths: [tempNodeModules], - }); + const tempRequire = createRequire(tempNodeModules + '/'); + const resolvedCollectionPath = tempRequire.resolve(join(collectionName, 'package.json')); if (!success) { return 1; @@ -341,7 +342,7 @@ export class AddCommandModule private isPackageInstalled(name: string): boolean { try { - require.resolve(join(name, 'package.json'), { paths: [this.context.root] }); + this.rootRequire.resolve(join(name, 'package.json')); return true; } catch (e) { @@ -400,9 +401,7 @@ export class AddCommandModule const { logger, root } = this.context; let installedPackage; try { - installedPackage = require.resolve(join(name, 'package.json'), { - paths: [root], - }); + installedPackage = this.rootRequire.resolve(join(name, 'package.json')); } catch {} if (installedPackage) { diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index e652b708d52e..c25b2f4a8020 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -10,6 +10,7 @@ import { UnsuccessfulWorkflowExecution } from '@angular-devkit/schematics'; import { NodeWorkflow } from '@angular-devkit/schematics/tools'; import { SpawnSyncReturns, execSync, spawnSync } from 'child_process'; import { existsSync, promises as fs } from 'fs'; +import { createRequire } from 'module'; import npa from 'npm-package-arg'; import pickManifest from 'npm-pick-manifest'; import * as path from 'path'; @@ -483,7 +484,8 @@ export class UpdateCommandModule extends CommandModule { // Try to resolve from package location. // This avoids issues with package hoisting. try { - migrations = require.resolve(migrations, { paths: [packagePath] }); + const packageRequire = createRequire(packagePath + '/'); + migrations = packageRequire.resolve(migrations); } catch (e) { assertIsError(e); if (e.code === 'MODULE_NOT_FOUND') { @@ -717,6 +719,7 @@ export class UpdateCommandModule extends CommandModule { }[]; if (success && migrations) { + const rootRequire = createRequire(this.context.root + '/'); for (const migration of migrations) { // Resolve the package from the workspace root, as otherwise it will be resolved from the temp // installed CLI version. @@ -728,15 +731,13 @@ export class UpdateCommandModule extends CommandModule { try { packagePath = path.dirname( // This may fail if the `package.json` is not exported as an entry point - require.resolve(path.join(migration.package, 'package.json'), { - paths: [this.context.root], - }), + rootRequire.resolve(path.join(migration.package, 'package.json')), ); } catch (e) { assertIsError(e); if (e.code === 'MODULE_NOT_FOUND') { // Fallback to trying to resolve the package's main entry point - packagePath = require.resolve(migration.package, { paths: [this.context.root] }); + packagePath = rootRequire.resolve(migration.package); } else { throw e; } @@ -768,7 +769,8 @@ export class UpdateCommandModule extends CommandModule { // Try to resolve from package location. // This avoids issues with package hoisting. try { - migrations = require.resolve(migration.collection, { paths: [packagePath] }); + const packageRequire = createRequire(packagePath + '/'); + migrations = packageRequire.resolve(migration.collection); } catch (e) { assertIsError(e); if (e.code === 'MODULE_NOT_FOUND') {