從頭寫React-like框架的工程搭建實現(xiàn)
最近在網上看到了 Build your own React 這篇文章,作者從零開始實現(xiàn)了一個簡易類 React 框架,雖然沒有過多的優(yōu)化,但 React 中的核心思想 Concurrent Mode,F(xiàn)iber Reconciler 等都有實現(xiàn),看完后對理解 React 有很大幫助,因此我想在 Build your own React 的基礎上,對代碼進行拆分,搭建起自己的框架工程,然后完善教程中沒完成的其他功能,代碼在 rac 中。
工程搭建
技術棧上我選擇用 TypeScript 開發(fā),Rollup 打包, 都是平時用的不多的技術,順帶一起練練手,而且相比 webpack, rollup 配置更簡單一些。在工程中創(chuàng)建一個 tsconfig.json 和一個 rollup.config.js, 然后安裝一下需要的 rollup 插件,比如 rollup-plugin-typescript2, rollup-plugin-terser。另外準備一個 examples 文件夾,創(chuàng)建一個小型的 demo 工程,使用 tsx 開發(fā)
支持 jsx
如果想讓 TypeScript 支持 jsx,需要在 tsconfig 中開啟 jsx TypeScript 自帶了三種模式: preserve, react,和 react-native,我們設置為 react, TypeScript 就會將代碼中的 jsx 翻譯成 React.createElement,這也是在使用 jsx 時,React 必須要在作用域中的原因。
但是我們要自己實現(xiàn)一個 React-like 框架,完全可以給 React.createElement 換個名字。在 Build your own React 中,作者通過 /** @jsx Didact.createElement */ 注釋,告訴編譯器將 jsx 的輸出函數(shù)改為 Didact.createElement,這個方法只對當前文件生效,如果是在工程中使用為每個文件都加一行注釋就麻煩了。我們通過另一種辦法,在 tsconfig 中通過 jsxFactory 屬性指定,我們這里叫 h,除了 React.createEmenent,還有個特殊元素 - Fragment,TypeScript 默認會翻譯成 React.Fragment,我們通過 jsxFragmentFactory 直接改為 Fragment。
tsconfig.json:
{ "compilerOptions": { "target": "esnext", "module": "commonjs", "moduleResolution": "node", "jsx": "react", // enable jsx "jsxFactory": "h", // React.createElement => h "jsxFragmentFactory": "Fragment", // React.Fragment => Fragment "rootDir": "./src", "lib": ["dom", "es2015"] } }
Rollup 配置
Rollup 的配置比較簡單,除了 input,output,再額外加一些插件就可以了:
const path = require('path') const typescript = require('rollup-plugin-typescript2') const { terser } = require('rollup-plugin-terser') const eslint = require('@rollup/plugin-eslint') export default { input: 'src/index.ts', output: [ { file: 'dist/rac.umd.js', format: 'umd', name: 'rac' } ], plugins: [ terser(), eslint({ throwOnError: true, include: ['src/**/*.ts'] }), typescript({ verbosity: 0, tsconfig: path.resolve(__dirname, 'tsconfig.json'), useTsconfigDeclarationDir: true }) ] }
Eslint in TypeScript
為了能讓 Eslint 支持 TypeScript,需要給 Eslint 一些額外配置:
module.exports = { parser: '@typescript-eslint/parser', env: { es6: true, browser: true }, plugins: [ '@typescript-eslint' ], extends: [ 'eslint:recommended', ], parserOptions: { sourceType: 'module' }, rules: { ... } }
項目結構
React 新的 Fiber 架構有幾個核心概念,在 Build your own React 中,作者依照
- Step I: The createElement Function
- Step II: The render Function
- Step III: Concurrent Mode
- Step IV: Fibers
- Step V: Render and Commit Phases
- Step VI: Reconciliation
- Step VII: Function Components
- Step VIII: Hooks
這幾步逐步實現(xiàn)了一個 mini React,為了提高代碼可讀性和可維護性,會把這些功能劃分到不同的文件中:
. ├── README.md ├── examples // demo目錄 ├── package.json ├── rollup.config.js ├── src │ ├── dom.ts │ ├── h.ts │ ├── hooks.ts │ ├── index.ts │ ├── reconciler.ts │ ├── scheduler.ts │ └── type.ts └── tsconfig.json
- dom.ts 中處理 DOM 相關工作
- h.ts 中是對 jsxFactory, jsxFragmentFactory 的實現(xiàn)
- hooks.ts 中是對 hooks 的實現(xiàn)
- reconciler.ts 是 reconcile 階段和 commit 階段的實現(xiàn)
- shceduler.ts 是任務調度器的實現(xiàn)
- type.ts 是一些類型定義
到這工程就搭建起來了,整個工程的結構和一些代碼實現(xiàn)上借鑒了 fre 這個框架。
到此這篇關于從頭寫React-like框架的工程搭建實現(xiàn)的文章就介紹到這了,更多相關React-like搭建內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
react中的forwardRef 和memo的區(qū)別解析
forwardRef和memo是React中用于性能優(yōu)化和組件復用的兩個高階函數(shù),本文給大家介紹react中的forwardRef 和memo的區(qū)別及適用場景,感興趣的朋友跟隨小編一起看看吧2023-10-10React實現(xiàn)控制減少useContext導致非必要的渲染詳解
這篇文章主要介紹了React如何有效減少使用useContext導致的不必要渲染,使用useContext在改變一個數(shù)據(jù)時,是通過自己逐級查找對比改變的數(shù)據(jù)然后渲染,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-11-11React利用插件和不用插件實現(xiàn)雙向綁定的方法詳解
我們知道在 angular 中數(shù)據(jù)時雙向綁定的;而在 react 中,數(shù)據(jù)是向一個方向傳遞:從擁有者到子節(jié)點。也就是我們說的單向數(shù)據(jù)綁定。那如何實現(xiàn)雙向綁定呢?下面這篇文章主要給大家介紹了關于React利用插件和不用插件實現(xiàn)雙向綁定的方法,需要的朋友可以參考下。2017-07-07react學習每天一個hooks?useWhyDidYouUpdate
這篇文章主要為大家介紹了react學習每天一個hooks?useWhyDidYouUpdate使用示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04Zustand介紹與使用 React狀態(tài)管理工具的解決方案
本文主要介紹了Zustand,一種基于React的狀態(tài)管理庫,Zustand以簡潔易用、靈活性高及最小化原則等特點脫穎而出,旨在提供簡單而強大的狀態(tài)管理功能2024-10-10解決React報錯Unexpected default export of an
這篇文章主要為大家介紹了React報錯Unexpected default export of anonymous function解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12