使用說明

JSX to JS:將 React 程式碼變成純 JavaScript

JSX to JS 的意思,是把 React 元件的標籤語法改寫成瀏覽器能執行的純 JavaScript。這個工具使用 Babel,所以輸出結果和 Babel 建置步驟寫出來的相同。你可以在傳統的 React.createElement 呼叫和自動的 jsx() 執行階段之間選擇,然後複製結果。你的程式碼在瀏覽器中編譯,不會上傳,也不會執行。


JSX to JS 線上使用步驟

不需要安裝,也不用註冊帳號:

  1. 把程式碼貼到JSX 程式碼欄位。欄位空白時會顯示「在此貼上 JSX…」。上限是 1,000,000 個字元。
  2. 稍等一下。你輸入或貼上之後,約在最後一次變更的三分之一秒後自動編譯,所以沒有按鈕要按。第一次使用時 Babel 會下載一次,會稍微久一點。
  3. 在標題JavaScript下方查看結果,內容是唯讀、帶語法上色的程式碼。
  4. 選擇複製到剪貼簿,按鈕會變成已複製。
  5. 想改變編譯 JSX 的方式,請使用旁邊的齒輪按鈕(JSX 執行階段設定)。它會開啟JSX 執行階段群組,裡面有傳統和自動兩個選項。變更後程式碼會重新編譯。

如果文字不是有效的 JSX,你會看到指出行與欄的語法錯誤訊息,加上出錯那一行和標在位置下方的 ^,在修正之前不會有輸出。如果程式碼裡完全沒有 JSX,會原樣以純 JavaScript 回傳,並顯示「這段程式碼中找不到 JSX,所以原樣以純 JavaScript 回傳。」

傳統與自動:React.createElement 還是 jsx()

傳統是預設值。每個元素都會變成 React.createElement(type, props, ...children) 呼叫,Fragment 則變成 React.Fragment。它不會加入任何 import,所以 React 必須已在作用域內。如果你的專案或教學仍在每個檔案匯入 React,或是要配合較舊的設定,就選這個。

自動會把 JSX 變成 jsx() 或 jsxs() 呼叫,子元素放進 props 裡,Fragment 則叫 _Fragment。來自 react/jsx-runtime 的 import 會自動加上,而且只包含程式碼用到的名稱。這個選項需要 React 17 以上,輸出和目前的 React 工具鏈產生的相同。

輸出會保留什麼、改變什麼

不支援的部分:TSX、TypeScript、Flow

它只編譯 JSX。它讀不懂 TypeScript,所以帶有型別標註的 TSX 會出現語法錯誤,Flow 也不支援。它不會執行你的程式碼,不會檢查元件能不能運作,也不會打包檔案。

如果想反過來,把一般 JavaScript 變成有型別的程式碼,請用 JS 轉 TS 轉換器。想閱讀壓縮或混淆過的腳本,則可以用 JS 反混淆工具。

為什麼全部都在瀏覽器裡執行

Babel 只會在你第一次貼上時載入一次,之後的編譯都在你裝置上的 Web Worker 裡進行。你的元件不會被傳到任何地方,也不會被執行,所以貼上帶有副作用的檔案也很安全。


常見問題

要怎麼線上使用 JSX to JS?

把 JSX 貼到「JSX 程式碼」欄位。大約三分之一秒後,編譯好的 JavaScript 會出現在「JavaScript」標題下方。這裡沒有轉換按鈕,按「複製到剪貼簿」就能取走結果。Babel 會在第一次貼上時下載一次,所以第一次會稍微久一點。

Babel 可以把 JSX 變成 JavaScript 嗎?

可以。Babel 的 React 預設集會把 JSX 的標籤改寫成 JavaScript,這個頁面在你的瀏覽器裡執行的就是它,所以輸出和 Babel 建置步驟的結果一致。建置工具在建置專案時也會自動做同樣的事。想看或複製單一元件或程式片段的結果時,就可以用這個頁面。

JS 和 JSX 有什麼差別?

JSX 是加上類似 XML 語法來描述介面的 JavaScript,例如帶有 onClick 處理函式的 button 標籤。瀏覽器無法直接執行,所以編譯器會把每個標籤改寫成一般的函式呼叫,結果就是普通的 JavaScript。.jsx 副檔名只是用來標示含有 JSX 的檔案的命名慣例。

傳統和自動執行階段有什麼差別?

傳統會把 JSX 變成 React.createElement 呼叫,所以每個用到 JSX 的檔案都要有 React 在作用域內。自動會把 JSX 變成 jsx() 和 jsxs() 呼叫,並替你加上來自 react/jsx-runtime 的 import,所以你不必只為了寫 JSX 而匯入 React。自動需要 React 17 以上。這裡的預設值是「傳統」。

要怎麼從 JSX 得到 React.createElement?

讓 JSX 執行階段維持預設的「傳統」就行。每個元素都會變成 React.createElement 呼叫:先是標籤名稱,接著是 props 物件(沒有的話是 null),然後是子元素。Fragment 會變成 React.Fragment。

為什麼輸出用了 React 卻沒有匯入它?

傳統輸出會呼叫 React.createElement 和 React.Fragment,但不會加入 import,因為它假設 React 已經在作用域內。如果你的檔案開頭沒有 import React from 'react',請補上那一行,或把 JSX 執行階段改成「自動」,它會寫出需要的 import。

為什麼輸出裡有 /*#__PURE__*/ 註解?

Babel 會在每個元素呼叫前面加上 /*#__PURE__*/,告訴壓縮工具和打包工具這個呼叫沒有副作用,所以從未用到的元素可以從最終的套件中移除。這些註解你可以保留,也可以刪掉,不會改變程式碼的行為。

可以處理 TSX 或 TypeScript 嗎?

不行。它預期的是一般 JavaScript 裡的 JSX,所以像 props: Props 這樣的型別標註會變成語法錯誤。請先移除型別,或用 TypeScript 編譯器來編譯。Flow 語法也不支援。

我的程式碼會被上傳或執行嗎?

不會。Babel 在你的瀏覽器裡、於 Web Worker 中編譯程式碼,不會有任何內容傳到伺服器。程式碼也不會被執行,所以貼上帶有副作用的元件也很安全。唯一會下載的只有 Babel 本身,而且只有一次。