最近在网上看到了 Build your own React
这篇文章,做者从零开始实现了一个简易类 React 框架,虽然没有过多的优化,但 React 中的核心思想 Concurrent Mode
,Fiber Reconciler
等都有实现,看完后对理解 React 有很大帮助,所以我想在 Build your own React
的基础上,对代码进行拆分,搭建起本身的框架工程,而后完善教程中没完成的其余功能,代码在 rac 中。node
技术栈上我选择用 TypeScript 开发,Rollup 打包, 都是平时用的很少的技术,顺带一块儿练练手,并且相比 webpack, rollup 配置更简单一些。在工程中建立一个 tsconfig.json
和一个 rollup.config.js
, 而后安装一下须要的 rollup 插件,好比 rollup-plugin-typescript2
, rollup-plugin-terser
。另外准备一个 examples
文件夹,建立一个小型的 demo 工程,使用 tsx 开发react
若是想让 TypeScript 支持 jsx,须要在 tsconfig 中开启 jsx
TypeScript 自带了三种模式: preserve
, react
,和 react-native
,咱们设置为 react
, TypeScript 就会将代码中的 jsx 翻译成 React.createElement
,这也是在使用 jsx 时,React 必需要在做用域中的缘由。webpack
可是咱们要本身实现一个 React-like 框架,彻底能够给 React.createElement
换个名字。在 Build your own React
中,做者经过 /** @jsx Didact.createElement */
注释,告诉编译器将 jsx 的输出函数改成 Didact.createElement
,这个方法只对当前文件生效,若是是在工程中使用为每一个文件都加一行注释就麻烦了。咱们经过另外一种办法,在 tsconfig 中经过 jsxFactory
属性指定,咱们这里叫 h
,除了 React.createEmenent
,还有个特殊元素 - Fragment
,TypeScript 默认会翻译成 React.Fragment
,咱们经过 jsxFragmentFactory
直接改成 Fragment
。git
tsconfig.json
:es6
{ "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 的配置比较简单,除了 input,output,再额外加一些插件就能够了:github
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 支持 TypeScript,须要给 Eslint 一些额外配置:web
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
中,做者依照typescript
这几步逐步实现了一个 mini React,为了提升代码可读性和可维护性,会把这些功能划分到不一样的文件中:json
. ├── 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
到这工程就搭建起来了,整个工程的结构和一些代码实现上借鉴了 fre 这个框架。react-native