您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“React實(shí)時(shí)預(yù)覽react-live源碼分析”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“React實(shí)時(shí)預(yù)覽react-live源碼分析”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。
react-live
是一個(gè) react
的實(shí)時(shí)編輯器,可直接編輯 react
代碼,并實(shí)時(shí)預(yù)覽。
本文針對(duì)的源碼版本
src ├── components │ ├── Editor │ │ └── index.js │ └── Live │ ├── LiveContext.js │ ├── LiveEditor.js │ ├── LiveError.js │ ├── LivePreview.js │ ├── LiveProvider.js │ └── LiveProvider.test.js ├── constants │ └── theme.js ├── hoc │ └── withLive.js ├── index.js └── utils ├── test │ ├── errorBoundary.test.js │ ├── renderer.js │ └── transpile.test.js └── transpile ├── errorBoundary.js ├── evalCode.js ├── index.js └── transform.js
先看下導(dǎo)出內(nèi)容,包括:
Editor
:編輯器
LiveProvider
:實(shí)時(shí)編輯環(huán)境的 Provider
,Context.Provider
LiveEditor
:實(shí)時(shí)編輯上下文的編輯器
LiveError
:實(shí)時(shí)編輯上下文的報(bào)錯(cuò)
LivePreview
:實(shí)時(shí)編輯上下文的預(yù)覽
LiveContext
:實(shí)時(shí)編輯的 Context
withLive
:實(shí)時(shí)編輯上下文的 HOC
文件結(jié)構(gòu)和組件拆分一目了然。
先看下 Provider
,它提供了以下內(nèi)容:
element
:實(shí)時(shí)編輯輸出的元素
error
:當(dāng)前的報(bào)錯(cuò)信息
code
:當(dāng)前編輯的代碼
language
:代碼語(yǔ)言
theme
:代碼編輯器主題
disabled
:是否禁用
onError
:報(bào)錯(cuò)的回調(diào)
onChange
:代碼編輯時(shí)的回調(diào)
Provider
用來(lái)收集代碼變更,然后通過(guò) transpileAsync
將代碼編譯生成組件實(shí)例:
function transpileAsync(newCode) { const errorCallback = error => { setState({ error: error.toString(), element: undefined }); }; try { const transformResult = transformCode ? transformCode(newCode) : newCode; return Promise.resolve(transformResult) .then(transformedCode => { const renderElement = element => setState({ error: undefined, element }); // Transpilation arguments const input = { code: transformedCode, scope }; if (noInline) { setState({ error: undefined, element: null }); // Reset output for async (no inline) evaluation renderElementAsync(input, renderElement, errorCallback); } else { renderElement(generateElement(input, errorCallback)); } }) .catch(errorCallback); } catch (e) { errorCallback(e); return Promise.resolve(); } }
renderElementAsync
可以先無(wú)視,主要是用于 noInline
模式下調(diào)用 render
進(jìn)行渲染,邏輯與非 noInline
模式下類似。
實(shí)時(shí)預(yù)覽的核心部分就在這里了,它會(huì)將代碼先進(jìn)行編譯,然后執(zhí)行代碼,取得返回值。
const generateElement = ({ code = '', scope = {} }, errorCallback) => { // NOTE: Remove trailing semicolon to get an actual expression. const codeTrimmed = code.trim().replace(/;$/, ''); // NOTE: Workaround for classes and arrow functions. const transformed = transform(`return (${codeTrimmed})`).trim(); return errorBoundary(evalCode(transformed, { React, ...scope }), errorCallback); };
代碼如上,它會(huì)先去掉頭尾空白,然后去掉結(jié)尾的分號(hào),這一步是為了下一步的 return
拼接能夠正常返回。通過(guò) return
拼接讓 react-live
能夠支持下述語(yǔ)法直接渲染:
直接寫一個(gè)匿名函數(shù):
() => <h4>So functional. Much wow!</h4>;
直接寫 jsx
:
<h4>Hello World!</h4>
單 class
組件:
class Comp extends React.Component { render() { return <center>component</center>; } }
不過(guò)也導(dǎo)致了一定的學(xué)習(xí)成本,如果寫多個(gè)函數(shù),多個(gè)組件,嵌套等情況下會(huì)讓人覺(jué)得語(yǔ)法很奇怪。
transform
就是將代碼通過(guò) sucrase
進(jìn)行轉(zhuǎn)譯,處理 jsx
、class
這些語(yǔ)法,可以理解為通過(guò) babel
轉(zhuǎn)譯。
早期的 react-live
通過(guò) buble
進(jìn)行轉(zhuǎn)譯,能夠支持 jsx
注釋,現(xiàn)在由于 sucrase
不支持 jsx
注釋,所以新版無(wú)法使用 jsx
注釋來(lái)控制 jsx
渲染引擎。
/** @jsx mdx */ // 新版上述注釋會(huì)失效
隨后將轉(zhuǎn)譯的代碼通過(guò) evalCode
轉(zhuǎn)換為 React element
,此處會(huì)將 scope
和 React
傳入 evalCode
中。
const evalCode = (code, scope) => { const scopeKeys = Object.keys(scope); const scopeValues = scopeKeys.map(key => scope[key]); return new Function(...scopeKeys, code)(...scopeValues); };
evalCode
中使用 new Function
來(lái)構(gòu)造函數(shù),scope
就是在這里作為參數(shù)進(jìn)行注入。如果對(duì) new Function
不理解的可以看我之前一篇關(guān)于 JS
沙箱的文章。
errorBoundary
則是一個(gè)簡(jiǎn)單的 HOC
,用來(lái)捕獲生成的組件運(yùn)行時(shí)的錯(cuò)誤信息,通過(guò) errorCallback
拋出。
const errorBoundary = (Element, errorCallback) => { return class ErrorBoundary extends Component { componentDidCatch(error) { errorCallback(error); } render() { return typeof Element === 'function' ? <Element /> : React.isValidElement(Element) ? Element : null; } }; };
上面就是 react-live
能夠?qū)崟r(shí)預(yù)覽的核心代碼了。下面再看下其它幾個(gè)組件,都比較簡(jiǎn)單。
LivePreview
會(huì)接受 Provider
中的 Element
,將其渲染。
LiveError
接受 Provider
中的 error
進(jìn)行渲染。
LiveEditor
則是接收 Provider
的 code
、language
、theme
、disabled
、onChange
,提供編輯功能。
它的編輯器則是通過(guò) useEditable
編輯,Prism
進(jìn)行代碼高亮。
讀到這里,這篇“React實(shí)時(shí)預(yù)覽react-live源碼分析”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。