2015-11-16 50 views
3

在這個簡單的巴別塔(6.1.18)例如babel --presets es2015 test.js變換:爲什麼巴貝爾6部分(不必要的)代碼轉換

'use strict'; // enable strict mode 

(function() { 
    const A = 3; 
}()); 

'use strict' // enable strict mode 
; 
(function() { 
    var A = 3; 
})(); 

這主要是出於好奇,但我會有興趣更好地理解爲什麼: - 第一行中分號的位置已被移入單獨的行 - 生命的語法已從(function() {}());更改爲(function() {})();

+3

它不是真的決定轉換此代碼,因爲它可以保持原樣......這就是巴貝爾總是使用特定的語法來輸出特定的結構。您的輸入被解構爲一個抽象的語法樹,然後重新組裝成Javascript代碼。這裏的「彙編程序」被硬編碼以輸出這些特定的情況。就這樣。你可能會問,爲什麼它以這種特定的格式輸出東西,但是擔心爲什麼這個輸入具體轉換爲特定的輸出是沒有意義的。 – deceze

回答

6

An 摘要語法樹不保留格式化信息,例如,無論調用括號是在分組運算符之外還是在分組運算符之內。實際上,分組運營商((...))是not even represented in the AST

這就是爲什麼人們正在致力於Concrete Syntax Tree implementation,這將包含這樣的信息,然後代碼生成器可以使用它來保持更接近原始源代碼。

如果部分代碼沒有變化(如recast),有些工具可以重用原始代碼,但由於Babel主要關注瀏覽器的代碼轉換,所以這可能不那麼重要。這現在可能會改變,巴別變得更像一個平臺。

+0

這正是我感興趣的內容。Babel從AST重新生成代碼。顯然,我更願意假設Babel在編譯我的代碼時使用最少侵入性的方法。我想沒有人會真正關心,但我非常感謝「重鑄」方法,只做了絕對必要的更改,我的代碼儘可能保留「我的」代碼。謝謝! – doberkofler

4

巴貝爾是一個transpiler並以非常相似的方式工作的編譯器:

enter image description here

  1. 通天執行您的代碼詞法分析。這意味着它被標記。 (function(){})()成爲令牌流,例如"(" "function" "(" ")" ...

  2. babel創建語法樹。代表您的程序的線性令牌流將轉換爲如下形式的樹:enter image description here

  3. 然後,babel將對您的代碼執行語義分析。這是當它檢查是否存在錯誤,可以確保你的代碼是合法的ECMA6代碼,添加缺少的分號,並確保語法樹是一個合法的程序

  4. 巴貝爾從語法樹

生成JavaScript代碼因此,您可以看到有幾種方法可以編寫相同的代碼,但是執行語義分析和代碼生成時,會生成相同的代碼。

+0

我確實瞭解巴貝爾的工作原理,但希望在不需要的時候,它不那麼具有侵擾性。我用我給出的例子來說明巴貝爾實際上不需要傳譯任何東西的兩種情況。我的文件的語法樹已經包含'use strict'語句,並且iife生成相同的代碼。 – doberkofler

+0

嗯,但'(function(){}());'有一個不同於'(function(){})()的語法樹;' - 它不僅僅是空格。所以一定還有其他的事情要做。 – Bergi

+1

@Bergi:這是相同的語法樹,至少遵循ESTree規範。 –