在使用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 ILLEGAL
JavaScript語法錯誤。
它從何而來?
我不肯定,但我猜來自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規范(3、5.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都是一次學習吧,多多記錄,多多積累。