sveltejs / vite-plugin-svelte

Svelte plugin for http://vitejs.dev/
MIT License
864 stars 105 forks source link

Provide helpful error when using `lang="ts"` without a preprocessor #585

Closed Rich-Harris closed 1 year ago

Rich-Harris commented 1 year ago

Describe the problem

see e.g. https://github.com/sveltejs/kit/pull/8811. If a developer adds lang="ts" to a component without the relevant preprocessor, they'll get 'unexpected token' errors.

Describe the proposed solution

This is probably a common enough case that we could intercept the error and say something like 'you should add preprocessor: vitePreprocess()' or whatever

Alternatives considered

continue as presently

Importance

nice to have

dominikg commented 1 year ago

Question is how do you detect that without adding overhead for everyone.

The only way i can think of rn is using toRollupError (which basically wraps compile anyways to make vite error overlay nicer) and in there do

if( token_error && lang_ts && preprocessor_missing) {
  rollupError.message = 'friendly reminder to install ts preprocessor' 
}

problem is that lang_ts needs a regex and preprocessor_missing is hard to determine. Only really safe way is to feed a dummy ts script into the preprocessor chain and see if that fails.

Which reads like a lot of complexity. How often has this problem been reported so far?

yfwz100 commented 1 year ago

I also came across this error and was wondering why typescript is not supported in a modern framework... If it's hard to detect, can we add this pre-processor by default?

dominikg commented 1 year ago

I also came across this error and was wondering why typescript is not supported in a modern framework... If it's hard to detect, can we add this pre-processor by default?

vite-plugin-svelte itself has some automatic configuration for svelte features that are required for vite hot module reloading to work. However it won't start adding opinionated configuration for optional features.

It's up to the starter templates/frameworks/users that use typescript to add the required preprocessors and configuration needed for their projects.

Best we can do is try to have a better error message when we detect that it is missing.

rnwolfe commented 1 year ago

I am getting this error with vitePreprocess() setup.

svelte.config.js:

import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/kit/vite';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    // Consult https://kit.svelte.dev/docs/integrations#preprocessors
    // for more information about preprocessors
    preprocess: vitePreprocess(),
    kit: {
        adapter: adapter(),
        csp: {
            directives: {
                'font-src': ['self', 'data:', '*.typekit.net', '*.cloudflare.com'],
                'script-src': ['self', '*']
            }
        }
    }
};

export default config;

Component

<script lang="ts">
    import { page } from '$app/stores';
    import { goto } from '$app/navigation';

    import type { IQuestion } from '../../models/Question';

    export let questions: [IQuestion[]];

[...snipped]
</script>

Error

Internal server error: /src/components/footer/Footer.svelte:5:13 Unexpected token
  Plugin: vite-plugin-svelte
  File: /src/components/footer/Footer.svelte:5:13
   3 |    import { goto } from '$app/navigation';
   4 |  
   5 |    import type { IQuestion } from '../../models/Question';
                      ^
   6 |  
   7 |    export let questions: [IQuestion[]]; (x4)

More Context

I am also getting this when specifying lang="ts" in a <script> tag for the component: (this shows up in a VSCode error)

Cannot find module 'typescript'
Require stack:
- /Users/ryan/dev/goodspirits/gsc-website/node_modules/svelte-preprocess/dist/transformers/typescript.js
- /Users/ryan/dev/goodspirits/gsc-website/node_modules/svelte-preprocess/dist/autoProcess.js
- /Users/ryan/dev/goodspirits/gsc-website/node_modules/svelte-preprocess/dist/index.js
- /Users/ryan/.vscode/extensions/svelte.svelte-vscode-107.2.5/node_modules/svelte-language-server/dist/src/importPackage.js
- /Users/ryan/.vscode/extensions/svelte.svelte-vscode-107.2.5/node_modules/svelte-language-server/dist/src/lib/documents/configLoader.js
- /Users/ryan/.vscode/extensions/svelte.svelte-vscode-107.2.5/node_modules/svelte-language-server/dist/src/lib/documents/Document.js
- /Users/ryan/.vscode/extensions/svelte.svelte-vscode-107.2.5/node_modules/svelte-language-server/dist/src/lib/documents/index.js
- /Users/ryan/.vscode/extensions/svelte.svelte-vscode-107.2.5/node_modules/svelte-language-server/dist/src/server.js
- /Users/ryan/.vscode/extensions/svelte.svelte-vscode-107.2.5/node_modules/svelte-language-server/bin/server.jssvelte(script)

I have dug around and am update to date on all svelte packages.

gsc-website@0.0.1 /Users/ryan/dev/goodspirits/gsc-website
├── @playwright/test@1.32.1
├── @sveltejs/adapter-auto@1.0.3
├── @sveltejs/adapter-node@1.2.3
├── @sveltejs/kit@1.15.0
├── @typescript-eslint/eslint-plugin@5.57.0
├── @typescript-eslint/parser@5.57.0
├── autoprefixer@10.4.14
├── eslint-config-prettier@8.8.0
├── eslint-plugin-svelte3@4.0.0
├── eslint@8.37.0
├── luxon@3.3.0
├── mongoose@7.0.3
├── postcss-load-config@4.0.1
├── postcss@8.4.21
├── prettier-plugin-svelte@2.10.0
├── prettier@2.8.7
├── svelte-check@3.1.4
├── svelte-fast-marquee@0.4.1
├── svelte-intersection-observer@0.10.0
├── svelte-local-storage-store@0.4.0
├── svelte-viewport-info@1.0.0
├── svelte@3.58.0
├── typescript@5.0.3
├── vite@4.2.1
└── vitest@0.25.8

Is this related? Not sure what else to try.

dominikg commented 1 year ago

@rnwolfe please file a separate issue. This issue is about not having a typescript preprocessor installed and then trying to use typescript features. But your code shows you are using vitePreprocess, so it is a different problem. Please include a link to a reproduction in your report.