在线本地调试大观

标签: Programming | 发表时间:2011-07-24 12:54 | 作者:lifesinger Vingel
出处:http://lifesinger.wordpress.com

线上页面有 bug 了,或者需要修改或增加某项功能时,传统的开发/调试方法如下:

  1. 在本地搭建一套完整的开发环境,前后端代码甚至数据库等全在本机。想修改啥就修改啥,修改验证好了发布上线即可。好处是全盘控制非常强大,坏处是环境越复杂越麻烦。当本地与线上存在差异时,有些 bug 甚至无法重现。对于云时代的前端开发攻城师来说,这种方式太笨重了。
  2. 本地仅保存前端代码,修改后,提交到测试环境验证。这种方式无需搭建本地环境,但调试起来麻烦,遇到棘手的 bug 时,很可能需要反复 修改代码 -> 提交代码 -> 验证功能 -> 再次修改。虽然可以通过脚本部分实现自动化,但还是不够方便。
  3. 将线上页面保存到本地,直接修改页面中的 css/js 引用。这招非常简明快捷,在某些场合下的确是上上之选。但坏处也很明显,页面稍微复杂一点,就有可能失灵。

为了过上快乐幸福的生活,爱折腾的攻城师们想出了一个好点子:在线本地调试

名词解释

在线本地调试是指:

  1. 在线是指环境。环境是线上的,包括数据请求、cookie 等等,不是高仿,是货真价实的正品。
  2. 本地是指前端代码在本地,包括 js/css 等静态资源。
  3. 调试是指修改本地代码 + 刷新页面即可看到效果。

基本原理

很多事情,没有做不到,只有想不到。一旦开始追求美好的调试生活,立刻就能发现原理非常简单:

只要能将需要调试的代码映射到本地即可。

对前端来说,需要调试的代码一般是 js/css 文件。

html 代码有时也需要修改,可以搭建本地环境或用 Fiddler 等工具来实现,这篇博客里就不多说了。

我们将关注点聚焦到 js/css 文件的本地映射。

方式一:客户端工具

在 Windows 系统下,可以用大名鼎鼎的 Fiddler 来实现:AutoResponder Reference . 阿里巴巴中文站 UED 博客有图文教程:使用 Fiddler 提高前端工作效率

在 Mac 系统下,也有类似的工具:Charles .

客户端工具的好处是灵活,想映射什么就映射什么,想映射到哪就映射到哪。

坏处是要安装软件。在云时代,安装客户端软件显得太 out 啦。更恼人的是,Fiddler 依赖 Microsoft .NET Framework. Charles 更不用说了,是收费的。

方式二:服务端代理

比如在淘宝,可以先让所有攻城师都修改 hosts:

10.1.2.3    a.tbcdn.cn

使得 js/css 文件都通过内部代理服务器来访问。既然是内部服务器,就可以进一步通过 samba 等服务 mount 到本地。

好处是可定制性高,可以实现本地、测试、预发和线上等环境的自由切换等等功能。

坏处是对内网环境有依赖,在外网使用时,需要开启 VPN 软件。其次,要从服务器端代理回本机目录时,要通过 HFS 等客户端软件来实现,有点小麻烦。还有一个小缺陷是,当同时使用的人数过多时,服务器的性能和稳定性很重要。一旦出故障,攻城师就只能看美女了。

无论如何,淘宝聪明的攻城师们已实现了一个内部方案:UCool. 非常赞非常好用,内部人士不容错过。

方式三:利用虚拟主机与文件重写

作为攻城师,工作电脑上开一个 web 服务是家常便饭。假设我们使用的是老牌的 apache. 通过 Virtual Host 和 Rewrite Module 就可以实现本地映射。下面以淘宝为例来说明。

淘宝的 js/css 文件存放在 cdn 上,有两个域名:a.tbcdn.cnassets.taobaocdn.com. 绝大部分线上页面使用的是 a.tbcdn.cn. 因此我们可以绑定 a.tbcdn.cn 到本地,同时保持 assets.taobaocdn.com 依旧指向线上:

127.0.0.1            a.tbcdn.cn

接着修改 apache 的配置文件:

<VirtualHost *:80>
  DocumentRoot "/Users/lifesinger/Sites/svn/assets/"
  ServerName a.tbcdn.cn
  RewriteEngine On
  #
  # handle combo url "/??path/to/a.js,path/to/b.js"
  #
  RewriteCond %{QUERY_STRING} ^\?.*\.(?:js|css)(?:,|$) [NC]
  RewriteRule ^/.*$ /combo.php [QSA,L,NS,NC]
  #
  # redirect to online version when the requested file does not exist in local file system.
  #
  RewriteCond /Users/lifesinger/Sites/svn/assets/%{REQUEST_FILENAME} !-F
  RewriteRule ^/(.+)$ http://assets.taobaocdn.com/$1 [QSA,P,L,NC]
</VirtualHost>

combo.php 的内容如下:

<?php

$LOCAL_ROOT = "/Users/lifesinger/Sites/svn/assets";
$REAL_CDN = "http://assets.taobaocdn.com";

$parts = explode("??", $_SERVER["REQUEST_URI"]);
$base = $parts[0];
$files = explode(",", $parts[1]);

if (strpos($files[0], ".js")) {
  header("Content-type: application/x-javascript");
} else {
  header("Content-type: text/css");
}

foreach($files as $file) {
  $url = $base.$file;
  $root = $REAL_CDN;

  if(file_exists($LOCAL_ROOT.$url)) {
    echo "/* fetched from local file system */\n";
    $root = $LOCAL_ROOT;
  }

  echo file_get_contents($root.$url);
}

这样,要调试某个文件时,仅需要在本地 assets 目录下,按照线上的目录结构,放上需要修改的文件即可。本地没有的文件,会依旧访问线上。

这种方式很灵活强大,稍微修改修改,对绝大部分项目都适用。缺点是稍有门槛,要自己配置。对于爱折腾的攻城师来说,强烈推荐这种方式。

方式四:基于 seajs 的本地映射

如果一个页面是用 seajs 组织的,意味着所有用 seajs 加载的 js/css, 都可以映射到任意路径。我们以 markzhi.com 为例来说明。

正常访问 markzhi.com 时,加载的 js 文件都是线上的:

要将线上文件映射到本地,首先需要在访问地址上加上标识 http://markzhi.com/?seajs-debug. 注意右下角的悬浮层:

在输入框里填写上映射配置文件:http://localhost/seajs-map.js

seajs-map.js 的内容为:

define(function() {
  var rules = [];

  // the map rules for markzhi.com
  rules.push([
    'http://markzhi.com/assets/',
    'http://localhost/~lifesinger/markzhi/portal/src/main/webapp/assets/'
  ]);

  seajs.config({'map': rules});
});

rules 还可以是正则,比如:

// replace compressed version to debug version
rules.push([
  /^(.*)\.js$/i,
  '$1-debug\.js'
]);

点击 SeaJS Debug Console 悬浮层的 Refresh 按钮,就可以看到除了 seajs 自身,其他文件到映射到本地了:

成功映射后,可以点击 Hide 按钮隐藏掉悬浮层,点击 Exit 按钮是退出 debug 模式,还原到正常状态。

注意:在 debug 状态时,页面的 title 会自动添加 [debug] 前缀以供辨识。

除了通过 ?seajs-debug 的方式来开启调试控制层,还可以通过 bookmarklet 的方式来开启:映射插件

这种方式的好处是:方便快捷,对调试页面所在机器无要求,开发机器上也只需要有 www 服务即可。比如对于 iPad 来说,可以用 ?seajs-debug 打开配置层,让配置文件指向开发机器。这样,就可以在开发机器上写代码,刷新 iPad 上的页面立刻就可以看到修改后的效果。这种便捷,是其他几种方式很难做到的。

坏处是:要调试的代码必须是通过 seajs 加载的,这是前提条件,必不可少。除此之外,暂时想不到有什么不妥之处。

小结

我最常用的方式是:

  1. 基于 seajs 的本地映射。如果要调试的文件是用 seajs 加载的,这种开发调试方式非常便捷。
  2. 利用虚拟主机和文件重写。当要调试的文件不是用 seajs 加载的,通过这种方式,可以一次配置,永久受用。

调试方式就如编辑器一样,没有最好,只有最合适。偶尔,notepad 会比 IDE 还方便,保存到本地的调试方式也有可能比其他任何方式都快捷。清晰地知道各种方式的利弊,合理选择就好。


相关 [在线 调试 大观] 推荐:

在线本地调试大观

- Vingel - 岁月如歌
线上页面有 bug 了,或者需要修改或增加某项功能时,传统的开发/调试方法如下:. 在本地搭建一套完整的开发环境,前后端代码甚至数据库等全在本机. 想修改啥就修改啥,修改验证好了发布上线即可. 好处是全盘控制非常强大,坏处是环境越复杂越麻烦. 当本地与线上存在差异时,有些 bug 甚至无法重现. 对于云时代的前端开发攻城师来说,这种方式太笨重了.

在线调试并共享HTML,CSS,JS

- Albert - [米随随] s5s5
如题,以后同人讲代码时可以用到. 2004年04月9日 -- MSN中文专业站 (0). 2006年06月5日 -- 读“疲倦的博客们”有感 (9). 2005年07月20日 -- 基于web2.0的网站创意 (33).

5个优秀的在线调试代码网站

- - CSDN博客推荐文章
对于编程开发的人来说,有个快速测试代码的地方是非常方便重要的,这里,我们收集了5个很好用的在线调试网站. 是一款简单的在线 IDE 编辑器服务,你只需要把代码粘贴进去就可以编译运行了,连工程也不需要新建,而且 codepad 支持的语言达到了9种,支持的语言有:C,C++,D,Haskell,Lua,OCaml,PHP,Perl,Plain Text,Python,Ruby,Scheme,Tcl.

Log调试

- - ITeye博客
在开发中我们一定不能避免使用Log类,但是这个类存在一个问题就是,当你在程序中使用了大量的Log,那么在程序开发完毕的时候,这将是一个问题,因为,你需要将所有的Log记录注释掉(当然,你不注释也是可以的). 我们可以写一个类,将Log类包装起来,使用一个boolean来控制所有的Log记录的显示. public static final boolean isDebug = true;//这里控制所有Log的显示情况.

Python调试

- - 企业架构 - ITeye博客
原文地址: http://blog.csdn.net/xuyuefei1988/article/details/19399137. 1、下面网上收罗的资料初学者应该够用了,但对比IBM的Python 代码调试技巧:. IBM:包括 pdb 模块、利用 PyDev 和 Eclipse 集成进行调试、PyCharm 以及 Debug 日志进行调试:.

前端调试技巧(PC调试)

- - 掘金 前端
前端工作中,不仅编码很重要,重现bug,解决bug的能力同样重要. 本文就一些调试技巧做出总结,不足之处,欢迎大家多多补充. 在你觉得有问题的代码处,加上一句 console.log() 就好了. 然后在开发者工具控制台就可以看到你打印出来的东西了. 在代码中添加 debugger 语句,当代码执行到该语句的时候就会自动断点.

远程调试Tomcat

- - ITeye博客
  这种情况下只能通过查看远程服务器上的log来调试,如果出现unknown source说明编译的时候没有加入行号的信息,按如下修改.   a)通过javac编译时,默认相当于指定-g:source,lines,这样编译出来的class文件中会包含源代码和行号信息.   b)而通过ant编译时,默认相当于指定-g:none,这样编译出来的class文件会比较小,但是不包含任何调试信息,所以出错的时候就会打印出unknown source.

gdb调试工具

- - CSDN博客系统运维推荐文章
查看帮助一是man 命令,二是进入 www.gnu.org,找到gdb的帮助文档(更详细). gcc -Wall -g main.c -o main,只有这样才能产生调试信息,包括core的调试信息.     run(r)  运行,执行到断点,重新用r,表示重新开始执行.     list(l)  列出源代码,l 2,l main,l 2,16(数字表示行数).

python代码调试

- - 阿里古古
【转自: http://blog.csdn.net/luckeryin/article/details/4477233】. 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序. 例如,有模拟税收计算的程序:. debug_demo函数计算4500的入账所需的税收. 在需要插入断点的地方,加入红色部分代码:如果_DEBUG值为True,则在该处开始调试(加入_DEBUG的原因是为了方便打开/关闭调试).