UglifyJs打包压缩问题引起的思考

最近做了一个webapp项目,qa用手机测试功能时,在iphone6plus上表现是白屏,其他手机目测是ok的;因为之前在测试其他项目时也发现在这个iphone6上表现与其他手机不太一样。于是当时以为这个手机出了什么问题,或者其版本过低;就不放在心上。

然而这次白屏的影响还是要加以重视,于是在空闲的时候主动看了下,用VSCosole查看了日志信息,控制台报了一个警告信息:

unexception token const ...

然后看了加载的js源码,竟然发现一个大坑:

  • 代码没有压缩

  • 部分代码也没有编译成es5

这时心里顿生一阵阵的凉意,辛亏看了一下这个问题,否则发到线上会有重大问题。

uglifyjs为啥会报错

  1.   else:  
  2.         print url.split('.net')[1]  
  3.         print url.split('.net')[1].split('/')[1]            
  4.         return url.split('.net')[1].split('/')[1]            
  5. #程序运行主函数            
  6. def run(url,dir_path):    
  7.     read_num_for_sort=[www.wanmeiyuele.cn  ]    
  8.     content_list=[]    
  9.     content_total_list=[]    
  10.         
  11.     #定义文件夹名字并创建文件夹    
  12.     dir_path=dir_path  
  13.     mkdir_folder(dir_path)    
  14.         
  15.     #定义文件名字    
  16.     count_file_name=dir_path+'/www.636591.cn'+datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')+'.txt'    
  17.     fd=open(count_file_name,'w')    
  18.         
  19.     #1.从主页进入获取页面总数    
  20.     main_html=get_html(url)    
  21.     last_page=get_last_page(main_html,fd)    
  22.         
  23.   
  24.     if  last_page>1:  
  25.     #3.组装url,分别加载每页的页面,同时在每一个页面提取我们需要的内容    
  26.         for i in range(1,int(last_page)+1):    
  27.             if  'category' not www.douniu157.comin url:  
  28.                 main_url=url.split(www.wmyl11.com '?www.dejiaylsmile.cn ')[0]+'/article/list/%d?viewmode=contents' % i   
  29.             else:  
  30.                 main_url=url+'/%s' % i  
  31.             self_log('即将获取第%d页的内容,地址是:%s' % (i,main_url))    
  32.                     
  33.             items=get_items(main_url)#获取每一页的页面内容,根据页面内容得到文章item list    
  34.             handle_items(items,content_list,read_num_for_sort)#处理item list    
  35.     else:  
  36.         items=get_items(url)#获取每一页的页面内容,根据页面内容得到文章item list    
  37.         handle_items(items,content_list,read_num_for_sort)#处理item list    
  38.     self_log('总共有%d 篇文章' % len(content_www.078881.cn list))#根据得到的数据,统计文章总数    
  39.     #根据 indexs(阅读次数)这个索引值进行排序    
  40.     #非常好的一个根据列表中字典数据进行排序的方法    
  41.     content_list = sorted(content_list,cmp=lambda x,y:cmp(x['indexs'],y['indexs']),reverse=0)    
  42.         
  43.     article_index = 1    
  44.     for a in content_list:    
  45.         #组装打印语句    
  46.         totalcontent= '第'+str(article_index)www.dfzx157.com+'篇|'+a['title']+'|'+a['read_times']+'|'+a['comments_time']+'|'+a['content_url']    
  47.         #self_log(totalcontent)    
  48.         print totalcontent    
  49.         #将其存贮到本地    
  50.         fd.write(totalcontent)    
  51.         fd.write('www.dfzx157.com \n')    
  52.         article_index +=1    
  53.         content_total_list.append(totalcontent)    
  54.     fd.close()          
  55.     
  56.     return content_total_list    
  57.         
  58. if __name__ == '__main__':     
  59.     print ''''' 
  60.             *****************************************   
  61.             **    Welcome to Spider of Count CSDN  **   
  62.             **      Created on 2017-05-07          **   
  63.             **      @author: Jimy_Fengqi           **   
  64.             ***************************************** 
  65.             '''  
  66.   
  67.     url='http://blog.csdn.net/qiqiyingse?viewmode=contents'    
  68.     #url='http://blog.csdn.net/qiqiyingse/article/category/6292432?viewmode=contents'   
  69.     #url='http://blog.csdn.net/zuoxiaolong8810/article/category/1434962?viewmode=contents'   
  70.     dir_path=get_blocker_name(url)  
  71.     content_total_list=run(url,dir_path)    
  72.     run_to_get_article(content_total_list,dir_path)    

出现上面的问题,首先会想到的webpack的压缩代码插件出问题了,项目中使用uglifyjs-webpack-plugin来压缩代码。于是在本地执行发布上线的操作代码编译压缩,果不其然,压缩类似这样的错误:

ERROR in static/javascripts/test_0_30fbc92.js from UglifyJs
Unexpected token: name (instance) [static/javascripts/test_0_30fbc92.js:2854,6]

具体可以看下图:

然后定位到指定文件的报错的位置,发现都是es6的语法:

  • 第一个文件2874行的内容:let instance

  • 第二个文件78行的内容: function loadJS(url, {timeout = 5000, crossOrigin = false } = {}) {

可以看到,这两个位置都是文件第一次出现es6没有编译的位置,其实在此之后还有很多未编译的es6语法。

可能到这里有人会问,上面压缩报错为什么还能在非iphone6p的其他手机上可以正常访问到呢,可能原因如下:

  • uglifyjs-webpack-plugin虽然报错但是并不会阻止代码的产出,从上图也可以看出代码已经产出。只不过其内容没有压缩

  • 另一个原因我猜是未出现问题的手机上打开浏览器已经支持这些es6语法

分析了这么多,为啥uglifyjs-webpack-plugin会报错呢,因为当前引用uglifyjs-webpack-plugin的版本为0.4.6,它依赖的是uglify-js; 它不支持压缩 es6,可以参考github的issueIt seems like uglify-js does not support es6?

所以:

uglify-js在压缩代码时,遇到es6语法就不会压缩并且也会报错。

如果想压缩e6代码,可以使用uglify-es,其提供配置属性ecma来压缩不同类型的js。

es6为啥没有编译

上面分析我们得知,uglify-webpack-plugin之所以没有压缩,因为代码混合es6语法,那么es6语法为啥没有编译呢?推测:

在使用babel来编译es6时,由于webpack错误配置的原因导致某些文件不在指定的babel编译范围,babel从而会忽略这些js文件的编译

我们的项目目录结构如下:

这是个多个微系统共用的一个工程,这些微系统共用的组件大部分相同,他们共用一个webpack配置。

webpack的有关js的配置如下所示:

   {
      test: /\.js$/,
      loader: 'babel-loader',
      include: [
        path.resolve('moudleA'),
        path.resolve('moudleB')
      ]
    }

但是与服务端交互的api目录、公共组件components目录以及公共的js方法目录common目录没有配置进上面babel-loader的include数组中,从而babel-loader会忽略这些目录下的js文件编译,导致这些目录下的js文件没有被babel-loader编译。从而导致上述问题。

所以,总结一下:

开发过程中遇到任何问题还是需要认真对待一下,保持一颗这就是bug的心态去发现并找出原因所在,才能降低线上出现重大问题的风险。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值