nswbmw / node-in-debugging

《Node.js 调试指南》
6.43k stars 801 forks source link

如何调试 ES6 modules ? #9

Open mantou132 opened 6 years ago

mantou132 commented 6 years ago

下面是我的理解:

调试 ES6 modules,现在的方案是先编译成 es5,加上 sourcemap 进行调试。 如果要直接调试,可以使用 babel-node,但是在调试上下文中变量有问题。 使用 nodejs 原生 es6 modules 调试理论上没有问题。

NODE_OPTIONS='--experimental-modules --loader ./custom-loader.mjs' node —inspect-brk x.js
# custom-loader.js 支持加载 nodejs 内置模块,省略 js 后缀的 es6 模块 以及 mjs 后缀的 es6 模块

但是 Chrome 中调试有可能不能在 Filesystem 中看到文件,不方便打断点(需要添加 debugger 语句) 可以在 vscode 中调试:launch.json 中添加 runtimeArgs

mantou132 commented 6 years ago

这里改了官方文档中的 custom-loader.js:

import url from 'url';
import path from 'path';
import process from 'process';
import Module from 'module';

const builtins = Module.builtinModules;
const JS_EXTENSIONS = new Set(['.js', '.mjs']);

export function resolve(specifier, parentModuleURL = 'file://', defaultResolve) {
  console.log(specifier, parentModuleURL);
  if (builtins.includes(specifier)) {
    return {
      url: specifier,
      format: 'builtin'
    };
  }
  if (/^\.{0,2}[/]/.test(specifier) !== true && !specifier.startsWith('file:')) {
    // For node_modules support:
    return defaultResolve(specifier, parentModuleURL);
    // throw new Error(
    //   `imports must begin with '/', './', or '../'; '${specifier}' does not`);
  }
  const resolved = new url.URL(specifier, parentModuleURL);
  const ext = path.extname(resolved.pathname);
  let result = resolved.href;
  if (!JS_EXTENSIONS.has(ext)) {
    // throw new Error(
    //   `Cannot load file with non-JavaScript file extension ${ext}.`);
    result = resolved.href + '.js';
  }
  return {
    url: result,
    format: 'esm'
  };
}
nswbmw commented 6 years ago

在 Node.js 没有完全支持 ES6 modules 之前不会添加这个 case...