持续创作,加速成长!这是我参与「掘金日新计划 · 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很像,所以调试起来也不麻烦:
让我们的页面变得更有趣:从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你会发现生成的代码更复杂了:
为了在更老的版本浏览器上支持await和async,ts必须将event handler改写成状态机。所以导致原始代码和生成代码差异巨大。
这时候可以将tsconfig.json的sourceMap进行这样设置:
{
"compilerOptions": {
"sourceMap": true
}
}
当你运行tsc,每个ts文件生成两个文件:.js文件,.js.map文件。第二个文件是source map文件。这个时候浏览器的debugger会出现index.ts文件:
注意出现在左侧文件列表页的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,那么将会有你不像公开的信息出现在网上。