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

Svelte 5: Unexpected character '@' when using *.svelte.ts with Decorators and $state and importing in client #12205

Closed
gemue-parndt opened this issue Jun 27, 2024 · 5 comments
Labels
awaiting submitter needs a reproduction, or clarification

Comments

@gemue-parndt
Copy link

Describe the bug

I can't use a class with a decorated method.

|- SyntaxError: Unexpected character '@' (27:2)

Reproduction

Generate a decorator in a file , use the decorator on a class method and import the class in the client side.

test.svelte.ts

function logToHistory(target: any, propertyKey:any) {
    return function (this: EditorPageState, ...args: any[]) {
        console.log('params: ', ...args);
        const result = target.call(this, ...args);
        console.log('result: ', result);
        return result;
    }
}

export class History {
    private _history: IMemento<EditorState>[] = [];
    private anyCustomState: $state(false) // for simplicity
    @logToHistory
    addElement = (element: Base) => {
        this._state.content.push(element);
    }
}

+page.svelte

<script lang="ts>
import History from 'test.svelte'

const history = new History()
</script>

Results in:

|- SyntaxError: Unexpected character '@' (x:x)

Logs

{
  name: 'SyntaxError',
  id: '//src/lib/client/editor/EditorPageState.svelte.ts',
  message: "Unexpected character '@' (27:2)",
  frame: '',
  code: undefined,
  stack: "SyntaxError: Unexpected character '@' (27:2)\n" +
    '    at pp$4.raise (file://///node_modules/acorn/dist/acorn.mjs:3580:13)\n' +
    '    at pp.getTokenFromCode (file://///node_modules/acorn/dist/acorn.mjs:5561:8)\n' +
    '    at pp.readToken (file://///node_modules/acorn/dist/acorn.mjs:5248:15)\n' +
    '    at pp.nextToken (file://///node_modules/acorn/dist/acorn.mjs:5239:15)\n' +
    '    at pp.next (file://///node_modules/acorn/dist/acorn.mjs:5200:8)\n' +
    '    at pp$8.parseBlock (file://///node_modules/acorn/dist/acorn.mjs:1258:8)\n' +
    '    at pp$5.parseFunctionBody (file://///node_modules/acorn/dist/acorn.mjs:3398:22)\n' +
    '    at pp$5.parseMethod (file://///node_modules/acorn/dist/acorn.mjs:3337:8)\n' +
    '    at pp$8.parseClassMethod (file://///node_modules/acorn/dist/acorn.mjs:1533:35)\n' +
    '    at pp$8.parseClassElement (file://///node_modules/acorn/dist/acorn.mjs:1491:10)',
  plugin: 'vite-plugin-svelte-module',
  pluginCode: 'import { Utils } from "$lib/utils";\n' +
    'function logToHistory(target, propertyKey) {\n' +
    '  return function(...args) {\n' +
    '    console.log("params: ", ...args);\n' +
    '    const result = target.call(this, ...args);\n' +
    '    console.log("result: ", result);\n' +
    '    return result;\n' +
    '  };\n' +
    '}\n' +
    'export class EditorPageState {\n' +
    '  initalSize = Utils.convertMmToPx(100);\n' +
    '  _state = {\n' +
    '    title: "Untitled",\n' +
    '    area: {\n' +
    '      width: this.initalSize,\n' +
    '      height: this.initalSize\n' +
    '    },\n' +
    '    content: [],\n' +
    '    scale: 1,\n' +
    '    showGrid: false,\n' +
    '    selectedElement: null\n' +
    '  };\n' +
    '  _history = [];\n' +
    '  get state() {\n' +
    '    return this._state;\n' +
    '  }\n' +
    '  @logToHistory\n' +
    '  addElement = (element) => {\n' +
    '    this._state.content.push(element);\n' +
    '  };\n' +
    '}\n'
}

System Info

Typescript: 5.5.2
Svelte: 5.0.0-next.166
SvelteKit: 2.5.17
Bun: 1.1.17

Severity

annoyance

@paoloricciuti
Copy link
Member

This is basically a duplicate of #11502

@dummdidumm
Copy link
Member

Depends - I would have expected the typescript plugin to run on that file first, which would then down level the decorator. Wondering why that isn't the case, and whether that's due to specific tsconfig settings.

Please provide a proper reproduction link so we can investigate

@dummdidumm dummdidumm added the awaiting submitter needs a reproduction, or clarification label Jun 27, 2024
@Padi2312
Copy link

(Its me @gemue-parndt just from my personal account)

@dummdidumm I just uploaded a reproduceable example. example.zip

I also figured out it doesn't depends on the runtime, it doesn't work neither with Bun nor with Node.
Additionally i made the example just with Svelte and Svelte 4, also having the same problem.

@gemue-parndt
Copy link
Author

(Its me @gemue-parndt just from my personal account)

@dummdidumm I just uploaded a reproduceable example. example.zip

I also figured out it doesn't depends on the runtime, it doesn't work neither with Bun nor with Node. Additionally i made the example just with Svelte and Svelte 4, also having the same problem.

here you go

@dummdidumm
Copy link
Member

This is definetly unrelated to Svelte, therefore closing.

I'd still wanted to figure out why decorators aren't downleveled though. AFAIK ESbuild supports decorators, and so does TS 5.0+, so I would've thought that Vite would downlevel them. Things I tried without success:

  • setting "target": "ES2022" in the tsconfig.json
  • setting build.target to 'es2022' in vite.config.ts

What finally worked, thanks to pointers in vitejs/vite#17308:

  • setting esbuild.target to 'es2022' in vite.config.ts

What also works, but which isn't really what one should do going forward is to set "experimentalDecorators": true in your tsconfig.json. This means TypeScript's obsolete/deprecated decorator downleveling is used.

@dummdidumm dummdidumm closed this as not planned Won't fix, can't repro, duplicate, stale Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting submitter needs a reproduction, or clarification
Projects
None yet
Development

No branches or pull requests

4 participants