記一次debug記錄:Uncaught SyntaxError: Unexpected token ILLEGAL


在使用FIS3搭建項目的時候,遇到了一些問題,這里記錄下。

這里是發布搭建代碼:

// 代碼發布時
fis.media('qa')
  .match('*.{js,css,png}',    { useHash: true })                                     // 添加指紋
  .match('*.js',                     { optimizer: fis.plugin('uglify-js') })         // js壓縮
  .match('*.css',                  { optimizer: fis.plugin('clean-css') })      // css壓縮
  .match('*.{png,jpg}',        { optimizer: fis.plugin('png-compressor') })   // 圖片壓縮
  .match('::package',          { spriter: fis.plugin('csssprites') })          // 圖片合並,需要添加:?__sprite
  .match('*.css',                  { useSprite: true })                                   // 對 CSS 進行圖片合並
  .match('*', {
    deploy: [
      fis.plugin('http-push', {
        receiver: 'xxx',
        to: '/xxx/CMS-OPERATION/CMS/static
'
      }),
      fis.plugin('skip-packed', {})
    ]
  });

大家如果使用fis的話,可以把上面的代碼復制下來,然后嘗試發布,保准你會得到下面的提示:

[ERROR] Load /Users/yangyoucun/Documents/market-h5-fe/cms/fis-conf-cms.js error: Unexpected token ILLEGAL
SyntaxError: Unexpected token ILLEGAL

配置文件有200行,剛開始以為是引號出現問題,然后開始排查所有引號,是不是使用正確。

經過排查,引號都是正常的,然后又懷疑是不是分號使用錯誤,一行一行的找,分號也都正確!

最后實在不知道什么原因,果斷求助谷歌。

查看到了這個問題:

No visible cause for “Unexpected token ILLEGAL”

這是地址:No visible cause for “Unexpected token ILLEGAL”

以下是個人翻譯,如果誤導請指出。

文章大意是:

提問者:我的代碼就只有一句,為啥還報Unexpected token ILLEGAL錯誤!代碼如下:

var foo = 'bar';​

下面是解答:

當JavaScript解析器解析代碼的時候,會把代碼分成片段稱為tokens,在JavaScript中有四種基礎的token類型,當一個token不能被分類到這其中的時候,就會貼上ILLEGAL標簽,並拋出錯誤。

還有一些情況會導致這種情況發生,比如:

  • 你的代碼里有一個特殊的@
  • 使用花括號有問題
  • 圓括號
  • 自動補充括號
  • 單引號沒有閉合(例如:this.run('dev1)
  • ...

很多種情況都會引起這個錯誤。如果你的代碼里面沒有明顯的語法錯誤和不合法字符,那么很有可能是由看不見的不合法字符導致的。這也是這個回答要講述的。

但是,我看不見任何不合法的字符啊!

在代碼中有一些不合法的字符在分號的后面。這些字符為Unicode U+200B Zero-width space(又稱為:ZWSP,例如HTML實體:​),大致翻譯成零寬字符。這些字符經常會引起Unexpected token ILLEGALJavaScript語法錯誤。

它從何而來?

我不肯定,但我猜來自jsfiddle,如果你從里面復制代碼,就很有可能包括一個或多個U+200B字符。好像這個工具使用這些字符來控制長字符串。

UPDATE 2013-01-07

自從jsfiddle上次更新,現在它會用紅色的原點顯示出這些字符,和codepen一樣。很明顯,它再也沒有插入U+200B字符,所以這個問題從現在開始應該很少會出現了。

UPDATE 2015-03-17

Vagrant有時候也會出現這種問題,這是VirtualBox的bug。這篇文章的做法是設置sendfile為off;在nginx配置中或者Apache中,設置EnableSendfile為off。

也有人指出,從Chrome開發者工具中復制出來的代碼也包括這些字符,但是我不能夠在我的當前版本(22.0.1229.79 on OSX)中復現。

我如何才能認出它

這些字符時看不見的,那么怎么才能知道他們藏在哪里呢?你可以要求你的編輯器來顯示這些不可見的字符,許多文本編輯器都有這個功能。例如Vim,默認會顯示出來這些特殊字符,並且ZWSP顯示為<u200b>。你也可以在網上發現他們:jsbin會展示為紅點在代碼編輯框中,CodePen.io也會展示為一個點,刪掉在保存然后就沒有了。

下面展示一下截圖:

codepen中

jsfiddle中

jsbin中

相關聯的問題

出現這些字符有時候也不是啥壞事,它也非常有用。在Wiki上有一個例子演示了如何用它來控制長文本的折斷換行。然而,如果你並沒有意識到你的文本中有這些字符的話,這就可能會引起麻煩了。如果這些字符出現在你的字符串中(例如:DOM元素的nodeValue上,但是看不見)。你可能會覺得這個這個字符串是空的,但事實上並不是(使用String.trim也不管用)。

ZWSP也會引起其他的空格在HTML頁面中的展示,就比如ZWSP出現在兩個<div>元素中間時(就比如這個問題)。這個案例基本上不會再jsfiddle中復現了。

另一個潛在的問題是:如果網頁的編碼不是UTF-8,那么這些字符可能回顯示出來(比如在latin1編碼中,會顯示為​)。

如果ZWSP出現在了CSS代碼中(不管是內聯的還是引用的),樣式同樣可能不被展示(經我嘗試,在開發者工具中顯示出來一個空格),一些樣式就不會生效(就比如這個問題)。

** ECMAScript 規范**

在ECMAScript規范(35.1版本)中我沒有找到任何提到這些字符的詳細說明,當前版本在第7.1節提到了這些字符(U+200C以及U+200D),規范中寫道:這些字符應該被當做IdentifierParts(標識符)進行處理,可以出現在評論、字符串文本或者正則表達式文本中,這些字符也可以是變量名,例如:var x\u200c;

7.2章節中列舉了有效的空白字符(例如tab、space、no-break space等等),也稍微提及了其他的Unicode空格字符(“ZS”分類),也應該當做空白格處理。我可能不是最合適的人來討論這個規范,但是在實際中執行時(Chrome、Firefox)都把他們當做unexpected token,引發語法錯誤,在我看來,根據這些,U+200B應該被考慮進空白格規范中。

寫在最后

其實最后的解決方法很簡單,只要把代碼復制到jsfiddle中或者codepen中,刪除錯誤點代碼,然后復制回來就可以了。但是查找過程之痛苦只有我自己知道,配置很正確,但就是無法執行!

每一次debug都是一次學習吧,多多記錄,多多積累。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM