Having trouble debugging a Typescript Vue app in VS Code?

When setting up my new Vue app, I followed these steps:

? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x (Preview)
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with dart-sass)
? Pick a linter / formatter config: Prettier
? Pick additional lint features: Lint on save, Lint and fix on commit
? Pick a unit testing solution: Jest
? Pick an E2E testing solution: WebdriverIO
? Pick browsers to run end-to-end test on Chrome
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No

After that, I added a launch.json to my VS Code setup following these configurations:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "vuejs: chrome",
      "url": "http://localhost:8080",
      "webRoot": "${workspaceFolder}/src",
      "breakOnLoad": true,
      "sourceMapPathOverrides": {
        "webpack:///src/*": "${webRoot}/*"
      }
    }
  ]
}

Furthermore, I created a vue.config.js file in the root of my project with the following content:

module.exports = {
  configureWebpack: {
    devtool: 'source-map'
  }
}

To troubleshoot an issue, I added a breakpoint in main.ts at the following code snippet:

createApp(App)
  .use(store)
  .use(router)
  .mount("#app");

Upon running npm run serve from the command line and hitting F5 in VS Code, I encountered no breakpoint. How can I go about troubleshooting this? Could it be that Typescript is incompatible with Vue in this scenario, even though I've successfully used JS in previous projects?

Answer №1

It's disappointing that none of the solutions provided worked for me. Could it be because I was working with Single File Components (SFC) while others were not?

After delving deep into this issue for hours, I believe I have pinpointed the root cause:

During the compilation of your SFCs in Vue, they get divided into separate parts (<template>, <script>, and <style>) which are then processed by relevant loaders.

In the case of SFCs using TypeScript, the <script> section is compiled using the TypeScript Compiler (TSC). The challenge arises from TSC not recognizing the origin of the code it compiles, as it only receives the <script> content post-segregation by the Vue compiler.

As a result, TSC generates flawed Source Maps with incorrect line numbers (without adjustment for the <template> section), faulty source file references (due to hash-added filenames by Vue compiler), and incomplete source file content (containing <script> but lacking <template> and <style> code).

I can't delve into the fix here due to length constraints, but I recommend checking out my blog post on the topic.

To sum up, I managed to resolve the issue by utilizing the Webpack build process to rectify the faulty Source Maps.

Answer №2

For an effective approach, utilize the code snippet below to adjust your sourceMapPathOverrides

"sourceMapPathOverrides": {
        "webpack:///src/*.jsx": "${webRoot}/*.jsx",
        "webpack:///./src/*.js": "${webRoot}/*.js",
     }

Answer №3

To find a solution to your issue, you can refer to this recipe - https://github.com/microsoft/vscode-recipes/tree/master/vuejs-cli

When configuring your launch.json file, make sure it resembles the following example (you can exclude the preLaunchTask if not defined in tasks.json):

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "vuejs: chrome",
      "url": "http://localhost:8080",
      "webRoot": "${workspaceFolder}",
      "breakOnLoad": true,
      "pathMapping": {
        "/_karma_webpack_": "${workspaceFolder}"
      },
      "sourceMapPathOverrides": {
        "webpack:/*": "${webRoot}/*",
        "/./*": "${webRoot}/*",
        "/src/*": "${webRoot}/*",
        "/*": "*",
        "/./~/*": "${webRoot}/node_modules/*"
      },
      "preLaunchTask": "vuejs: start"
    }
  ]
}

Answer №4

After experimenting with various methods, I finally found one that actually solved the issue. source

All I had to do was add this snippet to my vue.config.js and suddenly my debugging feature started working.


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

module.exports = {
    configureWebpack: {
        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('')
                }
            },
        },
    },
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways of modifying the readonly and required attributes of an HTML element using Angular2 Typescript

I am facing an issue with changing input field attributes back and forth in some of my components. I have a code that successfully changes the readonly attribute as needed. However, when trying to change the required attribute, Angular2 still considers the ...

Troubleshooting VueJS, Electron, and Webpack integration with Hot Reload feature

I have been immersed in a new project that involves utilizing Electron, VueJS, and Webpack for HMR functionality. Unfortunately, I am encountering difficulties with the Hot Module Replacement feature not working as expected. Here is my current configurati ...

Troubleshooting Angular 14 Custom Form Control Display Issue

I'm facing an issue while attempting to develop a custom form control in Angular 14. Despite no errors showing up in the console, my custom control is not rendering as expected. When inspecting the Elements tab in the console, I can see the parent com ...

Vue component unexpectedly refreshed without cause

I noticed that my component is being re-rendered for no apparent reason whenever the parent's data item is changed, even though it has nothing to do with the component itself. For a simple demonstration, you can check out this example here. (Clicking ...

Setting options using the form group in dropdowns in Angular can greatly enhance the user experience

I have created a FormGroup called holidayform and set it up as follows: holidayform: FormGroup; this.holidayform = this.fb.group({ title: ['', [Validators.required]], entryDate: ['',], }) this.holidayform.patchValue ...

Exploring LocalStorage Monitoring in Vue.js 2

How can I stay informed about any changes in Banana.vue? I have tried using addEventListener, @watch but it doesn't seem to be working... The index.vue file is importing both Apple.vue and Banana.vue In Apple.vue: localStorage.setItem('fruit ...

What is the best way to implement useAsync (from the react-async-hook library) using TypeScript?

Currently, I am utilizing react-async-hook to retrieve API data within a React component. const popularProducts = useAsync(fetchPopularProducts, []); The fetchPopularProducts() function is an asynchronous method used to make API calls using fetch: export ...

Displaying the final element in an array using v-if nested within a v-for loop

I'm relatively new to using Vue and I'm struggling with nesting a v-if inside a v-for. The issue I am facing is that while everything is rendering correctly, the value of {{row.id}} (inside the v-if) is displaying the last element in my array ins ...

Make an http.patch request to the server using a Nativescript application

I am attempting to make an http.patch request to the server in my Nativescript application, which is built with Typescript and Angular2. The backend system is developed using Python(Django). Here is the code for my request: updateOrder(id, message) { ...

Using the Vue.js Compositions API to handle multiple API requests with a promise when the component is mounted

I have a task that requires me to make requests to 4 different places in the onmounted function using the composition api. I want to send these requests simultaneously with promises for better performance. Can anyone guide me on how to achieve this effic ...

Utilizing ES6 JavaScript for Creating Static Methods and Angular 2 Services

During the development of an Angular 2 app involving multiple calculation services, I encountered some interesting questions: Is it beneficial to use static in an Angular service provided on the application level? Or is it unnecessary? How does a static ...

From integrating Vue 2 TSX to React TSX: ensuring seamless cooperation

Currently, my app is built with Vue 2 using vue-tsx-support, vue-class-component, and vue-property-decorator. All of my Vue 2 components are already TSX classes. I am interested in gradually transitioning to React. I experimented with https://github.com/ ...

Navigate to a specific position with a single click by accessing a class from another Vue component

Clarification of the issue When a user clicks on the login link, the view should automatically scroll down to the login window where they can input their credentials. I know how to achieve this in a single file using document.getElementById('login-w ...

An error was encountered in compiler.js at line 1021, stating that an unexpected value 'UserService' was imported by the module 'UserModule'. It is recommended to add a @NgModule annotation to resolve this issue

As a PHP programmer new to Angular, I am facing an issue while trying to retrieve user properties from a Laravel API. When attempting this, I encountered the following error: compiler.js:1021 Uncaught Error: Unexpected value 'UserService' importe ...

Having trouble triggering a method on button click using Vuetify's v-btn component

I am facing an issue with executing a method when clicking on a v-btn. Here is my template <template> <v-app> <v-main> <v-card class="mx-auto" max-width="500" tile> <v-text-field ...

Excessive recursion detected in the HttpInterceptor module

My application uses JWT tokens for authentication, with a random secure string inside the JWT and in the database to validate the token. When a user logs out, a new random string is generated and stored in the database, rendering the JWT invalid if the str ...

Limiting the use of TypeScript ambient declarations to designated files such as those with the extension *.spec.ts

In my Jest setupTests file, I define several global identifiers such as "global.sinon = sinon". However, when typing these in ambient declarations, they apply to all files, not just the *.spec.ts files where the setupTests file is included. In the past, ...

The attempt to run 'createElement' on the 'Document' has resulted in failure. The tag name inputted ('{{laravue.currentview }}') is not recognized as a valid name

I recently started using the Laravue library from https://github.com/laravue/laravue. However, when I tried to run it on my local machine, I encountered the following error: Uncaught DOMException: Failed to execute 'createElement' on 'D ...

Is it feasible to utilize tutorials designed for vue-cli with CLI 3 instead?

Recently, I began my journey into learning Vue.js. The tutorial I am following recommends using npm install -g vue-cli, but unfortunately, I encountered some technical difficulties and despite trying various solutions, I was unable to resolve them. As ...

Vue - Struggling to invoke sweetalert2 within a method

I'm encountering an issue with launching sweetalert within a Vue method. When I directly call the sweetalert in the script, it works fine. However, when I try to launch the sweetalert upon clicking a button, nothing happens (no errors in the console). ...