Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$page is an illegal variable name #652

Open
2 tasks done
huntabyte opened this issue Dec 15, 2023 · 15 comments
Open
2 tasks done

$page is an illegal variable name #652

huntabyte opened this issue Dec 15, 2023 · 15 comments
Labels
bug Something isn't working feat: svelte v5

Comments

@huntabyte
Copy link
Member

huntabyte commented Dec 15, 2023

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.56.0

What version of eslint-plugin-svelte are you using?

2.36.0-next.3

What did you do?

Configuration
/** @type { import("eslint").Linter.FlatConfig } */
module.exports = {
	root: true,
	extends: [
		'eslint:recommended',
		'plugin:@typescript-eslint/recommended',
		'plugin:svelte/recommended'
	],
	parser: '@typescript-eslint/parser',
	plugins: ['@typescript-eslint'],
	parserOptions: {
		sourceType: 'module',
		ecmaVersion: 2020,
		extraFileExtensions: ['.svelte']
	},
	env: {
		browser: true,
		es2017: true,
		node: true
	},
	overrides: [
		{
			files: ['*.svelte'],
			parser: 'svelte-eslint-parser',
			parserOptions: {
				parser: '@typescript-eslint/parser'
			}
		}
	]
};
  1. pnpm create svelte@latest
  2. Choose Skeleton Project, Typescript, Eslint, Svelte 5
  3. install dependencies
  4. Realize eslint-plugin-svelte@next isn't installed, so pnpm i -D eslint-plugin-svelte@next
<!-- src/routes/+page.svelte -->
<script lang="ts">
	import { page } from "$app/stores"
	console.log($page.data) // $page is an illegal variable name.
</script>

What did you expect to happen?

$page to be a legal variable name

What actually happened?

$page is an illegal variable name. To reference a global variable called $page, use globalThis.$page(illegal-global)eslint[svelte/valid-compile](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-compile/)
let $page: Page<Record<string, string>, string | null>

4:14 error $page is an illegal variable name. To reference a global variable called $page, use globalThis.$page(illegal-global) svelte/valid-compile

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/huntabyte/s5-illegal-variable-repro

Additional comments

I noticed this only occurs when using Typescript. If I go through the create svelte flow and choose "Javascript with JSDoc" everything is good.

@lyssieth
Copy link

lyssieth commented Jan 7, 2024

This also happens for a custom store (in my case secret or $secret) as well.

Also Svelte 5, Eslint, TS.

@ota-meshi ota-meshi added the bug Something isn't working label Jan 15, 2024
@christophsturm
Copy link

is there a workaround? btw, where is the source of the next plugin, in case i want to work on a PR

@RyousukeUchino
Copy link

RyousukeUchino commented Mar 19, 2024

@christophsturm @huntabyte

I'm not entirely sure if this is correct, but I was able to find a workaround using the following method:

  • eslint-plugin-svelte@2.36.0-next.12
  • svelte@5.0.0-next.80
<script lang="ts">
  import { page } from '$app/stores';
  import { get } from 'svelte/store';

  const currentPagePath = get(page).url.pathname;
  const currentPageData = get(page).data
</script>
{#if currentPagePath === '/store'}
  hoge fuga
{/if}

@unlocomqx
Copy link

Is it possible to disable this error?

@jill64
Copy link

jill64 commented Mar 30, 2024

As you may already know, the @RyousukeUchino proposal may suppress warnings, but is not recommended in hot code paths.

https://svelte.dev/docs/svelte-store#get

This works by creating a subscription, reading the value, then unsubscribing. It's therefore not recommended in hot code paths.

@jill64
Copy link

jill64 commented Mar 30, 2024

@unlocomqx

The following can be used as a workaround

Disable in one line

<script>
  import { page } from '$app/stores';

  // eslint-disable-next-line svelte/valid-compile
  const currentPagePath = $page.url.pathname;
</script>

Disable in project

.eslintrc.cjs

module.exports = {
  // ...
  rules: {
    "svelte/valid-compile": "off"
  }
}

Check here for additional details
https://eslint.org/docs/latest/use/configure/rules

@ryanatkn
Copy link

The get proposal is also unsuitable as a general workaround because it's non-reactive. It subscribes and immediately unsubscribes, whereas $ subscribes and doesn't unsubscribe until the component is destroyed.

@Conduitry
Copy link
Member

This plugin appears to be incorrectly transforming the <script> tag (perhaps via TypeScript?) before passing it to the compiler.

Something like

<script>
	import { page } from '$app/stores';
</script>

is getting transformed into

<script>import '$app/stores';
//# sourceMappingURL=module.js.map
</script>

presumably because it's only operating on the <script> tag and it thinks page is unused and it's safe to turn that into a bare import '$page/stores'.

Putting a bare reference to page; in the <script> tag seems to be a workaround for the time being.

<script>
	import { page } from '$app/stores';
	page;
</script>

gets transformed into

<script>import { page } from '$app/stores';
page;
//# sourceMappingURL=module.js.map
</script>

but the real solution is going to be fixing this transformation that the plugin does to the script tag before passing it to the Svelte compiler. If this is related to TypeScript, I think the solution is going to be to just stop running the <script> tag through TypeScript in Svelte 5, because that should be already handled by the Svelte compiler.

@unlocomqx
Copy link

I tried adding page as a global in eslint config
no luck

not a big deal though

@dummdidumm
Copy link
Member

From @Conduitry's investigation my shot in the dark is that ts.transpileModule (or whatever the low level transpiration API is called) is called with the wrong config, where imports are not left alone and instead "treeshaken". verbatimModuleSyntax was introduced for this reason in TS and is the recommended default since TS 5.0, and leaves imports as is.

@Conduitry
Copy link
Member

@dummdidumm In Svelte 5, is there a reason to transpile the <script> tag at all before passing it to the Svelte compiler, though?

@rChaoz
Copy link

rChaoz commented May 2, 2024

I don't think so, the Svelte 5 compiler natively supports Typescript (now even in the template, not just the script tag).

@niemyjski
Copy link

I'm running into this as well.

@ptrxyz
Copy link
Contributor

ptrxyz commented May 14, 2024

I tried setting verbatimModuleSyntax to true, but it doesn't seem to have an effect. So yes, probably it is using a wrong configuration. :/

@Alia5
Copy link

Alia5 commented May 14, 2024

I don't think so, the Svelte 5 compiler natively supports Typescript (now even in the template, not just the script tag).

It doesn't fully support all TS features, decorators and enums among them, so there might still be a need to preproccess the files beforehand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working feat: svelte v5
Projects
None yet
Development

No branches or pull requests