Skip to content

SublimeText 4: Prettier parser conflict with Svelte files requires manually specifying Svelte parser #481

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

Open
hkjens opened this issue Jan 14, 2025 · 1 comment

Comments

@hkjens
Copy link

hkjens commented Jan 14, 2025

Description

When using SublimeText 4: Prettier defaults to HTML parser for .svelte files causing formatting errors with JavaScript/rune code. The issue can temporarily resolve after HTML changes because this triggers a different parser selection.

Root cause: Prettier needs explicit --parser=svelte and --plugin=prettier-plugin-svelte arguments to correctly format Svelte files.

My current workaround: use a wrapper script that enforces correct parser selection based on file extension.

Original issues

When modifying JavaScript code in a Svelte 5 component with runes, Prettier throws a syntax error. However, making any whitespace change in the HTML part makes Prettier work again.

Steps to Reproduce

  1. Start with this minimal example that uses Svelte 5 runes:
<script>
  import { onMount } from 'svelte';

  let someVar = 456;
  let imageData = $state(null);

  onMount(() => {
    if (!imageData) {
      imageData = { loaded: false };
    }
  });

  $effect(() => {
    if (imageData?.loaded) {
      console.log('Loaded!');
    }
  });
</script>

{#if imageData}
  <div
    class="w-[200px]"
    style="height: 200px">
    Content here
  </div>
{/if}
  1. Change 456 to 4567
  2. Try to save/format with Prettier
  3. Observe error
  4. Add a single space anywhere in the HTML part
  5. Try to save/format again - now it works

Error message

[error] test.svelte: SyntaxError: Unexpected token (8:5)
[error]    6 |
[error]    7 |   onMount(() => {
[error] >  8 |     if (!imageData) {
[error]      |     ^
[error]    9 |       imageData = { loaded: false };
[error]   10 |     }
[error]   11 |   });

Expected Behavior

Prettier should format the file without errors, regardless of whether changes are made to the script or HTML sections.

Environment

  • Sublime Text 4, build 4189
  • prettier: 3.4.2
  • prettier-plugin-svelte: 3.3.2
  • prettier-plugin-tailwindcss: 0.6.9
  • Svelte: 5.x

Additional Notes

  • The error message points to an if statement, but the error is triggered by changing a variable declaration elsewhere in the code
  • The error only occurs when modifying the script section
  • Adding any whitespace to the HTML section temporarily fixes the issue
@hkjens
Copy link
Author

hkjens commented Jan 17, 2025

I found the root cause of this issue. The error occurs because Prettier is incorrectly using the HTML parser instead of the Svelte parser.

Here's my complete working (User) configuration for Sublime Text with JsPrettier that fixes the issue for svelte files but incorrectly formats JS files.

{
  "debug": true,
  "auto_format_on_save": true,
  "prettier_cli_path": "./node_modules/.bin/prettier",
  "allow_inline_formatting": true,
  "custom_file_extensions": ["svelte"],
  "format_on_save_extensions": ["js", "svelte"],
  "additional_cli_args": {
    "--plugin": "prettier-plugin-svelte",
    "--parser": "svelte"
  }
}

Configuring the parser via a project .prettierrc.js as follows does not work:

  plugins: ['prettier-plugin-svelte'],
  overrides: [
    {
      files: '*.svelte',
      options: {
        parser: 'svelte'
      }
    }
  ]

I've tried a lot of combinations of .prettierrc.js (es6 formatted) and sublime JsPrettier.sublime-settings, but specifying parsers by file type seems to be impossible.

As workaround I now use a bash script prettier-wrapper.sh that applies the correct settings:

JsPrettier.sublime-settings

{
  "debug": true,
  "auto_format_on_save": true,
  "allow_inline_formatting": true,
  "custom_file_extensions": ["svelte"],
  "format_on_save_extensions": ["js", "svelte"],
  "prettier_cli_path": "~/bin/prettier-wrapper.sh"
}

.prettierrc.js

export default {
  useTabs: false,
  singleQuote: true,
  semi: true,
  trailingComma: 'none',
  bracketSpacing: true,
  bracketSameLine: false
};

~/bin/prettier-wrapper.sh

#!/bin/bash

# Get the file name
if [[ "$*" == *"--stdin-filepath"* ]]; then
  FILE=$(echo "$*" | grep -o '\--stdin-filepath [^ ]*' | cut -d' ' -f2)
  ARGS=$(echo "$@" | sed 's/--parser[= ][^ ]*//')
else
  FILE=$1
  shift
  ARGS=$(echo "$@" | sed 's/--parser[= ][^ ]*//')
fi

# Configure prettier options
PRETTIER_CMD="./node_modules/.bin/prettier"
SVELTE_OPTS="--parser=svelte --plugin=prettier-plugin-svelte"

# Apply formatting based on the file type
if [[ "${FILE##*.}" == "svelte" ]]; then
  [ -t 0 ] && cat "$FILE" | $PRETTIER_CMD $SVELTE_OPTS $ARGS || \
  cat | $PRETTIER_CMD $SVELTE_OPTS $ARGS
else
  [ -t 0 ] && cat "$FILE" | $PRETTIER_CMD $ARGS || \
  cat | $PRETTIER_CMD $ARGS
fi

Create project inside ~/bin to install dependencies

pnpm init
pnpm add  prettier prettier-plugin-svelte

@hkjens hkjens changed the title Prettier fails on script changes but works after HTML whitespace change (Svelte 5) SublimeText 4: Prettier parser conflict with Svelte files requires manually specifying Svelte parser Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant