question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Generate distinct paths for supporting .vue files in sourcemaps

See original GitHub issue

What problem does this feature solve?

Hello Vue šŸ‘‹

I’m working on our new JavaScript debugger for VS Code, and ran into some problems when trying out Vue. The default vue-cli setup creates several supporting .vue scripts. For instance, open the Chrome devtools and ctrl p for ā€œApp.vueā€ in a new project. The top entry is the correct Vue file, the others aren’t.

From the VS Code perspective, the user might ask us to set a breakpoint in a Vue file. We know which file the breakpoint is attached to on disk, and we need to figure out which loaded file that breakpoint gets mapped to. However, because all these paths are quite similar and all (in the context of a generic web app) possibly the file we want, we end up putting the breakpoint in the wrong file and breaking in the incorrect place. And often the supporting scripts evaluate before the ā€˜real’ script does, so we can’t, for example, wait and pick the best match from the possible candidates.

What does the proposed API look like?

The simplest solution would be to prefix the supporting files with some path like __vue__, or something along those lines. This would prevent the paths from incorrectly mapping to files that exist on disk.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:17
  • Comments:20 (3 by maintainers)

github_iconTop GitHub Comments

7reactions
andrewmackrodtcommented, Mar 2, 2021

From the VS Code perspective, the user might ask us to set a breakpoint in a Vue file. We know which file the breakpoint is attached to on disk, and we need to figure out which loaded file that breakpoint gets mapped to. However, because all these paths are quite similar and all (in the context of a generic web app) possibly the file we want, we end up putting the breakpoint in the wrong file and breaking in the incorrect place. And often the supporting scripts evaluate before the ā€˜real’ script does, so we can’t, for example, wait and pick the best match from the possible candidates.

I’ve found a workaround which is to provide a custom function to webpack’s output.devtoolModuleFilenameTemplate property which names component files according to which loaders are in use, i.e. if it is a vue file, the query is type=script and there are no additional loaders (e.g. ts-loader), then simply name the file Component.vue and breakpoints set in vscode work.

The following is only tested with vue-loader@16 in a typescript without babel project:

output: {
  devtoolModuleFilenameTemplate: info => {
    if (info.allLoaders === '') {
      // when allLoaders is an empty string the file is the original source
      // file and will be prefixed with src:// to provide separation from
      // modules transpiled via webpack
      const filenameParts = ['src://']
      if (info.namespace) {
        filenameParts.push(info.namespace + '/')
      }
      filenameParts.push(info.resourcePath.replace(/^\.\//, ''))
      return filenameParts.join('')
    } else {
      // otherwise we have a webpack module
      const filenameParts = ['webpack://']
      if (info.namespace) {
        filenameParts.push(info.namespace + '/')
      }
      filenameParts.push(info.resourcePath.replace(/^\.\//, ''))
      const isVueScript = info.resourcePath.match(/\.vue$/) &&
        info.query.match(/\btype=script\b/) &&
        !info.allLoaders.match(/\bts-loader\b/)
      if (!isVueScript) {
        filenameParts.push('?' + info.hash)
      }
      return filenameParts.join('')
    }
  },
}

This assumes that a .vue file will only ever have one <script></script> element.

Additionally, for vue-loader@16 (vue 3 users), an extra step is required so that source maps have the correct line numbering (due to the way newline handling prior to <script></script> is handled. @vue/compiler-sfc requires pad: true but this isn’t exposed anywhere by vue-loader so the function must be overridden until that functionality is added, i.e.

const CompilerSfc = require('@vue/compiler-sfc')
const parse = CompilerSfc.parse
CompilerSfc.parse = (source, options) => {
  return parse(source, Object.assign({ pad: true }, options))
}

I explain the reasoning behind the latter in a bit more detail in https://github.com/vuejs/vue-cli/issues/2897#issuecomment-788952677.

With those 2 changes, I’m able to set breakpoints in vscode and have execution pause at the correct place, including in async functions and timer callbacks, e.g. setTimeout and setInterval.

I’ve created a minimal ts + vue 3 project to test with: https://github.com/andrewmackrodt/vue3-ide-breakpoint-test

1reaction
connor4312commented, Dec 29, 2021

@znck let me know what you think a good solution is. We’ve gotten continued reports of people running into this with VS Code and I remain more than happy to help get this fixed šŸ™‚

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sourcemaps in .vue files are broken in development - GitLab
This makes it virtually impossible to map paths to source directories, and can cause conflicts if two .vue templates use the same filename....
Read more >
Configuration Reference | Vue CLI
The directory where the production build files will be generated in when running vue-cli-service build . Note the target directory contents willĀ ...
Read more >
DevTools: referencing a Vue file from multiple sourcemaps
When compiling vue single file components with webpack / vue-loader that contain plain CSS/JS/HTML, i end up with two sourcemaps:Ā ...
Read more >
Troubleshooting Source Maps for Vue - Sentry Documentation
join(".", "app.min.js.map"); // Line and column located in your generated file (for example, the sourceĀ ...
Read more >
Vue + TypeScript & Debuggers - ckh|Consulting
If you don't already have one, create a file named vue.config.js in the ... A list of paths to all files that contributed...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found