Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/config-loader.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as TsConfigLoader2 from "./tsconfig-loader";
import { MatchPath, createMatchPath } from "./match-path-sync";
import * as path from "path";

export interface ExplicitParams {
Expand Down Expand Up @@ -87,3 +88,35 @@ export function configLoader({
addMatchAll: loadResult.baseUrl !== undefined,
};
}

export function findConfigMatcher({
cwd,
explicitParams,
}: ConfigLoaderParams):
| { config: ConfigLoaderSuccessResult; matchPath: MatchPath }
| undefined {
const configLoaderResult = configLoader({
cwd,
explicitParams,
});

if (configLoaderResult.resultType === "failed") {
console.warn(
"".concat(configLoaderResult.message, ". tsconfig-paths will be skipped")
);

return;
}

const matchPath = createMatchPath(
configLoaderResult.absoluteBaseUrl,
configLoaderResult.paths,
configLoaderResult.mainFields,
configLoaderResult.addMatchAll
);

return {
config: configLoaderResult,
matchPath,
};
}
50 changes: 32 additions & 18 deletions src/register.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { createMatchPath } from "./match-path-sync";
import { configLoader, ExplicitParams } from "./config-loader";
import * as path from "path";

import { findConfigMatcher, ExplicitParams } from "./config-loader";

const noOp = (): void => void 0;

function getCoreModules(
builtinModules: string[] | undefined
): { [key: string]: boolean } {
): {
[key: string]: boolean;
} {
builtinModules = builtinModules || [
"assert",
"buffer",
Expand Down Expand Up @@ -76,25 +79,16 @@ export function register(params?: RegisterParams): () => void {
cwd = argv.project;
}

const configLoaderResult = configLoader({
cwd: cwd ?? process.cwd(),
const primaryMatcher = findConfigMatcher({
cwd: cwd !== null && cwd !== void 0 ? cwd : process.cwd(),
explicitParams,
});

if (configLoaderResult.resultType === "failed") {
console.warn(
`${configLoaderResult.message}. tsconfig-paths will be skipped`
);

if (!primaryMatcher) {
return noOp;
}

const matchPath = createMatchPath(
configLoaderResult.absoluteBaseUrl,
configLoaderResult.paths,
configLoaderResult.mainFields,
configLoaderResult.addMatchAll
);
const configMatchers = [primaryMatcher];

// Patch node's module loading
// eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires
Expand All @@ -103,10 +97,30 @@ export function register(params?: RegisterParams): () => void {
const originalResolveFilename = Module._resolveFilename;
const coreModules = getCoreModules(Module.builtinModules);
// eslint-disable-next-line @typescript-eslint/no-explicit-any,no-underscore-dangle
Module._resolveFilename = function (request: string, _parent: any): string {
Module._resolveFilename = function (request: string, parent: any): string {
const isCoreModule = coreModules.hasOwnProperty(request);
if (!isCoreModule) {
const found = matchPath(request);
const parentFilename = parent?.filename;

let matcher = configMatchers.find(
({ config }) =>
!parentFilename || parentFilename.startsWith(config.absoluteBaseUrl)
);

if (!matcher) {
const targetProject = path.dirname(parentFilename);

matcher = findConfigMatcher({
cwd: targetProject,
explicitParams,
});

if (matcher) {
configMatchers.push(matcher);
}
}

const found = matcher?.matchPath(request);
if (found) {
const modifiedArguments = [found, ...[].slice.call(arguments, 1)]; // Passes all arguments. Even those that is not specified above.
return originalResolveFilename.apply(this, modifiedArguments);
Expand Down