Skip to content

Commit

Permalink
fix: support windows ERR_PACKAGE_PATH_NOT_EXPORTED error
Browse files Browse the repository at this point in the history
  • Loading branch information
christophehurpeau committed Jul 30, 2022
1 parent 6bbc54e commit d77c4fe
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 17 deletions.
23 changes: 15 additions & 8 deletions dist/index-node14.cjs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index-node14.cjs.js.map

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import createRollupConfig from 'pob-babel/createRollupConfig.js';

export default createRollupConfig({
cwd: new URL('.', import.meta.url).pathname,
cwd: new URL('.', import.meta.url).pathname.slice(
process.platform === 'win32' ? 1 : 0,
),
});
46 changes: 46 additions & 0 deletions src/utils/createGetDependencyPackageJson.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { PackageJson } from 'type-fest';
import { createGetDependencyPackageJson } from './createGetDependencyPackageJson';

jest.mock('./createGetDependencyPackageJson', () => ({
...jest.requireActual('./createGetDependencyPackageJson'),
readPkgJson: jest.fn(),
writePkgJson: jest.fn(),
internalLoadPackageJsonFromNodeModules: jest.fn(),
}));

describe('createGetDependencyPackageJson', () => {
test('on windows with error', () => {
const internalLoadPackageJsonFromNodeModulesMock = jest
.fn()
.mockImplementation(() => {
const err: NodeJS.ErrnoException = new Error(
'Package subpath \'./package.json\' is not defined by "exports" in C:\\test\\check-package-dependencies\\node_modules\\test1\\package.json',
);
err.code = 'ERR_PACKAGE_PATH_NOT_EXPORTED';

throw err;
});

const mockPkg: PackageJson = {};
const readPkgJsonMock = jest.fn((pkgPath: string) => mockPkg);

const getDependencyPackageJson = createGetDependencyPackageJson({
pkgDirname: 'test',
internalCustomLoadPackageJsonFromNodeModules:
internalLoadPackageJsonFromNodeModulesMock,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
internalReadPkgJson: readPkgJsonMock as any,
});

const res = getDependencyPackageJson('test1');

expect(res).toBe(mockPkg);
expect(internalLoadPackageJsonFromNodeModulesMock).toBeCalledWith(
'test1',
'test',
);
expect(readPkgJsonMock).toBeCalledWith(
'C:\\test\\check-package-dependencies\\node_modules\\test1\\package.json',
);
});
});
31 changes: 24 additions & 7 deletions src/utils/createGetDependencyPackageJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,47 @@ export function writePkgJson(packagePath: string, pkg: PackageJson): void {
writeFileSync(packagePath, JSON.stringify(pkg, null, 2));
}

/** @internal */
export function internalLoadPackageJsonFromNodeModules(
pkgDepName: string,
pkgDirname: string,
): PackageJson {
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
return require(require.resolve(`${pkgDepName}/package.json`, {
paths: [pkgDirname],
})) as PackageJson;
}

type NodeModulesPackagePathCache = Map<string, PackageJson>;

interface CreateGetDependencyPackageJsonOptions {
pkgDirname: string;
nodeModulesPackagePathCache?: NodeModulesPackagePathCache;
/** @internal */
internalCustomLoadPackageJsonFromNodeModules?: typeof internalLoadPackageJsonFromNodeModules;
/** @internal */
internalReadPkgJson?: typeof readPkgJson;
}

export function createGetDependencyPackageJson({
pkgDirname,
nodeModulesPackagePathCache = new Map<string, PackageJson>(),
internalCustomLoadPackageJsonFromNodeModules = internalLoadPackageJsonFromNodeModules,
internalReadPkgJson = readPkgJson,
}: CreateGetDependencyPackageJsonOptions): GetDependencyPackageJson {
return (pkgDepName) => {
const existing = nodeModulesPackagePathCache.get(pkgDepName);
if (existing) return existing;
let pkg: PackageJson;
if (pkgDepName.startsWith('.')) {
const packagePath = `${pkgDirname}/${pkgDepName}/package.json`;
pkg = readPkgJson(packagePath);
pkg = internalReadPkgJson(packagePath);
} else {
try {
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-unsafe-assignment
pkg = require(require.resolve(`${pkgDepName}/package.json`, {
paths: [pkgDirname],
}));
pkg = internalCustomLoadPackageJsonFromNodeModules(
pkgDepName,
pkgDirname,
);
} catch (err: unknown) {
if (!(err instanceof Error)) throw err;

Expand All @@ -45,13 +62,13 @@ export function createGetDependencyPackageJson({
throw err;
}

const match = / in (.*\/package.json)($|\simported from)/.exec(
const match = / in (.*[/\\]package.json)($|\simported from)/.exec(
err.message,
);

if (match) {
const [, matchPackageJson] = match;
pkg = readPkgJson(matchPackageJson);
pkg = internalReadPkgJson(matchPackageJson);
} else {
throw err;
}
Expand Down

0 comments on commit d77c4fe

Please sign in to comment.