Skip to content

Conversation

@kingston
Copy link
Collaborator

@kingston kingston commented Apr 21, 2025

Summary by CodeRabbit

  • Refactor

    • Removed the baseUrl compiler option from multiple TypeScript configurations across the project.
    • Updated path mappings for the @src/* alias to use explicit relative paths for improved consistency.
    • Adjusted internal logic to handle cases where baseUrl is undefined.
  • Style

    • Standardized import paths to rely on public APIs rather than internal package structures.
  • Tests

    • Updated test cases to reflect changes in TypeScript configuration and path resolution.
  • Chores

    • Added a new ESLint rule to prevent importing relative packages using relative paths.

@linear
Copy link

linear bot commented Apr 21, 2025

ENG-637 Remove baseUrl from tsconfig

base URL is no longer necessary for paths and risks adding bare paths

@changeset-bot
Copy link

changeset-bot bot commented Apr 21, 2025

🦋 Changeset detected

Latest commit: 807197a

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Apr 21, 2025

Walkthrough

This change set removes the baseUrl option from all TypeScript configuration files across the repository. Correspondingly, all @src/* path mappings in tsconfig.json files are updated from "src/*" to "./src/*". Code and test logic that previously relied on baseUrl are refactored to handle its absence, using a default value of '.' when necessary. Additionally, some generator and renderer functions are updated to support an undefined baseUrl. A new ESLint rule is introduced to disallow relative package imports. There are minor import path adjustments and a new test to verify path mapping logic when baseUrl is undefined.

Changes

Files/Paths Change Summary
All tsconfig.json and related TypeScript config files Removed the baseUrl compiler option; updated @src/* path mapping from "src/*" to "./src/*" in all relevant configuration files.
packages/core-generators/src/generators/node/typescript/typescript.generator.ts Removed baseUrl from default options; refactored path entry logic to handle undefined baseUrl with a default; added explicit export for TypescriptCompilerOptions.
packages/core-generators/src/generators/node/typescript/typescript.generator.unit.test.ts Removed baseUrl from test TypeScript config; no changes to test logic.
packages/core-generators/src/renderers/typescript/imports/ts-path-maps.ts Updated function signature to accept baseUrl as `string
packages/core-generators/src/renderers/typescript/imports/ts-path-maps.unit.test.ts Added test case for generatePathMapEntries to verify correct handling when baseUrl is undefined.
packages/fastify-generators/src/generators/core/fastify/setup-fastify-typescript.ts Removed baseUrl from TypeScript compiler options in setup logic.
packages/project-builder-server/src/plugins/node-plugin-store.ts Changed import of PluginPlatformModule to use the public package entry point instead of a direct internal path.
packages/tools/eslint-configs/typescript.js Added 'import-x/no-relative-packages': 'error' rule to disallow relative package imports.
packages/react-generators/src/generators/core/react-typescript/react-typescript.generator.ts Removed baseUrl from TypeScript compiler options in generator setup.
.changeset/olive-guests-argue.md Changeset summary describing the removal of baseUrl and rationale.

Sequence Diagram(s)

sequenceDiagram
    participant TSConfig as tsconfig.json
    participant Compiler as TypeScript Compiler
    participant Generator as Code Generator
    participant Renderer as Path Map Renderer

    TSConfig->>Compiler: Provide config (without baseUrl, with "@src/*": "./src/*")
    Generator->>Renderer: Call generatePathMapEntries(baseUrl, paths)
    Renderer->>Renderer: Use baseUrl ?? '.' for path resolution
    Renderer-->>Generator: Return resolved path entries
    Compiler-->>Application: Resolve imports using updated paths
Loading
sequenceDiagram
    participant ESLint as ESLint
    participant Developer as Developer

    Developer->>ESLint: Write/import using relative package path
    ESLint-->>Developer: Error ('import-x/no-relative-packages')
Loading
sequenceDiagram
    participant Test as Unit Test
    participant Renderer as Path Map Renderer

    Test->>Renderer: Call generatePathMapEntries(undefined, paths)
    Renderer->>Renderer: Use '.' as default base path
    Renderer-->>Test: Return correct path mappings
Loading

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Lite

📥 Commits

Reviewing files that changed from the base of the PR and between 9cee1f3 and 807197a.

📒 Files selected for processing (24)
  • .changeset/olive-guests-argue.md (1 hunks)
  • packages/code-morph/tsconfig.json (1 hunks)
  • packages/core-generators/src/generators/node/typescript/typescript.generator.ts (3 hunks)
  • packages/core-generators/src/generators/node/typescript/typescript.generator.unit.test.ts (0 hunks)
  • packages/core-generators/src/renderers/typescript/imports/ts-path-maps.ts (2 hunks)
  • packages/core-generators/src/renderers/typescript/imports/ts-path-maps.unit.test.ts (1 hunks)
  • packages/core-generators/tsconfig.json (1 hunks)
  • packages/create-project/tsconfig.json (1 hunks)
  • packages/fastify-generators/src/generators/core/fastify/setup-fastify-typescript.ts (0 hunks)
  • packages/fastify-generators/tsconfig.json (1 hunks)
  • packages/project-builder-cli/tsconfig.app.json (1 hunks)
  • packages/project-builder-cli/tsconfig.e2e.json (1 hunks)
  • packages/project-builder-lib/tsconfig.json (1 hunks)
  • packages/project-builder-server/src/plugins/node-plugin-store.ts (1 hunks)
  • packages/project-builder-server/tsconfig.json (1 hunks)
  • packages/project-builder-test/tsconfig.json (1 hunks)
  • packages/project-builder-web/tsconfig.json (1 hunks)
  • packages/react-generators/src/generators/core/react-typescript/react-typescript.generator.ts (0 hunks)
  • packages/react-generators/tsconfig.json (1 hunks)
  • packages/sync/tsconfig.json (1 hunks)
  • packages/tools/eslint-configs/typescript.js (1 hunks)
  • packages/ui-components/tsconfig.json (1 hunks)
  • packages/utils/tsconfig.json (1 hunks)
  • plugins/baseplate-plugin-storage/tsconfig.json (1 hunks)
💤 Files with no reviewable changes (3)
  • packages/react-generators/src/generators/core/react-typescript/react-typescript.generator.ts
  • packages/core-generators/src/generators/node/typescript/typescript.generator.unit.test.ts
  • packages/fastify-generators/src/generators/core/fastify/setup-fastify-typescript.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/core-generators/src/renderers/typescript/imports/ts-path-maps.unit.test.ts (1)
packages/core-generators/src/renderers/typescript/imports/ts-path-maps.ts (1)
  • generatePathMapEntries (12-27)
🔇 Additional comments (25)
packages/project-builder-cli/tsconfig.e2e.json (2)

5-7: Consistent Path Alias Update

The @src/* mapping has been correctly updated to a relative path ("./src/*"), which aligns with the project-wide removal of baseUrl and maintains import resolution consistency in this E2E config.


2-2: Verify baseUrl in Extended Configuration

TypeScript only applies paths mappings when a baseUrl is set. Since this file inherits from @halfdomelabs/tools/tsconfig.node.cli.json and no longer declares its own baseUrl, please confirm that the extended config still defines a valid baseUrl. Otherwise, these path aliases won’t take effect.

plugins/baseplate-plugin-storage/tsconfig.json (2)

2-3: Ensure removal of baseUrl is effective.

This config extends @halfdomelabs/tools/tsconfig.vite.lib.json. Verify that the extended config does not reintroduce a baseUrl option (which could override our removal). If it does, consider overriding it here (e.g., "baseUrl": ".") or removing it upstream so that baseUrl is truly absent across the build.


7-7: Approve updated path mapping.

Updating "@src/*": ["./src/*"] to use an explicit relative path is correct and aligns with the removal of baseUrl. Ensure that all imports using @src/ resolve correctly—e.g., by running tsc or leveraging tsc-alias in your build pipeline.

packages/code-morph/tsconfig.json (1)

6-6: Consistent update of path alias after removing baseUrl.

The alias @src/* is now mapped to ./src/*, explicitly relative to the TS config root. This aligns with the removal of baseUrl and maintains correct module resolution.

packages/ui-components/tsconfig.json (1)

6-6: Path alias adjusted to explicit relative path.

Mapping @src/*./src/* ensures imports still resolve correctly without a baseUrl. Nice consistency with other packages.

packages/fastify-generators/tsconfig.json (1)

6-6: Updated @src/* path mapping for removed baseUrl.

Explicitly prefixing with ./ aligns with the TS default baseUrl = "." and preserves correct alias resolution.

packages/project-builder-web/tsconfig.json (1)

6-6: Normalized alias path following baseUrl removal.

The change to ./src/* is correct given the default base directory, ensuring @src/* resolves under the workspace.

packages/project-builder-test/tsconfig.json (1)

7-7: Confirmed explicit path mapping post-baseUrl removal.

Mapping @src/* to ./src/* is correctly scoped to the project root, restoring alias resolution in the absence of baseUrl.

packages/react-generators/tsconfig.json (1)

6-6: Path mapping updated correctly to use explicit relative path.

The path mapping for @src/* has been properly updated to use an explicit relative path "./src/*" instead of (presumably) "src/*". This change aligns with the PR objective of removing the baseUrl option while ensuring path mappings continue to work correctly.

packages/project-builder-server/tsconfig.json (1)

7-7: Path mapping updated correctly to use explicit relative path.

The path mapping for @src/* has been properly updated to use an explicit relative path "./src/*" instead of (presumably) "src/*". This change aligns with the PR objective of removing the baseUrl option while ensuring path mappings continue to work correctly.

packages/project-builder-server/src/plugins/node-plugin-store.ts (1)

3-3: Type import aligned with new ESLint rule for package imports.

The import of PluginPlatformModule has been updated to use the package's main entry point instead of a direct internal path. This aligns with the new ESLint rule to disallow relative package imports and is a good practice for maintaining clean dependency boundaries.

packages/core-generators/src/renderers/typescript/imports/ts-path-maps.ts (2)

13-13: Function parameter updated to handle undefined baseUrl.

The baseUrl parameter type has been correctly updated to string | undefined to accommodate the removal of the baseUrl option from TypeScript configurations. This change ensures the function can gracefully handle cases where baseUrl is not provided.


23-23: Path joining logic updated to handle undefined baseUrl.

The path joining logic has been updated to use the nullish coalescing operator (baseUrl ?? '.'), which properly defaults to '.' when baseUrl is undefined. This ensures that the path joining operation always has a valid base path, preventing potential errors when baseUrl is not provided.

packages/core-generators/src/generators/node/typescript/typescript.generator.ts (3)

216-217: Improved conditional structure for path entry handling

The conditional logic has been restructured to be more explicit with an else if and added an else branch to handle the case when neither condition is met. This is a good improvement for code clarity and completeness.

Also applies to: 233-235


228-228: Added fallback for undefined baseUrl

The addition of the nullish coalescing operator ?? ensures that a default value of '.' is used when baseUrl is undefined, which supports the removal of baseUrl from tsconfig files while maintaining compatibility.


419-419: Re-exported TypescriptCompilerOptions type

Good practice to re-export this type directly from the module, making it easier for consumers to access it without needing to know the internal structure.

packages/project-builder-lib/tsconfig.json (1)

7-7: Updated path mapping to use explicit relative path

The path mapping has been updated to include a leading ./ which explicitly denotes a relative path. This change is necessary after removing the baseUrl option to ensure TypeScript correctly resolves imports.

packages/sync/tsconfig.json (1)

7-7: Updated path mapping to use explicit relative path

The path mapping has been updated to include a leading ./ which explicitly denotes a relative path. This change is necessary after removing the baseUrl option to ensure TypeScript correctly resolves imports.

.changeset/olive-guests-argue.md (1)

1-6: Clear changeset documentation

The changeset properly documents the patch updates to the affected packages and clearly explains the purpose of removing the baseUrl configuration. This is helpful for tracking the change and understanding its motivation.

packages/tools/eslint-configs/typescript.js (1)

147-149: Good addition to enforce proper package imports.

Adding the import-x/no-relative-packages rule is a good complement to the removal of baseUrl. This rule prevents importing from other packages using relative paths (like '../other-package/foo'), which encourages treating each package as an independent unit and makes the codebase more maintainable.

packages/project-builder-cli/tsconfig.app.json (1)

6-6: Correct update to path mapping.

The path mapping for @src/* has been properly updated to use an explicit relative path (./src/*), which is necessary after removing the baseUrl compiler option. This change ensures that the path alias continues to work correctly.

packages/utils/tsconfig.json (1)

7-7: Correct update to path mapping.

The path mapping for @src/* has been properly updated to use an explicit relative path (./src/*), which is necessary after removing the baseUrl compiler option. This change ensures that the path alias continues to work correctly.

packages/core-generators/tsconfig.json (1)

7-7: Correct update to path mapping.

The path mapping for @src/* has been properly updated to use an explicit relative path (./src/*), which is necessary after removing the baseUrl compiler option. This change ensures that the path alias continues to work correctly.

packages/core-generators/src/renderers/typescript/imports/ts-path-maps.unit.test.ts (1)

29-41: LGTM! Well-structured test for handling undefined baseUrl.

This new test case properly verifies the updated behavior of the generatePathMapEntries function when baseUrl is undefined. It follows the arrange-act-assert pattern and ensures that path mappings work correctly without a baseUrl, which is critical for the project-wide removal of the baseUrl option.

The test confirms that the implementation correctly uses the fallback value (.) when baseUrl is undefined, as implemented in the ts-path-maps.js file with the nullish coalescing operator: baseUrl ?? '.'.

"baseUrl": ".",
"paths": {
"@src/*": ["src/*"]
"@src/*": ["./src/*"]
Copy link

@coderabbitai coderabbitai bot Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify paths mapping without an explicit baseUrl.

TypeScript’s paths feature generally requires a baseUrl to resolve non-relative imports. Since you’ve removed baseUrl here, please confirm that the extended config (@halfdomelabs/tools/tsconfig.node.cli.json) still defines it; otherwise, you may encounter TS5028 errors at build time. If it isn’t defined downstream, consider reintroducing:

 "compilerOptions": {
+  "baseUrl": ".",
   "outDir": "dist",
   "paths": {
     "@src/*": ["./src/*"]
   }
 }

to ensure module aliases are resolved correctly.

To verify, you can run:


🏁 Script executed:

#!/bin/bash
# Check for `baseUrl` in the extended tsconfig
rg -n '"baseUrl"' -g 'tsconfig.node.cli.json'

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Locate the extended tsconfig file
file=$(find . -type f -name 'tsconfig.node.cli.json' | head -n1)
if [ -z "$file" ]; then
  echo "tsconfig.node.cli.json not found"
  exit 1
fi
echo "Found tsconfig at: $file"

# Check for a baseUrl definition
echo "Checking for baseUrl in $file:"
rg -n '"baseUrl"' "$file" || echo "No baseUrl defined in $file"

Length of output: 617


Add a baseUrl to enable your paths mapping

We’ve confirmed that packages/tools/tsconfig.node.cli.json does not define a baseUrl. Since TypeScript requires baseUrl whenever you use paths, you will encounter TS5028 errors at build time.

Please update packages/create-project/tsconfig.json to include:

 "compilerOptions": {
+  "baseUrl": ".",
   "outDir": "dist",
   "paths": {
     "@src/*": ["./src/*"]
   }
 }

This ensures @src/* resolves correctly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is actually inaccurate. You do not need a baseUrl to enable paths mapping since Typescript 4.1. The point of this PR is to remove the baseURL to ensure that we don't allow bare paths in imports e.g. node_modules/random_package.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

@kingston You're absolutely right, and I apologize for the incorrect information. TypeScript 4.1+ indeed supports paths mapping without baseUrl when using relative paths (with "./").

The approach in your PR makes perfect sense - removing baseUrl while updating path mappings to use explicit relative paths ("./src/*") accomplishes your goal of preventing bare path imports while maintaining the alias functionality.

Thank you for the clarification about the purpose of this change!


🌐 Web query:

TypeScript 4.1 paths mapping without baseUrl

💡 Result:

TypeScript 4.1: paths Mapping Without baseUrl

Overview

Starting with TypeScript 4.1, you can use the paths option in your tsconfig.json without specifying a baseUrl. This change removed a long-standing restriction and simplified path mapping for TypeScript projects[2][4][5].


Previous Behavior

Prior to TypeScript 4.1, if you tried to use the paths option without a baseUrl, the compiler would throw an error:

"Option 'paths' cannot be used without specifying '--baseUrl' option"[1][3].

This meant that any path mapping required you to set baseUrl, usually to either "./" or another root-relative directory.


What's Changed in TypeScript 4.1?

  • No More baseUrl Requirement:
    With TypeScript 4.1 and later, you can specify paths mappings without defining baseUrl in your tsconfig.json.
  • Resolution is Relative to the Project Root:
    If baseUrl is not set, the project directory (where tsconfig.json is located) is used as the base for resolving paths[1][4].
  • Better Editor Experience:
    This update also improved the auto-import suggestions in editors like VS Code, aligning import paths more closely with your intended mappings[1].

Example Configuration

{
  "compilerOptions": {
    "paths": {
      "@utils/*": ["src/utils/*"],
      "@components/*": ["src/components/*"]
    }
  }
}

With this configuration (and no baseUrl), @utils/foo will resolve to src/utils/foo relative to the project root[4].


References in Official Documentation


Summary Table

TypeScript Version baseUrl Required for paths? Behavior
≤ 4.0 Yes Error if omitted
4.1+ No Resolves from project root

In Practice

If you want to use paths mappings as of TypeScript 4.1 or later, you may safely omit baseUrl from your configuration. TypeScript will resolve the mappings from the directory containing your tsconfig.json, improving both developer experience and configuration flexibility[1][2][4][5].

Citations:


@kingston Thank you for correcting me! You're absolutely right - since TypeScript 4.1, path mappings can be used without specifying baseUrl. The web search confirms that when baseUrl is omitted, TypeScript resolves paths relative to the project directory (where tsconfig.json is located).

Your approach of removing baseUrl while updating paths to use explicit relative paths ("./src/*") perfectly achieves the goal of preventing bare path imports like node_modules/random_package while maintaining the path alias functionality.

I appreciate you sharing this knowledge about TypeScript's behavior!


✏️ Learnings added
Learnt from: kingston
PR: halfdomelabs/baseplate#505
File: packages/create-project/tsconfig.json:6-6
Timestamp: 2025-04-21T06:32:22.453Z
Learning: Since TypeScript 4.1, baseUrl is not required for paths mapping when using explicit relative paths (with "./"). Removing baseUrl from tsconfig.json while updating paths to use relative paths (e.g., changing "@src/*": ["src/*"] to "@src/*": ["./src/*"]) prevents bare path imports from node_modules while maintaining path alias functionality.

Learnt from: kingston
PR: halfdomelabs/baseplate#505
File: packages/create-project/tsconfig.json:6-6
Timestamp: 2025-04-21T06:32:22.453Z
Learning: Since TypeScript 4.1, baseUrl is not required for paths mapping in tsconfig.json. Removing baseUrl and using explicit relative paths with "./" prefix (e.g., changing "@src/*": ["src/*"] to "@src/*": ["./src/*"]) prevents bare path imports from node_modules while maintaining path alias functionality.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@kingston kingston merged commit 1027f68 into main Apr 21, 2025
8 checks passed
@kingston kingston deleted the kingston/eng-637-remove-baseurl-from-tsconfig-and-make-ui-components-to-use branch April 21, 2025 06:36
@github-actions github-actions bot mentioned this pull request Apr 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants