JavaScript CoffeeScript 支持 source maps 了,在浏览器中调试 CoffeeScript 已成为现实

darkbaby123 · 2013年03月16日 · 最后由 chanshunli 回复于 2015年03月16日 · 10802 次阅读

CoffeeScript 1.6.1 版本的新功能之一,就是支持 source maps。

什么是 source maps?简单的说,它可以通过一定的方式,从编译/压缩后的 JavaScript 代码,找到对应的未编译/压缩的源文件。

这个技术就是用来调试用的,目前可以用在两个地方:

  1. 从压缩后的 JavaScript 代码找到未压缩的版本,让你在生产环境下调试时,不至于面对天书一样的 JavaScript 无从下手。
  2. 从编译后的 JavaScript 代码找到编译之前的 CoffeeScript 代码,不用你身体内置编译器了。

我们可以建一个简单的项目试试,如果你不想动手的话,看看代码和图片也足够明白了。

一个小实验

需要环境:Node.js, npm, 已安装 coffee-script 包,Google Chrome 最新版

先为项目建立一个文件夹叫 aaa。里面包含两个文件,a.coffee 和 a.html,原谅我起的名字吧~

a.coffee

window.hello = ->
  console.log 'Hello World'

a.html

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="a.js"></script>
  </head>
  <body></body>
</html>

然后在 aaa 目录下,执行 coffee 命令编译 a.coffee,带上参数 -m 用于生成 source maps 需要的文件。

Terminal

coffee -cm a.coffee

这会生成两个文件,a.js 和 a.map,来看看这个两个文件:

a.js

//@ sourceMappingURL=a.map
// Generated by CoffeeScript 1.6.1
(function() {

  window.hello = function() {
    return console.log('Hello World');
  };

}).call(this);

a.map

{
  "version": 3,
  "file": "a.js",
  "sourceRoot": "",
  "sources": [
    "a.coffee"
  ],
  "names": [],
  "mappings": ";;AAAA;CAAA;CAAA,CAAA,CAAe,EAAf,CAAM,GAAS;CACL,EAAR,IAAO,IAAP,EAAA;CADF,EAAe;CAAf"
}

a.js 自然是编译后的 JavaScript 文件,跟以前不同的是开头有两行注释。其中第一行就是告诉浏览器去找一个 map 文件 -- a.map。 浏览器就会通过 a.map,把编译前后代的代码一一对应起来。a.map 中的 mappings 内容就是记录这段内容的,它会根据 a.coffee 的改变而改变。 有兴趣的可以自行修改 a.coffee 尝试下。

项目到这里就搞完了。现在用浏览器实验下。

现在我们用 Google Chrome 打开 a.html。再打开 Inspector 工具。先点击右下角的齿轮图标打开 Settings,勾选 Enable source maps。

enable source maps

然后关闭 Settings,点击上面的 Sources 标签查看源代码,你会看到浏览器列出了 a.coffee 文件!

a.coffee {% img /images/blog/sources_coffee.png %}

现在我们先打个断点,然后执行 hello 函数看看:

a.coffee debug

See ? It works !

小结

不难看出,要做到在浏览器中调试 CoffeeScript 代码,必须做到以下几点:

  1. 浏览器支持 source maps,目前我只知道 Google Chrome 支持,其他浏览器的情况未知。
  2. JavaScript 文件中提供关于 map 文件的信息。这需要 CoffeeScript 编译时加上 -m 参数。
  3. 浏览器可以通过 url 获取到 coffee 文件和 map 文件。

也许因为这些原因,目前 Rails 项目里面还不能使用 source maps 直接调试 CoffeeScript 文件。好消息是 Sprocket 现在正在添加对 source maps 功能的支持,应该不久就会有结果。到时候用 Rails 的我们就又 high 啦。

另外,source maps 只是一个映射到源文件的技术,这就是说以后还可以利用这个技术在浏览器中看 SASS 和 LESS,说不定还可以通过 html 看 erb,slim 和 haml?前景可谓一片光明。

参考文档

这篇文章讲的很细,包括从压缩的 JavaScript 映射到未压缩的版本,从 JavaScript 映射到 TypeScript(微软的预编译语言,更类似静态语言)等等。

太强大了!!!

很强大,一直用 chrome 调试

assets precompile 能生成 source map 了吗?

@ShiningRay 目前还不行,因为 asset pipeline 是由 Sprocket 这个 gem 负责的,目前还没有支持这个,不过这件事情正在做,还专门建立了一个 source-maps 的分支。issues 讨论里相关的 ticket 是一年前就建立好的,就是一直在等 CoffeeScript 支持 source maps 特性,现在终于时机成熟了。

仔细想想,Rails 要支持 source maps 要做的事情还挺多的:

  1. 编译 coffee 文件时除了要生成带特定注释的 js 文件,还要生成 map 文件;而且要让浏览器能直接访问 coffee 文件。
  2. source maps 估计会以可配置参数的形式放进 Sprocket,比如只在 development 环境下打开。不然你在跑在 production 环境下压缩好的 js,别人一个 enable source maps 就可以把源码看光光……

够强大,期待能早些用上

@ShiningRay 如果是在选中 html 元素时在右边列出 scss,估计会有点呛

  1. source maps 估计会以可配置参数的形式放进 Sprocket,比如只在 development 环境下打开。不然你在跑在 production 环境下压缩好的 js,别人一个 enable source maps 就可以把源码看光光……

這個重要

Awesome! CoffeeScript Rock!

这个事情我前几天正好在弄,有点头疼的是,新版本内核的 webkit,不管是 webkit nightly 还是 chome 的,更改了对 sourcemap 的支持,这些会 break 目前 rails 对 sourcemap 的支持,貌似要等到下个版本的 rails 才会带出来,不知道现在解决了没有

@pzgz 我当时写这个的时候把 Chrome 升级到最新版了,现在这个也是最新的吧。版本号 25.0.1364.172。也没问题啊。不晓得你用的是不是更高版本的 Chrominum。不过我是纯静态页面测试的。Rails 4 出的时候能支持这个就没有遗憾了。

#12 楼 @darkbaby123

Chrome 没问题,我用的事 Canary Build,和 Safary 的 nighly build,Canary 的版本是 Version 27.0.1451.3 canary

Sprocket 现在还不支持,有一个monkey patch可以用 有人封了个 gem coffee-rails-source-maps

阮一峰有篇文章介绍 source map 来着,挺浅显易懂。

@camel 嗯,这个我没试过,可以用用。 @greatghoul 你说了我才知道,确实挺易懂,而且很详细。JavaScript Source Map 详解 我已经加到参考文档里面去了。

匿名 #17 2015年03月16日

这个 在 Chrome 40,好像不太管用了???

需要 登录 后方可回复, 如果你还没有账号请 注册新账号