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] Enabling Runes mode via compilerOptions incorrectly enforces it for external libraries #9632

Closed
AgarwalPragy opened this issue Nov 24, 2023 · 5 comments
Milestone

Comments

@AgarwalPragy
Copy link

AgarwalPragy commented Nov 24, 2023

Describe the bug

Non backwards-compatible Runes mode can be enabled via compilerOptions in svelte.config.js
https://svelte-5-preview.vercel.app/docs/runes#how-to-opt-in

export default {
  compilerOptions: {
    runes: true
  }
};

However, doing this enforces the runes mode even for external libraries. This means that any libraries written in svelte-4.x cannot be imported.

Ideally, runes mode should only be enforced for the current app and not the external libaries

Reproduction

https://github.com/AgarwalPragy/svelte-issue-9632

src/routes/+page.svelte

<script>
  import { Markdown } from 'svelte-exmarkdown';
</script>

<Markdown md='hello' />

Logs

> [email protected] dev .
> vite dev "--" "--open"

3:52:50 PM [vite-plugin-svelte] svelte 5 support in v-p-s is experimental, breaking changes can occur in any release until this notice is removed
3:52:50 PM [vite-plugin-svelte] svelte 5 does not support svelte-inspector yet, disabling it
3:52:50 PM [vite-plugin-svelte] svelte 5 does not support hmr api yet, disabling it for now

Port 5173 is in use, trying another one...

  VITE v4.5.0  ready in 309 ms

  ➜  Local:   http://localhost:5174/
  ➜  Network: use --host to expose
  ➜  press h to show help
node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-exmarkdown/dist/Transparent.svelte:1:8 Cannot use $$props in runes mode
node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-exmarkdown/dist/Renderer.svelte:7:0 Cannot use `export let` in runes mode — use $props instead
node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-exmarkdown/dist/Markdown.svelte:7:0 Cannot use `export let` in runes mode — use $props instead
3:52:51 PM [vite] Error when evaluating SSR module /node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-exmarkdown/dist/index.js: failed to import "/node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-exmarkdown/dist/Markdown.svelte"
|- CompileError: Cannot use `export let` in runes mode — use $props instead
    at error (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/errors.js:569:8)
    at ExportNamedDeclaration (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/2-analyze/validation.js:678:3)
    at go (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:49:5)
    at visitor (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:64:4)
    at go (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:49:5)
    at visitor (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:64:4)
    at Object.next (file://node_modules/.pnpm/[email protected]/node_modules/zimmerframe/src/walk.js:106:21)
    at go (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:45:29)
    at next (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:55:7)
    at _ (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/scope.js:661:4)

3:52:51 PM [vite] Error when evaluating SSR module /src/routes/+page.svelte: failed to import "/node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-exmarkdown/dist/index.js"
|- CompileError: Cannot use `export let` in runes mode — use $props instead
    at error (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/errors.js:569:8)
    at ExportNamedDeclaration (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/2-analyze/validation.js:678:3)
    at go (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:49:5)
    at visitor (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:64:4)
    at go (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:49:5)
    at visitor (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:64:4)
    at Object.next (file://node_modules/.pnpm/[email protected]/node_modules/zimmerframe/src/walk.js:106:21)
    at go (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:45:29)
    at next (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:55:7)
    at _ (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/scope.js:661:4)

{
  name: 'CompileError',
  id: 'node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-exmarkdown/dist/Markdown.svelte',
  message: 'node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-exmarkdown/dist/Markdown.svelte:7:0 Cannot use `export let` in runes mode — use $props instead',
  frame: '4  |  } from "./contexts";\n' +
    '5  |  import Renderer from "./Renderer.svelte";\n' +
    '6  |  import { createParser, nonNullable } from "./utils";\n' +
    '   |                                                       ^\n' +
    '7  |  export let md;\n' +
    '8  |  export let plugins = [];',
  code: 'invalid-legacy-export',
  stack: 'CompileError: Cannot use `export let` in runes mode — use $props instead\n' +
    '    at error (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/errors.js:569:8)\n' +
    '    at ExportNamedDeclaration (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/2-analyze/validation.js:678:3)\n' +
    '    at go (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:49:5)\n' +
    '    at visitor (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:64:4)\n' +
    '    at go (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:49:5)\n' +
    '    at visitor (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:64:4)\n' +
    '    at Object.next (file://node_modules/.pnpm/[email protected]/node_modules/zimmerframe/src/walk.js:106:21)\n' +
    '    at go (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:45:29)\n' +
    '    at next (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/visitors.js:55:7)\n' +
    '    at _ (file://node_modules/.pnpm/[email protected]/node_modules/svelte/src/compiler/phases/scope.js:661:4)',
  loc: {
    line: 7,
    column: 0,
    file: 'node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-exmarkdown/dist/Markdown.svelte'
  },
  plugin: 'vite-plugin-svelte',
  pluginCode: '<script>import {\n' +
    '  createComponentsContextValue,\n' +
    '  setComponentsContext\n' +
    '} from "./contexts";\n' +
    'import Renderer from "./Renderer.svelte";\n' +
    'import { createParser, nonNullable } from "./utils";\n' +
    'export let md;\n' +
    'export let plugins = [];\n' +
    'let parse;\n' +
    '$:\n' +
    '  parse = createParser(plugins);\n' +
    'const componentsContextValue = createComponentsContextValue({});\n' +
    '$:\n' +
    '  componentsContextValue.set({\n' +
    '    ...plugins.map((plugin) => plugin.renderer).filter(nonNullable).reduce((acc, cur) => ({ ...acc, ...cur }), {})\n' +
    '  });\n' +
    'setComponentsContext(componentsContextValue);\n' +
    'let result;\n' +
    '$:\n' +
    '  result = parse(md);\n' +
    '</script>\n' +
    '\n' +
    '<Renderer astNode={result} />\n'
}

System Info

System:
    OS: macOS 13.5.1
    CPU: (8) arm64 Apple M2
    Memory: 47.34 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 21.1.0 - /opt/homebrew/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 10.2.0 - /opt/homebrew/bin/npm
    pnpm: 8.10.2 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 119.0.6045.159
    Safari: 16.6
  npmPackages:
    svelte: ^5.0.0-next.1 => 5.0.0-next.11

Severity

blocking an upgrade

@AgarwalPragy AgarwalPragy changed the title Enabling Runes mode via compilerOptions incorrectly enforces it for external libraries [Svelte 5] Enabling Runes mode via compilerOptions incorrectly enforces it for external libraries Nov 24, 2023
@dummdidumm
Copy link
Member

@dominikg I believe this is something that needs to happen at the bundler plugin level, right?

@AgarwalPragy
Copy link
Author

Temporary workaround provided by @dominikg via discord

with vite-plugin-svelte you can use dynamicCompileOptions to change it by file. https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#dynamiccompileoptions
for vite 5/vite-plugin-svelte 3

// svelte.config.js
export default {
  //...
  vitePlugin:{
    dynamicCompileOptions({filename}){
      if(filename.includes('node_modules'){
        return {runes: undefined} // or false, check what works
      }
    }
  }
}

for sveltekit you have to add it as vitePlugin.experimental.dynamicCompileOptions

@Rich-Harris
Copy link
Member

This is working as expected. The dynamicCompileOptions solution isn't a temporary workaround, it's explicitly the mechanism for having different compile options for different files

@AgarwalPragy
Copy link
Author

@Rich-Harris Setting dynamicCompileOptions correctly to handle various libraries (svelte-4 and svelte-5) would be non-trivial for the users.

@dominikg mentioned the following via Discord.

workaround, we'll have to think about how this is supposed to work, there will be libraries for svelte4, svelte5 and both, and in the svelte5 case some might use runes while others might not. Optimal case is we have a declaration or heuristic so the bundler plugin knows which mode to use.

@dominikg
Copy link
Member

we may be able to pass more info into dynamicCompileOptions too. hopefully this is just needed for a transition period until libraries have been updated to support 5

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

5 participants