Write a React-like framework from scratch

Write a React-like framework from scratch

Recently I saw the article Build your own React on the Internet. The author implemented a simple React-like framework from scratch. Although there was not much optimization, the core ideas of React, such as Concurrent Mode and Fiber Reconciler, were all implemented. After reading it, it was very helpful for understanding React. Therefore, I want to split the code based on Build your own React, build my own framework project, and then improve other functions that were not completed in the tutorial. The code is in rac.

Project construction

For the technology stack, I chose to use TypeScript for development and Rollup for packaging. These are technologies that I don’t use very often, so I’ll practice them together. Compared to webpack, rollup configuration is simpler. Create a tsconfig.json and a rollup.config.js in the project, and then install the required rollup plugins, such as rollup-plugin-typescript2, rollup-plugin-terser. Also prepare an examples folder, create a small demo project, and use tsx to develop

Support jsx

If you want TypeScript to support jsx, you need to enable jsx in tsconfig. TypeScript comes with three modes: preserve, react, and react-native. If we set it to react, TypeScript will translate the jsx in the code into React.createElement. This is why React must be in scope when using jsx.

But if we want to implement a React-like framework ourselves, we can just rename React.createElement. In Build your own React, the author uses the /** @jsx Didact.createElement */ comment to tell the compiler to change the output function of jsx to Didact.createElement. This method is only effective for the current file. If it is used in a project, it will be troublesome to add a line of comments for each file. We use another method to specify it through the jsxFactory attribute in tsconfig, which we call h here. In addition to React.createEmenent, there is also a special element - Fragment. TypeScript will translate it into React.Fragment by default. We directly change it to Fragment through jsxFragmentFactory.

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 Configuration

The configuration of Rollup is relatively simple. In addition to input and output, you can add some additional plug-ins:

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

In order to enable Eslint to support TypeScript, some additional configuration is required for Eslint:

module.exports = {
  parser: '@typescript-eslint/parser',
  env: {
    es6: true,
    browser: true
  },
  plugins: [
    '@typescript-eslint'
  ],
  extends: [
    'eslint:recommended',
  ],
  parserOptions: {
    sourceType: 'module'
  },
  rules:
    ...
  }
}

Project Structure

React's new Fiber architecture has several core concepts. In Build your own React, the author follows

  • 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

These steps gradually implement a mini React. In order to improve code readability and maintainability, these functions will be divided into different files:

.
├── README.md
├── examples // demo directory├── package.json
├── rollup.config.js
├── src
│ ├── dom.ts
│ ├── h.ts
│ ├── hooks.ts
│ ├── index.ts
│ ├── reconciler.ts
│ ├── scheduler.ts
│ └── type.ts
└── tsconfig.json
  • Handle DOM related work in dom.ts
  • h.ts is the implementation of jsxFactory and jsxFragmentFactory
  • hooks.ts is the implementation of hooks
  • reconciler.ts is the implementation of the reconcile and commit phases
  • shceduler.ts is the implementation of the task scheduler
  • type.ts is some type definition

At this point, the project has been built. The structure of the entire project and some code implementations are based on the fre framework.

This is the end of this article about the project construction and implementation of the React-like framework written from scratch. For more relevant React-like construction content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • React implementation example using Amap (react-amap)
  • Detailed explanation of virtual DOM and diff algorithm in react
  • React example showing file upload progress
  • How to use lazy loading in react to reduce the first screen loading time
  • How to run the react project on WeChat official account
  • How to write CSS elegantly with react
  • Encapsulate a simplest ErrorBoundary component to handle react exceptions
  • React Fiber structure creation steps
  • Detailed explanation of the use of Refs in React's three major attributes
  • Understanding and using React useEffect

<<:  Detailed explanation of server and location configuration of simple forwarding request of nginx

>>:  Detailed explanation of Java calling ffmpeg to convert video format to flv

Recommend

Vue implements adding, displaying and deleting multiple images

This article shares the specific code for Vue to ...

How to process blob data in MySQL

The specific code is as follows: package epoint.m...

Notes on configuring multiple proxies using vue projects

In the development process of Vue project, for th...

MySQL replication table details and example code

MySQL replication table detailed explanation If w...

A brief discussion on the maximum number of open files for MySQL system users

What you learn from books is always shallow, and ...

HTML thead tag definition and usage detailed introduction

Copy code The code is as follows: <thead> &...

HTML Tutorial: Collection of commonly used HTML tags (5)

These introduced HTML tags do not necessarily ful...

Common JavaScript memory errors and solutions

Table of contents 1. Timer monitoring 2. Event mo...

Solution to the IP address not being displayed under Linux

Table of contents Preface Solution: Step 1 Step 2...

How to bind domain name to nginx service

Configure multiple servers in nginx.conf: When pr...