language-tools icon indicating copy to clipboard operation
language-tools copied to clipboard

Svelte's tooling ignores TypeScript code from previous `preprocessors`

Open ivanhofer opened this issue 2 years ago • 3 comments

Description

Speaking of the VS Code extension and the svelte-check command, when I'm adding my own preprocessor that modifies the script tag to include additional TypeScript syntax, that part gets ignored by the tooling.

I tried svelte-check and added some debug logs to see if the custom preprocessor get's loaded. The logs show up, but If I'm adding TypeScript syntax, the tooling ignores it.

Not sure what exactly happens, but it seems that the last preprocessor doesn't use the full output from the previous preprocessors.

Proposed solution

The VS Code extension and svelte-check should take the input from the previous preprocessors.

Alternatives

Leave it like it is and don't allow custom use-cases.

Additional Information, eg. Screenshots

Here is my svelte.config.js file

import preprocess from 'svelte-preprocess'

/** @type {import('@sveltejs/kit').Config} */
const config = {
	// Consult https://github.com/sveltejs/svelte-preprocess
	// for more information about preprocessors
	preprocess: [
		{
			script: ({ content, attributes, filename }) => {
				if (filename.includes('/src/routes/') && attributes.lang === 'ts' && attributes.context === 'module') {
					console.log(`1. the custom preprocessor get's used for '${filename}'`)
					const file = filename.substring(filename.lastIndexOf('/') + 1)
					const path = file.substring(0, file.indexOf('.'))
					const typePath = `./__types/${path}`

					console.log(`2. adding type import for '${filename}'`)
					return {
						code: `
import type { Load } from '${typePath}';
console.log('this gets logged');
${content}`,
					}
				}
			},
		},
		{
			script: ({ markup, content, attributes, filename }) => {
				if (filename.includes('/src/routes/') && attributes.lang === 'ts' && attributes.context === 'module') {
					console.log(`3. the resulting output for '${filename}' is:
${content}
`)
				}
			},
		},
		preprocess(),
	],
}

export default config

The first preprocessor will add the generated type imports for the Load function. The second preprocessor checks if the first preprocessor modified the source code The third preprocessor is the usual svelte-preprocess that ccan handle TypeScript syntax

Here is my custom route routes/test/[id]/summary:

<script context="module" lang="ts">
	export const load: Load = ({ params }) => {
		return { props: { id: params.id } }
	}
</script>

<script lang="ts">
	export let id: number
</script>

hello {id}

When running svelte-check I get following error: image

As you can see my custom preprocessor gets executed, but in the end I still see an error because the type import for Load is missing.

ivanhofer avatar Jul 23 '22 11:07 ivanhofer

This is primarily a duplicate of https://github.com/sveltejs/language-tools/issues/339 although that one is specific about template preprocess, the limitation we have still applied. The type check step doesn't use the preprocess config.

It could also be argued that even if we were to fix that issue. The script preprocesses would probably still be ignored. Currently, There's no way to tell if the preprocess is intended for type checks. And we can't run all the preprocessing as the code will not be typescript anymore.

jasonlyu123 avatar Jul 24 '22 01:07 jasonlyu123

Thanks, I now understand the problem better. So the propreocessor structure would need to be updated to be able to distinguish between "regular" preprocessors and preprocessors that make TypeScript changes? And ideally this type of preprocessor is performed in a synchronous way.

The issue you have linked (#339) is about making an asynchronous process synchronous. So I think those are two different problems that can be solved independently, right?

ivanhofer avatar Jul 24 '22 07:07 ivanhofer