-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Error: offset is longer than source length w/ Svelte v3.38.3 #6440
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
Comments
That sounds like you're trying to do something unsupported by Svelte because you're getting an error message that says it's not allowed:
|
Yes, that is the root cause, but the calculation of the offset or source length is not correct from Svelte. This is the reason why you don't see the actual problem and therefore rather difficult to detect unless you dig into Vite's source code. So it's more of a general problem with source transpilation and calculating the correct positions and source length. EDIT: |
I'm not quite sure where offset and source length are coming from, but I don't think it's SvelteKit? Maybe this is a bug in Svelte, Vite, or |
Ok, I think I found the problem: Svelte calculates the offset/pos based on the transpiled source: // props.source which is the component source https://github.com/sveltejs/svelte/blob/228832c9a3a6fdb8c11cdbb942444734686a04f6/src/compiler/utils/error.ts#L28
stylesheet: Stylesheet {
...
source: '<script lang="ts">var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n' +
' function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n' +
' return new (P || (P = Promise))(function (resolve, reject) {\n' +
' function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n' +
' function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }\n' +
' function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n' +
' step((generator = generator.apply(thisArg, _arguments || [])).next());\n' +
' });\n' +
'};\n' +
'import { onMount } from "svelte";\n' +
...
'\n' +
'<style>\n' +
...
' .slider :global(.noUi-handle:after, .noUi-handle:before) {\n' +
' left: 10px !important;\n' +
' top: 4px !important;\n' +
' }\n' +
...
' *{}</style>\n',
...
},
... ...and adds it to the error object (error.pos) that Vite uses. // source object https://github.com/vitejs/vite/blob/460d1cda317e4c4d03434f2b3d8de9152620005b/packages/vite/src/node/utils.ts#L257
<script lang="ts">
import { onMount } from "svelte"
...
</script>
...
<style>
...
.slider :global(.noUi-handle:after, .noUi-handle:before) {
left: 10px !important;
top: 4px !important;
}
...
</style> ...which, of course, does not match. This is a Svelte and not a SvelteKit issue. |
Did you enable source maps for TS? I guess you use Maybe we should enable that by default in the starter template. |
@dummdidumm thanks! The problem was that I set sveltePreprocess({
defaults: {
script: 'typescript',
style: 'postcss',
},
postcss: true,
}), When I remove it the language service shows the error in VSC. |
Yes, it's a known problem that PostCSS does not produce source maps and therefore the chain of source maps breaks. Not sure if there are possibilities for |
@dummdidumm sorry, it's still a svelte problem that the offset is still passed to Vite incorrectly, although the language service shows the error in VSC. Yes, the error only occurs (for me) when I have used the :global incorrectly, but this could be a problem in other situations as well. |
Ok I'll reopen until the culprit is found, but I still think this is a source map issue of third parties involved. Svelte can't magically know what the offsets are if there's no proper source map passed to it. Also please try setting source maps to true explicitely: sveltePreprocess({
defaults: {
script: 'typescript',
style: 'postcss',
},
sourceMap: true // <---------
}), |
I did that but it does not prevent the error. I added the error.pos (offset) from Svelte (2845) and the source length from Vite (2515) to Vite's error message: offset is longer than source length! 2845 2515
Error: offset is longer than source length! 2845 2515
at numberToPos (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:4234:15)
at formatError (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:44612:24)
at TransformContext.error (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:44591:19)
at Object.transform (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:44802:25) The offset is set from the transpiled file from Svelte and added to the error object (error.pos) which could be okay but Vite uses the non-transpiled file and checks if the length of it is greater than the offset (error.pos), which might be the case if the error occurs further up but then the offset is still not correct. I moved the wrong :global(...) must contain a single selector
ValidationError: :global(...) must contain a single selector
at error (file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:16752:19)
at Component.error (file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:29038:9) tl;dr: If an error occurred at the end of the Svelte file, the offset is higher than the source length (not transpiled) because the error position from Svelte is taken from the transpiled file. If an error occurs at a position where the offset is still within the range of the source length, then everything is fine, but if you were to compare the error position (offset) from Svelte and the error position from the Vite's file source, it would not match. EDIT: Either Vite should use the transpiled Svelte file as source (not sure where this is coming from) or the |
I would guess the latter. You probably want to know the location in the original source since that's what the user sees. @milahu did quite a bit of work on getting our sourcemaps working earlier and might be interested in this |
@akaufmann can you help to reproduce the error? something like ... reproduce.sh#!/usr/bin/env bash
# reproduce bug in svelte-preprocess
# Error: offset is longer than source length!
set -o xtrace # print cmds
expect << EOF
# generated by autoexpect
set timeout -1
spawn pnpx create-svelte@next my-app
match_max 100000
expect -re "Install the following package: create-svelte@next?"
# yes
send -- "\r"
expect -re "Which Svelte app template?"
# default (svelte kit)
send -- "\r"
expect -re "Use TypeScript?"
# right -> yes
send -- "\033\[C"
send -- "\r"
expect -re "Add ESLint for code linting?"
# no
send -- "\r"
expect -re "Add Prettier for code formatting?"
# no
send -- "\r"
expect eof
EOF
cd my-app
cat >src/routes/index.svelte << 'EOF'
<script lang="ts">
import { onMount } from 'svelte';
onMount(async () => {
const delay = (ms: number) => new Promise((res) => setTimeout(res, ms));
await delay(3000);
});
</script>
<div>Hello world!</div>
<style>
/* :global(...) must contain a single selector */
:global(.a, .b) { color: red; }
</style>
EOF
pnpm install
# only in dev mode:
# Error: offset is longer than source length!
npm run dev -- --open edit: async code + dev mode |
@milahu you get the error with a Svelte file like this: <script lang="ts">
import { onMount } from 'svelte';
onMount(async () => {
const delay = (ms: number) => new Promise((res) => setTimeout(res, ms));
await delay(3000);
});
</script>
<div>Hello world!</div>
<style>
.foo :global(.bar, .baz) {
left: 10px;
top: 4px;
}
</style> Just create a SvelteKit demo app with |
thanks, i fixed my currently proposed solution: |
Sounds related to #6089 , is that correct? Edit: No it's not directly related. What you mean is that when an error or warning is thrown, the positions are those of the final source that Svelte sees, positions are not mapped back, the map passed in is not used here. We have to map these positions oursleves in |
yes
but somewhere between one solution is to make or we fix the problem later in the toolchain |
Good question, what would make semantically more sense? I'm split here .. more opinions would be good. |
ideally both:
started here problem: low-resolution sourcemaps <style>/* mapped: 19:6 -> original 13:6 */
/* not mapped */
:global(.a, .b) { color: red; } /* location of error - not mapped */
/* not mapped */
</style><!-- mapped --> -> backtracing edit: at least in this case, i can backtrace the unmapped segment |
related: vitejs/vite#4782 |
Since the update to the latest Svelte version (3.38.3) an error is thrown from Vite when a request comes in.
Logs
I traced it to an error in one of my style blocks not displaying because the offset/source length is incorrect:
The offset is 2845 (offset/pos) but the source length is 2417 in that case.
https://github.com/vitejs/vite/blob/460d1cda317e4c4d03434f2b3d8de9152620005b/packages/vite/src/node/utils.ts#L252
Information about your SvelteKit Installation:
Let me know if this info is sufficient and reproducible with any SvelteKit app with the latest Svelte version + multiple selectors in a single
:global
like:global(.foo, .bar)
or a repro is needed.PS: Not sure if the bug report is correct here or should be created in the svelte or vite-plugin-svelte repo.
The text was updated successfully, but these errors were encountered: