diff --git a/app/components/error-boundary.tsx b/app/components/error-boundary.tsx index b881ed92..03096220 100644 --- a/app/components/error-boundary.tsx +++ b/app/components/error-boundary.tsx @@ -6,7 +6,7 @@ import { useParams, useRouteError, } from 'react-router' -import { getErrorMessage } from '#app/utils/misc' +import { getErrorMessage } from '#app/utils/misc.tsx' type StatusHandler = (info: { error: ErrorResponse diff --git a/app/routes/admin/cache/index.tsx b/app/routes/admin/cache/index.tsx index 4c6efc27..50e92732 100644 --- a/app/routes/admin/cache/index.tsx +++ b/app/routes/admin/cache/index.tsx @@ -8,7 +8,7 @@ import { useSearchParams, useSubmit, } from 'react-router' -import { GeneralErrorBoundary } from '#app/components/error-boundary' +import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx' import { Field } from '#app/components/forms.tsx' import { Spacer } from '#app/components/spacer.tsx' import { Button } from '#app/components/ui/button.tsx' diff --git a/app/routes/admin/cache/sqlite.server.ts b/app/routes/admin/cache/sqlite.server.ts index b90dd9f7..721ef8d5 100644 --- a/app/routes/admin/cache/sqlite.server.ts +++ b/app/routes/admin/cache/sqlite.server.ts @@ -4,7 +4,7 @@ import { cache } from '#app/utils/cache.server.ts' import { getInstanceInfo, getInternalInstanceDomain, -} from '#app/utils/litefs.server' +} from '#app/utils/litefs.server.ts' import { type Route } from './+types/sqlite.ts' export async function updatePrimaryCacheValue({ diff --git a/app/utils/auth.server.test.ts b/app/utils/auth.server.test.ts index b660cd6e..d3c5ab43 100644 --- a/app/utils/auth.server.test.ts +++ b/app/utils/auth.server.test.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from 'msw' import { describe, expect, test } from 'vitest' -import { server } from '#tests/mocks' +import { server } from '#tests/mocks/index.ts' import { consoleWarn } from '#tests/setup/setup-test-env.ts' import { checkIsCommonPassword, getPasswordHashParts } from './auth.server.ts' diff --git a/docs/decisions/031-imports.md b/docs/decisions/031-imports.md index ebd8f47e..83ad00bf 100644 --- a/docs/decisions/031-imports.md +++ b/docs/decisions/031-imports.md @@ -2,7 +2,8 @@ Date: 2023-08-16 -Status: accepted +Status: superseded by [046-remove-path-aliases](./046-remove-path-aliases.md) +due to TypeScript's native support for the `"imports"` field in package.json. ## Context @@ -27,21 +28,14 @@ and manually modify. Despite the magic of Path aliases, they are actually a standard `package.json` supported feature. Sort of. [The `"imports"` field](https://nodejs.org/api/packages.html#imports) in -`package.json` allows you to configure aliases for your imports. It's not -exactly the same as TypeScript Path aliases, and using them doesn't give you -autocomplete with TypeScript -([yet](https://github.com/microsoft/TypeScript/pull/55015)), but if you -configure both, then you can get the best of both worlds! +`package.json` allows you to configure aliases for your imports. +TypeScript also uses this for its own Path aliases since version 5.4 +so you get autocomplete and type checking for your imports. By using the `"imports"` field, you don't have to do any special configuration for `vitest` or `eslint` to be able to resolve imports. They just resolve them using the standard. -And by using the `tsconfig.json` `paths` field configured in the same way as the -`"imports"` field, you get autocomplete and type checking for your imports. This -should hopefully be temporary until TypeScript supports the `"imports"` field -directly. - One interesting requirement for `imports` is that they _must_ start with the `#` character to disambiguate from other imports. This is a bit annoying, but it's something that's not difficult to get used to. They also _must not_ start with @@ -50,8 +44,7 @@ again it's just a matter of familiarity. So it's no big deal. ## Decision -We're going to configure `"imports"` in the `package.json` and `paths` in the -`tsconfig.json` to use path aliases for imports. +We're going to configure `"imports"` in the `package.json` to use path aliases for imports. We'll set it to `"#*": "./*"` which will allow us to import anything in the root of the repo with `#/`. @@ -59,10 +52,6 @@ of the repo with `#/`. ## Consequences This is unfortunately _very_ soon after making the decision to drop the alias. -But I see this as slightly different because we're only using the alias to make -up for a shortcoming in TypeScript temporarily. Once TypeScript supports the -`"imports"` field, we can drop the `paths` field and just use the `"imports"` -standard for Node.js. If someone wants to use the Epic Stack without Node.js, and their runtime doesn't support `package.json` imports (I'm not sure whether other runtimes do diff --git a/docs/decisions/046-remove-path-aliases.md b/docs/decisions/046-remove-path-aliases.md new file mode 100644 index 00000000..13fa1305 --- /dev/null +++ b/docs/decisions/046-remove-path-aliases.md @@ -0,0 +1,41 @@ +# Remove Path Aliases + +Date: 2025-10-23 + +Status: accepted + +## Context + +In [031-imports](./031-imports.md), we implemented path aliases using both the +`"imports"` field in `package.json` and the `paths` field in `tsconfig.json`. +This was done as a temporary solution because TypeScript didn't natively support +the `"imports"` field, requiring us to maintain both configurations to get +autocomplete and type checking. + +However, TypeScript has now added native support for the `"imports"` field in +`package.json` (as referenced in the original decision's "yet" link). This means +we no longer need the `paths` configuration in `tsconfig.json` to get proper +TypeScript support for our imports. + +## Decision + +We're removing the path aliases configuration from `tsconfig.json` and relying +solely on the `"imports"` field in `package.json`. This simplifies our +configuration and aligns with the standard Node.js approach. + +The `"imports"` field will continue to work as before, providing the same import +resolution functionality, but now with full TypeScript support without requiring +duplicate configuration. + +## Consequences + +- **Simplified configuration**: We no longer need to maintain both + `package.json` imports and `tsconfig.json` paths +- **Standard compliance**: We're now using the standard Node.js approach without + TypeScript-specific workarounds +- **Reduced maintenance**: One less configuration to keep in sync +- **Better tooling support**: TypeScript now natively understands the + `"imports"` field, providing better IDE support + +This supersedes [031-imports](./031-imports.md) as the current approach for +handling imports in the Epic Stack. diff --git a/prisma/seed.ts b/prisma/seed.ts index 919bdc98..695920c2 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker' import { prisma } from '#app/utils/db.server.ts' -import { MOCK_CODE_GITHUB } from '#app/utils/providers/constants' +import { MOCK_CODE_GITHUB } from '#app/utils/providers/constants.ts' import { createPassword, createUser, diff --git a/tests/e2e/onboarding.test.ts b/tests/e2e/onboarding.test.ts index 1bfbad55..8fd8a9f4 100644 --- a/tests/e2e/onboarding.test.ts +++ b/tests/e2e/onboarding.test.ts @@ -4,11 +4,11 @@ import { prisma } from '#app/utils/db.server.ts' import { normalizeEmail, normalizeUsername, -} from '#app/utils/providers/provider' +} from '#app/utils/providers/provider.ts' import { USERNAME_MAX_LENGTH, USERNAME_MIN_LENGTH, -} from '#app/utils/user-validation' +} from '#app/utils/user-validation.ts' import { readEmail } from '#tests/mocks/utils.ts' import { createUser, diff --git a/tests/playwright-utils.ts b/tests/playwright-utils.ts index 0fe8fb0e..b8317caa 100644 --- a/tests/playwright-utils.ts +++ b/tests/playwright-utils.ts @@ -8,8 +8,8 @@ import { sessionKey, } from '#app/utils/auth.server.ts' import { prisma } from '#app/utils/db.server.ts' -import { MOCK_CODE_GITHUB_HEADER } from '#app/utils/providers/constants.js' -import { normalizeEmail } from '#app/utils/providers/provider.js' +import { MOCK_CODE_GITHUB_HEADER } from '#app/utils/providers/constants.ts' +import { normalizeEmail } from '#app/utils/providers/provider.ts' import { authSessionStorage } from '#app/utils/session.server.ts' import { createUser } from './db-utils.ts' import { diff --git a/tsconfig.json b/tsconfig.json index 057541cb..6c58b2be 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,8 +6,6 @@ "types": ["@react-router/node", "vite/client"], "rootDirs": [".", "./.react-router/types"], "paths": { - "#app/*": ["./app/*"], - "#tests/*": ["./tests/*"], "@/icon-name": [ "./app/components/ui/icons/types.ts", "./types/icon-name.d.ts"