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

SSR source map merging fails on empty file segments (Error: No element indexed by 0) #2391

Closed
GrygrFlzr opened this issue Mar 5, 2021 · 4 comments · Fixed by #2441
Closed

Comments

@GrygrFlzr
Copy link
Member

Describe the bug

The following source map merging:

let map = s.generateMap({ hires: true })
if (inMap && inMap.mappings) {
map = merge(inMap, {
...map,
sources: inMap.sources,
sourcesContent: inMap.sourcesContent
}) as SourceMap

Given an empty input will throw an error:

Dev mode log
$ pnpm dev

> sourcemap-repro@1.0.0 dev C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro
> node server

Error: No element indexed by 0
    at ArraySet$2.ArraySet_at [as at] (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:24278:9)
    at BasicSourceMapConsumer.<anonymous> (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:25193:67)
    at Array.map (<anonymous>)
    at BasicSourceMapConsumer.SourceMapConsumer_eachMapping [as eachMapping] (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:25192:14)
    at merge (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:26656:18)
    at ssrTransform (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:61382:15)
    at transformRequest (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:61650:48)
    at async instantiateModule (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:67994:10)
Error: No element indexed by 0
    at ArraySet$2.ArraySet_at [as at] (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:24278:9)
    at BasicSourceMapConsumer.<anonymous> (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:25193:67)
    at Array.map (<anonymous>)
    at BasicSourceMapConsumer.SourceMapConsumer_eachMapping [as eachMapping] (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:25192:14)
    at merge (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:26656:18)
    at ssrTransform (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:61382:15)
    at transformRequest (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:61650:48)
    at async instantiateModule (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:67994:10)
Error: No element indexed by 0
    at ArraySet$2.ArraySet_at [as at] (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:24278:9)
    at BasicSourceMapConsumer.<anonymous> (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:25193:67)
    at Array.map (<anonymous>)
    at BasicSourceMapConsumer.SourceMapConsumer_eachMapping [as eachMapping] (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:25192:14)
    at merge (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:26656:18)
    at ssrTransform (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:61382:15)
    at transformRequest (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:61650:48)
    at async instantiateModule (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:67994:10)
Error: No element indexed by 0
    at ArraySet$2.ArraySet_at [as at] (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:24278:9)
    at BasicSourceMapConsumer.<anonymous> (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:25193:67)
    at Array.map (<anonymous>)
    at BasicSourceMapConsumer.SourceMapConsumer_eachMapping [as eachMapping] (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:25192:14)
    at merge (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:26656:18)
    at ssrTransform (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:61382:15)
    at transformRequest (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:61650:48)
    at async instantiateModule (C:\Users\GrygrFlzr\Documents\projects\sourcemap-repro\node_modules\.pnpm\vite@2.0.5\node_modules\vite\dist\node\chunks\dep-e0f09032.js:67994:10)

Important to note here that merge is an import from merge-source-map, which has not been maintained since December 2017. A somewhat (?) related bug report from May 2018 was already filed on its repo: keik/merge-source-map#6, but with no response. This is why I am bringing up the issue in the vite repository instead, as I do not think it is solvable on the upstream dependency.

Reproduction

https://github.com/GrygrFlzr/vite-sourcemap-repro

git clone https://github.com/GrygrFlzr/vite-sourcemap-repro.git
cd vite-sourcemap-repro
pnpm install
pnpm dev
# load the page on http://localhost:3000

System Info

  • vite version: 2.0.5
  • Operating System: Windows 10 10.0.19042
  • Node version: 14.15.3
  • Package manager (npm/yarn/pnpm) and version: npm 7.5.2 / yarn 1.22.10 / pnpm 5.18.1
@GrygrFlzr GrygrFlzr changed the title SSR source map merging fails on empty file (Error: No element indexed by 0) SSR source map merging fails on empty file segments (Error: No element indexed by 0) Mar 6, 2021
@GrygrFlzr
Copy link
Member Author

GrygrFlzr commented Mar 6, 2021

I've further tracked this down to empty segments of files.

That is to say, not only do all loaded files need to be not-empty, in a .svelte file's case a <script> tag section must exist and not be empty.

This will error:

<span>Hello world!</span>

And so will this:

<script>
    // just a comment here
</script>
Hello world

This will succeed:

<script>
    let name = 'world';
</script>
<span>Hello {name}!</span>

It must have some proper content (i.e. not just comments, not compiled down to nothing) or it will trigger the bug.

@milahu
Copy link
Contributor

milahu commented Mar 6, 2021

merge is an import from merge-source-map, which has not been maintained since December 2017

svelte uses ampproject/remapping which is up to date

see function combine_sourcemaps in svelte/src/compiler/utils/mapped_code.ts

@GrygrFlzr
Copy link
Member Author

GrygrFlzr commented Mar 9, 2021

I've gotten some progress on this issue - it's not necessarily empty segments but any static file that does not involve JS processsing. Vite's current code does not handle blank sourcemaps at all. Problem is, when I tried to look at prior art:

  • Vite's Vue starter template does not generate any sourcemaps when dynamic parts are ripped out (e.g. file with no <script> tags) and just serves the unmapped generated JavaScript component. This is why it's not hitting the issue.
  • React is, well, React, and since it's always in some sort of JavaScript-related file it always avoids the problem.
  • Sapper does not generate any sourcemaps nor does it show the generated JavaScript component when dynamic parts are ripped out (no <script> tags, no {#each} block, etc).
  • Vanilla Svelte with or without TypeScript behaves the same as Sapper.

Sourcemaps are always properly generated with .svelte files that do some JS process:

<!-- this works -->
Hello {'world'}

<!-- this works -->
Hello world
{''}

<!-- this works -->
<script>
  let blah = true;
</script>
Hello world

<!-- this works -->
{#each [1, 2, 3] as num}
  {num}
{/each}

<!-- this doesn't, cause it's just HTML -->
<h1>Hello world</h1>

GrygrFlzr added a commit to GrygrFlzr/vite that referenced this issue Mar 9, 2021
GrygrFlzr added a commit to GrygrFlzr/vite that referenced this issue Mar 9, 2021
GrygrFlzr added a commit to GrygrFlzr/vite that referenced this issue Mar 9, 2021
@rmunn
Copy link

rmunn commented Mar 12, 2021

Until #2441 is merged into Vite, anyone running into this can apply the following workaround. WARNING: This is massively hacky and not a good long-term solution. This is intended mostly for people trying out Svelte-Kit via npm init svelte@next who don't want to wait for #2441 to be merged.

WARNING WARNING WARNING: If you use pnpm, applying the patch below will change not just the copy of Vite in your project's node_modules directory, but (since pnpm uses hardlinks to de-duplicate packages) it will also modify the copy of Vite in your $HOME/.pnpm-store/ directory. This means that every project on your hard disk that uses the same version of Vite (2.0.5, in my case) will also have this patch applied to it. That may be a good thing from your perspective if you're trying to run multiple small test projects trying out svelte@next, but you should be aware of this fact.

If you use pnpm and want to REMOVE this hacky workaround, all you need to do is run pnpm install vite again from an empty folder, and pnpm will notice that the Vite package no longer matches its checkums and will overwrite the mutated copy with a fresh copy that does not have this hacky patch applied. Or from your existing project folder, you can do rm -rf node_modules/.pnpm/vite@2.0.5 (substituting a different version number if required) and then run pnpm install, which will re-download and reinstall Vite.

Okay, if you haven't been scared off by the warnings above, here's the hacky workaround. After running pnpm install (or npm install or yarn install), save the patch below to fix-source-map-merging.patch in the root of your project and then run patch -p1 -i fix-source-map-merging.patch. Now run pnpm run dev and your Svelte-Kit project should compile.

--- a/node_modules/vite/dist/node/chunks/dep-e0f09032.js	2021-03-03 02:27:15.000000000 +0700
+++ b/node_modules/vite/dist/node/chunks/dep-e0f09032.js	2021-03-03 02:27:15.000000000 +0700
@@ -25190,7 +25190,12 @@
 
     var sourceRoot = this.sourceRoot;
     mappings.map(function (mapping) {
-      var source = mapping.source === null ? null : this._sources.at(mapping.source);
+      var source;
+      try {
+        source = mapping.source === null ? null : this._sources.at(mapping.source);
+      } catch (e) {
+        source = null;
+      }
       source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
       return {
         source: source,

NOTE: This works on Vite 2.0.5, but future Vite releases will probably use a different filename. If a new Vite release comes out before #2441 gets merged in, you'll have to tweak this patch by hand. The file you need to patch is the largest file in the node_modules/vite/dist/node/chunks/ directory. If the line numbers change too much and patch can't find the file, search the file for the text mapping.source === null and that should be the line you need to patch. I repeat: this is a massively hacky workaround, and you should not need this once a new Vite release comes out that includes #2441.

@github-actions github-actions bot locked and limited conversation to collaborators Jul 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants