带有自定义 webpack 构建的 vscode 节点调试器

Posted

技术标签:

【中文标题】带有自定义 webpack 构建的 vscode 节点调试器【英文标题】:vscode node debugger with custom webpack build 【发布时间】:2019-11-27 22:19:46 【问题描述】:

我有一个 JS web 应用程序,它有一个客户端和服务器包,两者都是使用 webpack 的节点 api 构建的。

在开发模式下运行我的项目需要经过以下步骤:

    运行两个 webpack 构建,生成两个输出文件。 服务器包输出到 dist/server/index.js 使用 dist/server/index.js 路径生成子节点进程 监视文件夹以进行更改。更改时,终止旧的子进程并重新运行步骤 1-3

我想使用 vscode 添加节点服务器调试。

到目前为止,当我启动一个新的子进程时,我在第 3 步中添加了以下标志。

['--inspect=9222', '--no-lazy', '--inspect-brk']

我在 vscode 中的 launch.json 文件是这样的


    "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
        
    ]

当我启动服务器并运行调试器时,一切正常。

不过,我想解决以下两个问题:

    即使使用"stopOnEntry": true,调试器也不会选择任何断点,除非我在启动子进程时包含"--inspect-brk"。这很烦人,因为如果我不运行调试器,进程将挂起并且不会继续执行。包含此标志后,当我运行调试器时,构建的 dist/server/index.js 文件将在我的编辑器中打开,并在第 1 行有一个断点。如果我点击继续,所有未来的调试工作。 我正在使用 webpack 的 "inline-source-map" 选项生成源地图。这会将“原始源”放入构建文件中。不过是babel改造后的源码,让调试代码有点烦。 E.g. _myFunction.default instead of myFunction。 vscode 是否有办法将构建的 .js 文件正确映射到我项目中的预构建源代码?我看到了 remoteRootlocalRoot 选项,但无法让它们工作(并且不确定这些选项是否正确)。

谢谢!

【问题讨论】:

【参考方案1】:

更新 VS Code 1.47+:

使用VS Code 1.47 和更高版本中的new javascript debugger,Node.js 中的子进程are automatically debugged - 只需在需要的地方设置断点。

示例launch.json(使用 TypeScript 源代码来说明 sourcemap 方法):

  "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 

示例main.ts
const  spawn  = require("child_process");
const args = [path.resolve("./child.js")];
const proc = spawn(process.execPath, args,  stdio: "inherit" );

有关pwa-node 的解释,请参阅this post。

VS 代码调试选项

program:指定要调试的主源文件。可以直接引用.ts源文件——VS Code会search the workspace for sourcemaps或者咨询outFiles

outFiles:告诉 VS Code 在这些全局位置中显式搜索源映射。

sourceMaps:如果 VS 代码要查找 sourcemap; defaults to true,所以不用设置。

stopOnEntry:程序启动时breaks immediately - 与第一行的断点相同。 1

nolazy:确保在代码运行前断点are validated不会“跳转”。默认情况下,VS Code sets this flag automatically,因此可以省略。

remoteRoot / localRoot:用于remote debugging,与生成源映射没有直接关系(请参阅 OP 问题)。

autoAttachChildProcesses:用于自动附加到在调试模式下启动的子进程;无需使用新的调试器进行设置。

节点调试选项

--inspect:启动程序in debug mode,无需等待调试器附加。--inspect-brk:与--inspect相同,但waits for the debugger 附上before starting。

您可以设置其中一项以启用在命令行上启动的程序的调试模式。注意:VS Code 现在也可以在不提供这些标志的情况下从 integrated terminal 到 auto-attach。

使用 Webpack 生成源地图

对于 webpack,你可以 generate sourcemaps 和 inline-source-mapsource-map 2

// inside webpack.config.js
devtool: "inline-source-map",

如果使用babel-loader,源映射应该被 webpack 自动考虑和合并上面的配置条目。对于 TypeScript,请参阅 Webpack docs。


(旧)调试子遗留解决方案

如果这在旧版本中不起作用,请将--inspect/--inspect-brk 的条件DEBUG 环境变量与autoAttachChildProcesses 一起传递:

const runner = spawn(process.execPath,
  [...(process.env.DEBUG === "true" ? ["--inspect-brk"] : []), ...args],
);
// inside launch.json configuration
"env": 
  "DEBUG": "true"
,

1 尽管有这个developer comment,stopOnEnty 对我来说没有被传播到子进程——即使是autoAttachChildProcesses 和子进程开始于--inspect.

2根据我的经验,这些选项提供了最佳的兼容性。

【讨论】:

感谢您的文章,肯定有帮助。就源映射正常工作而言,我认为它们被正确映射。我需要将“import from”更改为“require('')”才能以完全 ES5 格式查看内容。至于 autoAttachChildProcess,我无法让它工作。我可以让监听器启动,甚至可以看到 vscode 识别的子进程(如果我将 -inspect 节点标志添加到子进程),但断点总是显示为未验证(代码永远不会停止)。如果没有最初的“inspect-brk”,我也无法正常工作。 这是调试窗口在 vscode i.imgur.com/iWbWxMx.png 中的样子的图像 感谢您的跟进和示例回购!很高兴了解inspect-brk 和子进程。我认为在这种情况下,让 process.env 变量控制子进程运行的标志是最好的选择。

以上是关于带有自定义 webpack 构建的 vscode 节点调试器的主要内容,如果未能解决你的问题,请参考以下文章

带有 @nguniversal 的 Angular s-s-r 和用于 PostCSS 支持的自定义 webpack

如果我在 tsconfig 中使用自定义路径,Webpack 开发服务器找不到带有 Typescript 的模块

webpack:生产构建后缺少自定义样式

Storybook - 使用自定义 webpack / babel 的 typescript 项目中没有出现任何故事

找不到带有 Webpack、Typescript、自定义模块目录的模块

使用 webpack 构建在插件中注册多个自定义古腾堡块