[译]<<Effective TypeScript>> 技巧57:用 source map 对ts进行debug

877 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

本文的翻译于<<Effective TypeScript>>, 特别感谢!! ps: 本文会用简洁, 易懂的语言描述原书的所有要点. 如果能看懂这文章,将节省许多阅读时间. 如果看不懂,务必给我留言, 我回去修改.

技巧57:用 source map 对ts进行debug

运行ts代码实际上是运行ts编译生成的js代码。大多数的时候只要关注ts代码,而不用关注js代码。但是当你需要debug的时候情况不一样了,因为debugger运行在js上。你不知道ts编译成js会发生什么变化,浏览器提供商解决了这个问题:source map 。它将生成的文件的bug位置和符号和原始文件一一对应。大多数浏览器和ide支持这个功能,如果你知道怎么用source map调试ts,你就落伍了!

假如你正在给HTML上添加一个按钮,每次点击增加计数:

function addCounter(el: HTMLElement) {
  let clickCount = 0;
  const button = document.createElement('button');
  button.textContent = 'Click me';
  button.addEventListener('click', () => {
    clickCount++;
    button.textContent = `Click me (${clickCount})`;
  });
  el.appendChild(button);
}

addCounter(document.body);

如果你打开debugger,你会发现其生成的js和原始ts很像,所以调试起来也不麻烦:

image.png

让我们的页面变得更有趣:从numbersapi.com获取每个数字。

function addCounter(el: HTMLElement) {
  let clickCount = 0;
  const triviaEl = document.createElement('p');
  const button = document.createElement('button');
  button.textContent = 'Click me';
  button.addEventListener('click', async () => {
    clickCount++;
    const response = await fetch(`http://numbersapi.com/${clickCount}`);
    const trivia = await response.text();
    triviaEl.textContent = trivia;
    button.textContent = `Click me (${clickCount})`;
  });
  el.appendChild(triviaEl);
  el.appendChild(button);
}

打开debugger你会发现生成的代码更复杂了:

image.png

为了在更老的版本浏览器上支持await和async,ts必须将event handler改写成状态机。所以导致原始代码和生成代码差异巨大。

这时候可以将tsconfig.json的sourceMap进行这样设置:

{
  "compilerOptions": {
    "sourceMap": true
  }
}

当你运行tsc,每个ts文件生成两个文件:.js文件,.js.map文件。第二个文件是source map文件。这个时候浏览器的debugger会出现index.ts文件:

image.png 注意出现在左侧文件列表页的index.ts是斜体。这表明这个文件不是真实存在的。而是通过你的source map包含进来的。

source map有几点是你需要记住的:

  • 如果你是用bundler或者minifier,那么他们将生成的自己的source map,而不是ts官方的source map。为了获得最好的debug体验,你最好生成官方原始的 source map
  • 需要意识到你是否在生产环境中使用 source map。除非打开debugger,浏览器不会自动加载source map。所以source map不会对运行性能有什么影响。如果真的在生成环境中使用了source map,那么将会有你不像公开的信息出现在网上。