debugger on VSCode not working with Javascript - javascript

UPDATE: This is a question about how to configure VSCode to debug Javascript. I understand it uses Node.js, which I don't know about, javascript always works in the browser, but I would like to be able to step through the code rather than write hundreds of console.log() statements just to see what it is doing.
Trying to set up debugging for Javascript in VScode, but it's not picking it up, it keeps opening the launch.json file, but I've no idea what I need to put in there to make this work. I'm new to Javascript and just run things in a browser, I am assuming Node.js is kind of standalone JavaScript engine, so I did install it.
I have Node v4.2.6 installed on linux mint computer
and:
which node
resulted in:
/usr/bin/node
I'm confused, is this the correct path for node, and how do I add it to this config, I can't work out what the key/value pair is supposed to be. here is the launch.json file is spits out:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/app.js"
},
}
Any help on this would be much appreciated.

If I understand you correctly, you want to debug JavaScript running in the browser with VSCode. Right?
If that's the case, debugging your JavaScript running in node would not be of much value, because node may be missing the APIs your code relies upon (e.g. the DOM). Instead, you'll want to let your JavaScript run in the browser and just debug it with VSCode.
There are extensions for the different browsers that allow that, they mostly utilize the DevTools Protocol: vscode-firefox-debug, vscode-chrome-debug, vscode-edge-debug2.
Merely quoting from vscode-firefox-debug project page:
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch index.html",
"type": "firefox",
"request": "launch",
"reAttach": true,
"file": "${workspaceFolder}/index.html"
}
]
}
This will open ${workspaceFolder}/index.html in a new FireFox tab and you'll be able to debug that using VSCode. It'll get nasty with bundlers, source maps and all that jazz, but this is the gist you should get: run JavaScript in the browser, connect VSCode to the DevTools using an extension.

Related

How to setup pathMapping in VSCode to debug a Snowpack application

I'm evaluating Snowpack for building my JavaScript project. However, VSCode and the Debugger for Chrome extension cannot match the scripts on the dev server to the local source files. Because of this, breakpoints don't work. I'm not using any source maps because I'm not bundling/transforming anything, just using vanilla ES modules.
I'm using the following template: https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/app-template-lit-element
A simplified directory layout of the project is:
public/
index.html
src/
index.js
Now when I start the Snowpack dev server it serves the files using the following layout, which is quite different:
index.html
dist/
index.js
I tried the following launch configuration in VSCode, but it does not work, i.e., it cannot match the javascript files:
{
"name": "Launch localhost",
"type": "chrome",
"request": "launch",
"url": "http://localhost:8080/",
"webRoot": "${workspaceFolder}/public",
"pathMapping": {
"/dist": "${workspaceFolder}/src"
}
}
The pathMapping property has very scant documentation, and I'm wondering whether it's working at all.
Any ideas?
Update:
The lit-element example seems to use babel for transpiling, but even with transpiling disabled the problem persists. This is more a VSCode problem, not a Snowpack problem.
To create an output you would like to have please configure mount option for snowpack config, experiment with this config to get the result you need.
mount: {
public: '/',
src: '/src',
},

vscode node debugger with custom webpack build

I have a JS web app that has a client and server bundle, both built using webpack's node api.
Running my project in dev mode goes through these steps:
Run two webpack builds, resulting in two output files.
Server bundle is output to dist/server/index.js
Spawn child node process using the dist/server/index.js path
Watch folder for changes. On change, kill the old child process and re-run steps 1-3
I want to add node server debugging using vscode.
So far, I've added the following flags during step 3, when I launch a new child process.
['--inspect=9222', '--no-lazy', '--inspect-brk']
My launch.json file in vscode looks like this
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to dev server",
"type": "node",
"request": "attach",
"protocol": "inspector",
"address": "localhost",
"port": 9222,
"restart": true,
"trace": true,
"stopOnEntry": true
}
]
}
When I start the server and run the debugger, things mostly work.
However, I'd love to fix the following two things:
Even with "stopOnEntry": true, the debugger will not pick up any breakpoints, unless I include "--inspect-brk" when launching my child process. This is annoying, because if I'm not running the debugger, the process will hang and will not continue execution. With this flag included, when I run the debugger, the built dist/server/index.js file will open in my editor with a breakpoint on line 1. If I hit continue, all future debugging works.
I'm generating sourcemaps using webpack's "inline-source-map" option. This puts the "original source" in the built file. However, it's the source after babel transformation, making debugging the code a little annoying. E.g. _myFunction.default instead of myFunction. Does vscode have a way to correctly map the built .js file to the pre-built source code in my project? I saw the remoteRoot and localRoot options, but could not get them to work (and am unsure if these are the correct options).
Thanks!
Update VS Code 1.47+:
With the new JavaScript debugger in VS Code 1.47 and later versions, child processes are automatically debugged in Node.js - just set breakpoints where needed.
Example launch.json (with TypeScript source to illustrate the sourcemap approach):
{
"type": "pwa-node",
"request": "launch",
"name": "Launch Program",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/main.ts", // use .ts source
"outFiles": ["${workspaceFolder}/dist/**/*.js"], // search here for sourcemaps
}
Example main.ts:
const { spawn } = require("child_process");
const args = [path.resolve("./child.js")];
const proc = spawn(process.execPath, args, { stdio: "inherit" });
See this post for an explanation of pwa-node.
VS Code debug options
program: specifies main source file to be debugged. You can directly reference the .ts source file - VS Code will search the workspace for sourcemaps or consult outFiles.
outFiles: tell VS Code to explicitely search for sourcemaps in these glob locations.
sourceMaps: if VS code shall look for sourcemaps; defaults to true, so no need to set.
stopOnEntry: breaks immediately when program launches - same, as a breakpoint on first line. 1
nolazy: ensures that breakpoints are validated before the code is run and don't "jump". Per default, VS Code sets this flag automatically, so it can be left out.
remoteRoot / localRoot: are for remote debugging and are not directly related to generating sourcemaps (see OP question).
autoAttachChildProcesses: was used to automatically attach to child processed launched in debug mode; no need to set it with new debugger.
Node debug options
--inspect: starts the program in debug mode without waiting for the debugger to be attached.
--inspect-brk: same as --inspect, but waits for the debugger to attach before starting.
You can set one of these to enable debug mode for a program started on the command-line. Note: VS Code now can also auto-attach from integrated terminal without these flags given.
Generate sourcemaps with Webpack
For webpack, you can generate sourcemaps with inline-source-map or source-map 2.
// inside webpack.config.js
devtool: "inline-source-map",
If babel-loader is used, sourcemaps should be considered and merged automatically by webpack with above config entry. For TypeScript, see the Webpack docs.
(Old) Debug child legacy solution
If that does not work in older versions, pass a conditional DEBUG environmental variable for --inspect/--inspect-brk together with autoAttachChildProcesses:
const runner = spawn(process.execPath,
[...(process.env.DEBUG === "true" ? ["--inspect-brk"] : []), ...args],
);
// inside launch.json configuration
"env": {
"DEBUG": "true"
},
1 Despite this developer comment, stopOnEnty has not been propagated to child processes for me - even with autoAttachChildProcesses and child processed started with --inspect.
2 These options provide best compatibility from my experience.

How to use ES6 modules from dev tools console

As far as I understand it, if I create an ES6 module, I can only import it from code that is itself a module. This means non-module code, i.e. inline Javascript, or the Chrome dev tools console can never access code that is in a module.
Is that true? Is there any way around this because it seems like a fairly extreme limitation.
You can use dynamic import within Chrome's console.
import('path/to/module.js').then(m => module = m)
// [doSomething] is an exported function from [module.js].
module.doSomething()
You can register the function or variable in the global namespace with a line like window.myFunction = myFunction or window.myVariable = myVariable. You can do this in the module where myFunction or myVariable are declared or do it in a separate module where they have been imported.
Once you've done this, you will be able to use myFunction and myVariable from the Chrome DevTools console.
For example:
import myModule from '/path/to/module.js';
window.myModule = myModule;
// in the console:
myModule.foo();
(Credit to #Evert for providing this solution in a comment, albeit in a rather roundabout way that took me a while to figure out.)
You can await a dynamic import within Chrome's console:
const Module = await import('./path/to/module.js')
Module.doSomething()
That dynamic import is roughly equivalent to:
import * as Module from './path/to/module.js';
Module.doSomething()
There is a way to use the Chrome Dev Tools with ES6 modules, if you use VSCode and the Javascript Debugger for Chrome. I had some trouble to get it to work, but it was worth it.
https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome
The VSCode debugger launches a new chrome window which is connected to the VSCode debugger. You can also use Chrome Dev Tools (F12) in this window as usual. It works with ES6 modules and you can set breakpoints, use the console, inspect variables, etc...
In case you have trouble to set up the debugger, this is how it worked for me:
Go to the VSCode Debug Window (CTRL+SHIFT+D) -> select Add Configuration from dropdown -> Select Chrome Launch or Chrome Launch Legacy to change "launch.json"
my launch.json:
{
"name": "Launch Chrome Legacy",
"type": "chrome",
"request": "launch",
"url": "http://localhost:5000/auth/login",
"webRoot": "${workspaceFolder}",
"sourceMaps": true
},
{
"name": "Launch Chrome",
"request": "launch",
"type": "pwa-chrome",
"url": "http://localhost:5000/auth/login",
"webRoot": "${workspaceFolder}",
"sourceMaps": true
},
The key was to use "sourceMaps": true and "url": "http://localhost:5000/auth/login" instead of http://localhost:5000/blog", which is the page I actually want to debug. However, when the Debugger opens the new chrome window, my page was redirected to /auth/login, so I had to use this url.
You can try to disable the Preview Version of the new debugger and use the Legacy version instead:
Turn off Debug › JavaScript: Use Preview in the VSCode settings.
Then Run Launch Chrome Legacy from the Debug Window in VSCode
To set breakpoints in VSCode, open the javascript module from Loaded Scripts
You can call functions contained in Javascript modules from the Chrome developer console using import, as in #Kin's answer.
If you get error "TypeError: Failed to resolve module specifier", try using the full URL for the module file. For example, on Windows 10 with IIS running locally, and Chrome 87, this works for me:
// Call doSomething(), an exported function in module file mymodule.js
import('http://localhost/mysite/myfolder/mymodule.js').then((m) => { m.doSomething(); });
You can only import a module from other modules, because import is a modules feature.
How did you 'import' before ES6 modules? You didn't, because it didn't exist. You can actually interact with an E6 Module the same was as you used interact between two independent non-module scripts.
Hold and drag the module file into the chrome dev console.
Be sure to drag it to the input line section (after >) of the console.
(This works on my Chrome 78 under Windows 10.)
Carl's answer was quite helpful for me getting modules working in the console. However, since there are good reasons to not use window.* in your modules in production code, what I've started doing is:
Put a breakpoint inside the module you want to import.
When that breakpoint is hit, execute window.myModule = myModule; in the console.
Remove the breakpoint and resume. Now you can reference that module in the console whenever you want.

How to make Visual Studio Code check entire project for errors?

I'm using VS Code for TypeScript/JavaScript development. When I open a file it will check that file for errors. The problem is if I'm refactoring (like I move some shared code to a new location or change a name) it won't show me the errors this caused until I open the file with the problem. ...so if I want to do extensive refactoring I have to open every file just to make it scan the file for errors.
How can I make VS Code scan the whole project for errors without having to open each file one by one manually?
VS Code (v1.44) has an experimental feature, that allows project wide error reporting in TS. Try it out:
// put this line in settings.json
"typescript.tsserver.experimental.enableProjectDiagnostics": true
Figured it out. Note this answer is specific to TypeScript, which is what I am using. Here it is:
Make sure typescript is installed globally (I just had mine installed locally apparently):
npm install -g typescript
Then in VS Code press Shift+Ctrl+B. If you don't have a task runner set up it will ask what you want. I selected typescript and the tasks.json file will look like this:
{
"version": "0.1.0",
"command": "tsc",
"isShellCommand": true,
"args": ["-p", "."],
"showOutput": "silent",
"problemMatcher": "$tsc"
}
Then pressing Shift+Ctrl+B (or Shift+Command+B in macOS) will check the entire project for problems and they will be reported in your "problems" panel.
If you don't want to install TypeScript globally, you can do the following:
Install TypeScript locally on the project, that is yarn add --dev typescript or npm install --save-dev typescript.
Add a check-types run script to ./package.json. --noEmit means that the compiler will won't generate any JavaScript files.
{
"scripts": {
"check-types": "tsc --noEmit"
}
}
Let VSCode know about the run script in /.vscode/tasks.json.
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "check-types",
"problemMatcher": [
"$tsc"
]
}
]
}
To run the tasks hit the F1 key and select 'Run Task', and then 'npm: check-types'.
If you add the following lines to the task, pressing Ctrl+B will run it.
"group": {
"kind": "build",
"isDefault": true
}
For the most recent version of tasks.json this is the correct json, following deprecations in version 1.14. Create this as /.vscode/tasks.json
{
"version": "2.0.0",
"command": "tsc",
"type": "shell",
"args": [
"-p",
"."
],
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$tsc"
}
Once you have open your project in vs code, open the vs code terminal and run:
node_modules/.bin/tsc --noEmit
Go to View menu > Extensions and make sure the Microsoft VS Code ESLint extension is installed.
In Settings, search for "ESLint > Lint Task: Enable", and enable that setting (docs).
In the Terminal menu, choose Run Task… > eslint: lint whole folder.
UPDATE.
My answer below does not answer the original question, but if you're like me and have found this thread searching for how to turn on // #ts-check project-wide in VSCode so that you don't need to add // #ts-check to every file then my answer below is what you need. I have searched and searched and kept getting this thread as my top result so hopefully this helps others as well
I'm on vscode version 1.52.1 and the answer is so simple and right on the vscode website:
https://code.visualstudio.com/docs/nodejs/working-with-javascript#_type-checking-javascript
scroll down to the "Using jsconfig or tsconfig" section
Add a jsconfig.json in your project root and add "checkJs": true
{
"compilerOptions": {
"checkJs": true
},
"exclude": ["node_modules", "**/node_modules/*"]
}
You might need to restart vscode once you add it in
None of the other solutions worked fully for me. Here's a tasks.json that does, working with vscode 1.67+. On Linux etc. set command to tsc, on Windows be sure to run tsc.cmd as tsc alone will attempt to run the bash script and produce the following error:
The terminal process failed to launch: A native exception occurred during launch (Cannot create process, error code: 193)
"revealProblems": "always" in the presentation section shows the Problems panel on completion.
{
"version": "2.0.0",
"tasks": [
{
"label": "tsc: error check project",
"command": "tsc.cmd",
"args": [
"-p",
".",
"--noEmit"
],
"isBackground": false,
"problemMatcher": "$tsc",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"revealProblems": "always",
}
}
]
}
Edit: Since updating to 1.52.0 this no longer works. It will instead replace the current project files with what you selected...
===
I've tried every solution I can find and I think it's safe to say the answer is: You can't*
The best I've found is still technically opening each file manually, but at least it's not one-by-one:
You can't drag/drop a directory but you can select multiple files (including directories) and drag/drop. The directories will be ignored and any files you had selected will be opened in tabs.
Next, you need to give each tab focus so it triggers eslint to run. (Holding down the next tab keyboard shortcut works.)
This is terrible and I beg someone to prove me wrong.
*I haven't found a way that works as well as opening files manually. Each method -- experimental vscode feature and tsc task -- has its own set of drawbacks. The vscode feature is clearly the solution but without a way to ignore node_modules, etc. it's too painful to use.

Node debugging with WebPack and Feathers

I joined a group building a product with Node, Webpack, TypeScript and Express/Feathers. Other developers know what they are doing, but I have only used JavaScript on a client until now and have literally only a few hours of Node under my belt. Trying to figure out how to go about debugging. Specifically, my first task is to fix some failing API tests.
Tests are executed with:
$npm run testserver
My package has:
"scripts": {
....
"testserver": "webpack --config webpack.servertest.config.js && NODE_ENV=test mocha dist/serverTests.js",
....
},
The routine is to compile typescript into ES6 then babel to ES5 compatible with Node.
I tried doing:
$node-debug dist/serverTests.js
When this node-debug invocation runs, the results are not the same as with npm. Please share your experience.
Thank you
Based on your setup, I can recommend you to try Visual Studio Code, OS text editor/ide based on Electron as well as Atom editor.
To solve your issue you can use two vscode features:
Debugging - link on docs how to debug in vscode
Tasks - task management, for instance to look into webpack config which is started with some args and etc
Firstly, let's try simple solution that may be appropriate in your case (tasks file doesn't need):
Add to the end of testserver --debug-brk it's used for debug in node.js, brk - it simply stops execution on the first line.
"testserver": "webpack --config webpack.servertest.config.js && NODE_ENV=test mocha dist/serverTests.js --debug-brk",
Now when you npm run testserver, mocha starts in debug mode and in console you will see something like Debugger listen on port 5858
Second step, in vscode you need to add some props (port 5858) to launch.json - read section Debugging in docs that I mention above:
{
"version": "0.1.0",
"configurations": [
{
"name": "Attach", // or e.g. "Mocha Debug"
"type": "node",
"request": "attach",
"port": 5858
}
]
}
And that's it. Go in debug mode in vscode, put breakpoint in a test file, choose in dropdown 'Attach' or 'Mocha Debug' and start debugging(F5)
p.s. Also VS code has first-class TypeScript support that may be helpful for you.

Categories