Shell 压缩或解压缩JavaScript

Shell 压缩或解压缩JavaScript,JavaScript广泛用于网站设计。在编写JavaScript代码时,出于代码可读性以及可维护性方面的考虑,我们会使用一些空格、注释和制表符。但这些内容会增加JavaScript文件的体积,拖慢页面的加载速度。因此,多数专业网站为了加快页面载入速度,都会压缩JavaScript文件。这多是通过删除空白字符和换行符来实现的(也被称为minified JS)。对于压缩过的JavaScript,还可以通过加入足够的空白字符和换行符解压缩,恢复代码的可读性。本章就尝试在shell中实现类似的功能。

Shell压缩或解压缩JavaScript

预备知识

我们准备写一个JavaScript压缩工具,当然,还包括与之对应的解压缩工具。来考虑下面的Javascript代码:

$ cat sample.js
function sign_out()
{

   $("#loading").show();
   $.get("log_in",{logout:"True"},

   function(){
     window.location="";
   });
 }

下面是压缩JavaScript代码所需要完成的工作。
(1) 移除换行符和制表符。
(2) 移除重复的空格。
(3) 替换掉注释/* content */
要解压缩或者恢复JavaScript代码的可读性,则需要:

  • ;\n 替换;
  • {\n 替换 {\n} 替换}

实战演练

按照之前叙述过的步骤,我们使用下面的命令序列:

$ cat sample.js |  \
tr -d '\n\t' |  tr -s ' ' \
| sed 's:/\*.*\*/::g' \
| sed 's/ \?\([{}();,:]\) \?/\1/g'

输出如下:

function sign_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'

该脚本在使用上存在局限:它会删除本不该删除的空格。假如有下列语句:

var a = "hello  world"

两个空格会被转换成一个。这种问题可以使用我们讲过的模式匹配工具来解决。另外,如果需要处理关键JavaScript代码,最好还是使用功能完善的工具来实现。

工作原理

通过执行下面的步骤来进行压缩。
(1) 移除\n\t

tr -d '\n\t'

(2) 移除多余的空格:

tr -s ' '

或者

sed 's/[ ]\+/ /g'

(3) 移除注释:

sed 's:/\*.*\*/::g'

因为我们需要使用/**/,所以用:作为sed的分隔符,这样就不必对 / 进行转义了。
*sed 中被转义为\*
.*用来匹配/**/之间所有的文本。

(4) 移除{,}(,);:以及,前后的空格:

sed 's/ \?\([{}();,:]\) \?/\1/g'

上面的sed语句含义如下。

  • / \?\([{}();,:]\) \?/用于匹配,/\1/g 用于替换。
  • \([{}();,:]\)用于匹配字符组[ { }( ) ; , : ](出于可读性方面的考虑,在这里加入了空格)中的任意一个字符。\(\)是分组操作符,用于记忆所匹配的内容,以便在替换部分中进行向后引用。对()转义之后,它们便具备了另一种特殊的含义,可以作为分组操作符使用。位于分组操作符前后的\?用来匹配可能出现在字符集合周围的空格。
  • 在命令的替换部分,匹配的字符串(也就是一个可选的空格、一个来自字符集的字符再加一个可选的空格)被匹配的子串所替换。由分组操作符匹配到并记忆的子串是通过向后引用来指代的。可以用符号\1向后引用该分组所匹配的内容。

解压缩命令的工作方式如下:

  • s/;/;\n/g;替换为;\n
  • s/{/{\n\n/g{替换为{\n\n
  • s/}/\n\n}/g}替换为\n\n}

学习本章内容可以参考sed 命令tr 命令 相关知识。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

Shell 实例