sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.44k stars 1.89k forks source link

Separate `tsconfig.json` for server and client #12537

Open hyunbinseo opened 1 month ago

hyunbinseo commented 1 month ago

[!NOTE]
If SvelteKit v3 requires Node.js v20+, and Svelte v5 requires ES2023+, this issue can be converted to setting:

  • vite.config's build.target to es2023
  • tsconfig.json's compilerOptions.lib to ["ES2023", "DOM", "DOM.Iterable"]

ES2023 seems to be a reasonable baseline, since it is supported by:

  • macOS and iOS Safari 16.4+ (18 is coming out soon)
  • Node.js 20 (22 will soon be the active LTS)

Describe the problem

Out-of-the box, SvelteKit uses:

Vite will replace 'modules' to ['es2020', 'edge88', 'firefox78', 'chrome87', 'safari14']

Therefore, users can safely assume that SvelteKit and Svelte requires ES2020[^1].

[^1]: SvelteKit v2 did require ES2022 in its early stages, but it was rolled back.

However, the default tsconfig.json enables esnext APIs to be used globally.

{
  "compilerOptions": {
    "lib": ["esnext", "DOM", "DOM.Iterable"]
  },
  // ...
}

Since Vite does not automatically polyfill APIs, this could be problematic.

Describe the proposed solution

  1. Set the default compilerOptions.lib to es2020 (or the value SvelteKit v3 requires)
  2. Set compilerOptions.lib to es2022 for the server files. (or the SK3 requirements)
  3. Make users manually and explicitly bump compilerOptions.lib and build.target.
// src/routes/+layout.ts

// Property 'hasOwn' does not exist on type 'ObjectConstructor'.
// Do you need to change your target library?
// Try changing the 'lib' compiler option to 'es2022' or later.ts(2550)
Object.hasOwn({ prop: 'exists' }, 'prop');
// src/routes/+layout.server.ts
Object.hasOwn({ prop: 'exists' }, 'prop');

Alternatives considered

No response

Importance

would make my life easier

Additional Information

This will have the added benefit of specifying Svelte v5, SvelteKit v3 requirements.

Blocked by:

hyunbinseo commented 1 month ago

This is the workaround I've come up with:

https://github.com/hyunbinseo/svelte-kit-templates/commits/tsconfigs

Seems to work as expected:

// src/routes/+page.ts
import { PUBLIC_SITE_NAME } from '$env/static/public';
import type { PageLoad } from './$types';
export const load = (() => {
  [].at(-1); // Property at does not exist on type never[].
  return { title: PUBLIC_SITE_NAME };
}) satisfies PageLoad;
// src/routes/+page.server.ts
import { PUBLIC_SITE_NAME } from '$env/static/public';
import type { PageServerLoad } from './$types';
export const load = (() => {
  [].at(-1); // No error
  return { title: PUBLIC_SITE_NAME };
}) satisfies PageServerLoad;
hyunbinseo commented 1 month ago

Issues

svelte-check seems to only utilize the root tsconfig.json file.

// src/routes/+page.server.ts
[].at(-1); // No error in the editor
pnpm check
# Error: Property 'at' does not exist on type 'never[]'.
# Do you need to change your target library?
# Try changing the 'lib' compiler option to 'es2022' or later.