Skip to content

Commit

Permalink
fix: resolve absolute module imports only based on baseUrl (path alia…
Browse files Browse the repository at this point in the history
…ses) (#81)

* feat: resolve absolute module imports only based on baseUrl

* fix: display error message instead of complete error stack
  • Loading branch information
antoine-coulon committed Aug 29, 2023
1 parent dd486ac commit 669c2ec
Show file tree
Hide file tree
Showing 7 changed files with 395 additions and 154 deletions.
7 changes: 7 additions & 0 deletions .changeset/dirty-geese-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"skott": patch
---

Allow TypeScript path aliases module resolution when only providing a tsconfig "baseUrl" option.

Avoid propagating full error stacks currently bubbling up when using the CLI.
56 changes: 40 additions & 16 deletions packages/skott/bin/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,46 @@ export async function displaySkott(
typeOnly: options.trackTypeOnlyDependencies
};

const skottInstance = await skott({
entrypoint: entrypoint ? entrypoint : undefined,
ignorePattern: options.ignorePattern,
incremental: options.incremental,
circularMaxDepth: options.circularMaxDepth ?? Number.POSITIVE_INFINITY,
includeBaseDir: options.includeBaseDir,
dependencyTracking,
fileExtensions: options.fileExtensions
.split(",")
.filter((ext) => kExpectedModuleExtensions.has(ext)),
tsConfigPath: options.tsconfig,
manifestPath: options.manifest,
dependencyResolvers: [new EcmaScriptDependencyResolver()],
cwd: options.cwd,
verbose: options.verbose
});
let skottInstance: SkottInstance;

try {
skottInstance = await skott({
entrypoint: entrypoint ? entrypoint : undefined,
ignorePattern: options.ignorePattern,
incremental: options.incremental,
circularMaxDepth: options.circularMaxDepth ?? Number.POSITIVE_INFINITY,
includeBaseDir: options.includeBaseDir,
dependencyTracking,
fileExtensions: options.fileExtensions
.split(",")
.filter((ext) => kExpectedModuleExtensions.has(ext)),
tsConfigPath: options.tsconfig,
manifestPath: options.manifest,
dependencyResolvers: [new EcmaScriptDependencyResolver()],
cwd: options.cwd,
verbose: options.verbose
});
} catch (error: any) {
if (spinner) {
spinner.stop();
}

if (error.message) {
console.log(`\n ${kleur.bold().red("Error: ".concat(error.message))}`);
} else {
console.log(
`\n ${kleur
.bold()
.red(
"Unexpected error. Please report an issue at https://github.com/antoine-coulon/skott/issues"
)}`
);
}

process.exitCode = 1;

return;
}

const timeTook = `${(performance.now() - start).toFixed(3)}ms`;

Expand Down
2 changes: 1 addition & 1 deletion packages/skott/src/modules/resolvers/base-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ function resolveToModuleIfExists(moduleName: string) {
);
}

class ModuleNotFoundError {
export class ModuleNotFoundError {
readonly _tag = "ModuleNotFoundError";
constructor(private readonly message: string) {}
}
Expand Down
12 changes: 12 additions & 0 deletions packages/skott/src/skott.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,18 @@ export class Skott<T> {
path.join(this.fileReader.getCurrentWorkingDir(), moduleDeclaration)
)
),
Effect.orElse(() => {
const cwd = this.fileReader.getCurrentWorkingDir();
const baseDirectory = cwd === process.cwd() ? "./" : cwd;
const aliasPathStartingFromTsConfig = path.join(
baseDirectory,
path.dirname(this.config.tsConfigPath),
pathAliasBaseUrl,
moduleDeclaration
);

return resolveImportedModulePath(aliasPathStartingFromTsConfig);
}),
Effect.provideService(FileReaderTag, this.fileReader),
Effect.provideService(LoggerTag, this.logger),
Effect.runPromiseExit
Expand Down
67 changes: 60 additions & 7 deletions packages/skott/test/integration/ecmascript/typescript.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { describe, expect, it } from "vitest";
import { createRealFileSystem, withRootDir } from "../create-fs-sandbox";
import { Skott, defaultConfig } from "../../../src/skott";
import { FileSystemReader } from "../../../src/filesystem/file-reader";
import { InMemoryFileWriter } from "../../../src/filesystem/file-writer";
import { ModuleWalkerSelector } from "../../../src/modules/walkers/common";
import { FakeLogger } from "../../../src/logger";
import { fakeNodeBody } from "../../unit/shared";
import { createRealFileSystem, withRootDir } from "../create-fs-sandbox.js";
import { Skott, defaultConfig } from "../../../src/skott.js";
import { FileSystemReader } from "../../../src/filesystem/file-reader.js";
import { InMemoryFileWriter } from "../../../src/filesystem/file-writer.js";
import { ModuleWalkerSelector } from "../../../src/modules/walkers/common.js";
import { FakeLogger } from "../../../src/logger.js";
import { fakeNodeBody } from "../../unit/shared.js";

describe("When the extended config is coming from a third-party module", () => {
it("should resolve the path alias using the third-party config", async () => {
Expand Down Expand Up @@ -67,3 +67,56 @@ describe("When the extended config is coming from a third-party module", () => {
});
});
});

describe("When resolving modules with path aliases", () => {
it("Should only include file paths starting from the project base directory", async () => {
const tsConfig = {
compilerOptions: {
baseUrl: "src"
}
};

const rootDir = "temp-fs-typescript-modules";
const makeFilePath = withRootDir(rootDir);

const runSandbox = createRealFileSystem(rootDir, {
[makeFilePath("subfolder/src/foo/index.ts")]: `
import { a } from "./foo";
`,
[makeFilePath("subfolder/src/foo/foo.ts")]: `
import { b } from "bar/bar";
`,
[makeFilePath("subfolder/src/bar/bar.ts")]: `
export const b = "b";
`,
[makeFilePath("subfolder/tsconfig.json")]: JSON.stringify(tsConfig)
});

const skott = new Skott(
{
...defaultConfig,
entrypoint: "temp-fs-typescript-modules/subfolder/src/foo/index.ts",
includeBaseDir: true,
tsConfigPath: "temp-fs-typescript-modules/subfolder/tsconfig.json"
},
new FileSystemReader({
cwd: process.cwd(),
ignorePattern: ""
}),
new InMemoryFileWriter(),
new ModuleWalkerSelector(),
new FakeLogger()
);

await runSandbox(async () => {
const { getStructure } = await skott.initialize();
const { files } = await getStructure();

expect(files).toEqual([
makeFilePath("subfolder/src/foo/index.ts"),
makeFilePath("subfolder/src/foo/foo.ts"),
makeFilePath("subfolder/src/bar/bar.ts")
]);
});
});
});
Loading

0 comments on commit 669c2ec

Please sign in to comment.