终于来到了重头戏Sources面板,前面的文章提到了许多提高Debug效率的小技巧,但如果遇到了更加复杂的情境,透过Console、Elements面板都无法解决,此时就是Sources面板的出场时机。
阅读本篇文章时建议搭配Demo页面Sources-SourceMapFileEditing,效果更佳。
概览
打开Sources面板后可以看到主要分成左中右三个面板,左侧面板主要和当前页面的资源相关,在面板中会看到已载入的资源如HTML、CSS、JS等等档案以资料夹的型式呈现,也可以修改、储存档案改变当前的页面的行为。
右侧面板为JavaScriptDebugger,上方是Debugger的操作按钮以及JavaScript执行环境的资讯,搭配中、右侧面板能够清楚观察JavaScript的执行状况,并以断点、逐步执行、监看状态等功能辅助Debug。
中间的面板主要负责显示档案内容,搭配左右两侧面板有不同的效果,在上方也能将两侧面板收合,可以依据自身对Sources面板的使用需求改变各个子面板的收合状态和宽度。
不过在开始讲解Sources面板的功能之前,得先介绍Sourcemap和Fileediting功能是什么玩意儿。
Sourcemap
现今前端开发总跟框架脱离不了关系,也让许多网页上执行的JavaScript都会预先经过处理,与开发时所看到的原始码有所不同,常见的处理工具包括:
Compiler
如TypeScript,将一种程式语言转换为另一种,也可能会有效能上的优化。
Transpiler
如Babel,将原始码转换为浏览器中可以直接使用的JavaScript,基本上不改变程式码的逻辑,不过随着Babel的更新,也出现了
babel/preset-typescriptplugin,因此也可视为Compiler。Bundler
如Webpack、Rollup,将程式码、资源打包成网页,可搭配Transpiler、Loader等等,把网页用到的所有资源包成一个档案。
Compressor
如Terser,对程式码进行Treeshake,删去没用到的原始码。
有了这些工具的帮忙,才能够直接在程式码中使用浏览器尚未支援的JavaScript语法、常用在React的JSX,或是合并、压缩程式码来提升网页效能等等,但经历多道转换的原始码早已面目全非,遇到问题时几乎无法用来Debug,于是Sourcemap就出现了。
原始码VS打包后的代码
Why
通常在Debug的时候会藉由错误讯息、Callstack、行号等等来找出问题,但原始码经过转换后变数名称、行号已经完全不同,这时就要依靠Sourcemap来映射转换前后的代码位置,出错时才能对应到原始码进行Debug。
另外不只是JavaScript,Sourcemap也能应用在其他资源如经过了Bundler、SASS工具转换过的CSS。
原理
至于代码的映射方式,其实就是建立一份代码、原始码字元位置对照表,并把对照表的路径放在实际执行的代码中来读取,其步骤大概是:
原始码打包成一行执行码将原始码的每个变数存为阵列将执行码各个字元对应到原始码的行号和阵列位置以VLQ和Base64编码产出最终的Sourcemap
注意到右下角的sourcemappedfromlog.js吗?
有了对照表,当网页中的程式码出错时就能映射到原始码的位置,也就能够从原始码下手如新增断点来Debug。
考量篇幅及主题,想要深入了解对照表的产生方式请参考实作原理,真的非常有趣,值得一看,另外在实作原理文章下方可以看到Sourcemap的官方规范,你没看错,就是一份Googledocs文件。
FileEditing
FileEditing是在DevTools中编辑页面档案的功能,总归一句就是把ChromeDevTools当成IDE来使用,可以直接打开这个Sources-Files来试试。
进入Demo网页后先开启DevTools,照着Console里面的提示
先打开Source面板的Page页签按下index.js开启程式码编辑index.js的greetfunction后按Command+S存档马上就会看到程式码的行为改变了!基本的档案编辑功能就这样,非常直觉简单,提供了一个简易的程式码编辑功能来改变网页行为。
不过读者是否有发现可以编辑JavaScript、CSS等档案,但却不能编辑HTML,且即使按下存档,上方会出现一个惊叹号图示,重整页面后刚才的修改就全都消失了,该怎么保留编辑的内容呢?请待下回分晓。
无法储存到档案系统!?
小结
今天提及的Sourcemap在Sources面板扮演了非常重要的角色,常见的Bundletools也都有关于Sourcemap的设定(如Webpack),能依照需求及环境决定是否建立Sourcemap以及建立的方式。
另外现在ChromeDevTools中的Fileediting只剩下功能而没有页签,取而代之的是Filesystem和Overrides,会在Sources-Workspace中详细介绍。
#debug#