4.9 压缩或解压缩JavaScript
JavaScript广泛用于网站设计。在编写JavaScript代码时,出于代码可读性与方便维护方面的考虑,我们有必要使用一些空格、注释和制表符。但是大量的空格以及制表符会增加JavaScript文件的大小。随着文件体积的增加,网页载入的时间也随之延长。因此,多数专业网站为了加快页面载入,都会对JavaScript文件进行压缩。通过压缩可以大幅度降低空白字符和换行符的数量。经过压缩的JavaScript,还可以通过加入足够的空白字符和换行符进行解压缩,这样就能够恢复代码的可读性。这则攻略就尝试在shell中发掘出类似的功能。
4.9.1 预备知识
我们准备写一个JavaScript压缩工具或代码混乱器,当然,还包括与之对应的解压缩工具。我们打算用文本与字符替换工具tr
以及sed
来试一试。下面来看看具体的做法。
4.9.2 工作原理
首先梳理一下对JavaScript进行压缩与解压缩的处理逻辑以及代码。
- $ cat sample.js
- functionsign_out()
- {
- $("#loading").show();
- $.get("log_in",{logout:"True"},
- function(){
- window.location="";
- });
- }
下面列出了为压缩JavaScript所需完成的工作。
移除换行符和制表符。
压缩空格。
替换注释
/*内容*/
。替换下列内容:
"{ "
替换为"{"
" }"
替换为"}"
" ("
替换为"("
") "
替换为")"
", "
替换为","
" ; "
替换为";"
(我们需要移除所有多余的空格)
要解压缩或者恢复JavaScript的可读性,我们则需要执行下面的任务:
用
";\n"
替换";"
。用
"{\n"
替换"{"
,"\n}"
替换"}"
。
4.9.3 工作原理
通过执行下面的步骤压缩JavaScript:
- 移除
'\n'
和'\t'
:
tr -d '\n\t'
- 移除多余的空格:
tr -s ' '
或者
sed 's/[ ]\+/ /g'
- 移除注释:
sed 's:/\*.*\*/::g'
因为我们需要使用
/*
和*/
,所以以冒号作为sed
的定界符,这样就不必对/
进行转义了。*
在sed
中被转义为\*
。.*
用来匹配/*
与*/
之间所有的文本。
- 移除
{
、}
、(
、)
、;
、:
以及逗号前后的所有空格。
sed 's/ \?\([{ }();,:]\) \?/\1/g'
上面的sed
语句含义如下所示。
sed
代码中的/ \?([{ }();,:]) \?/
用于匹配,/\1/g
用于替换。([{ }();,:])
用于匹配集合[ { }( ) ; , : ]
(出于可读性方面的考虑,在这里加入了空格)中的任意一个字符。(
和)
是分组操作符,用于记忆所匹配的内容,以便在替换部分中进行向后引用。对(
和)
转义之后,它们便具备了另一种特殊的含义,进而可以将它们作为分组操作符。位于分组操作符前后的\?
用来匹配可能出现在字符集合前后的空格。在命令的替换部分,匹配字符串(也就是一个可选的空格、一个来自字符集的字符再加一个可选的空格)被匹配字符所替换。对于匹配字符,替换部分使用了向后引用,并通过组操作符
()
记录了匹配的字符内容。可以用符号\1
向后引用分组匹配的内容。
用管道将上面的步骤按照下列方式组合起来:
- $ catsample.js | \
- tr -d '\n\t' | tr -s ' ' \
- | sed 's:/\*.*\*/::g' \
- | sed 's/ \?\([{}();,:]\) \?/\1/g'
得到输出:
- functionsign_out(){$("#loading").show();$.get("log_in",{logout:"True"},function(){window.location="";});}
接下来,写一个可以将这些混乱的代码恢复正常的解压缩脚本:
- $ cat obfuscated.txt | sed 's/;/;\n/g; s/{/{\n\n/g; s/}/\n\n}/g'
或者
- $ cat obfuscated.txt | sed 's/;/;\n/g' | sed 's/{/{\n\n/g' | sed 's/}/\n\n}/g'
在上面的命令中:
s/;/;\n/g
将;替换为\n;
s/{/{\n\n/g
将 { 替换为{\n\n
s/}/\n\n}/g
将 } 替换为\n\n}
4.9.4 参考
2.6节讲解了
tr
命令。4.6节讲解了
sed
命令。