创建react源码项目-实现jsx转化

55 阅读1分钟

创建react

├── index.ts
├── package.json
└── src
    └── jsx.ts

初始化

cd packages/react
pnpm init
{
  "name": "react",
  "version": "1.0.0",
  "description": "react",
  // "main": "index.js", // esmodule 使用
  "module": "index.ts", // module export 使用
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  // monorepo 指明内部依赖
  "dependencies": {
     "shared": "workspace:*"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

创建jsx

/*
 * @Author: wy
 * @Date: 2024-02-26 15:44:03
 * @LastEditors: wy
 * @LastEditTime: 2024-02-26 17:20:09
 * @FilePath: /笔记/react-source-learn/packages/react/jsx.ts
 * @Description:
 */
import { REACT_ELEMENT_TYPE } from 'shared/ReactSymbols';
import type {
	Type,
	Key,
	Ref,
	Props,
	ElementType,
	ReactElement,
} from 'shared/ReactTypes';
const ReactElement = function (
	type: Type,
	key: Key,
	ref: Ref,
	props: Props,
): ReactElement {
const element = {
    $$typeof: REACT_ELEMENT_TYPE,
    type,
    key,
    ref,
    props,
    _mark: 'wy set',
};
return element;
};
// jsx 方法
export const jsx = (type: ElementType, config: any, ...maybeChildren: any) => {
	let key: Key = null;
	const props: Props = {};
	const ref: Ref = null;
	// key 和 ref 是特殊的props
	for (const prop in config) {
            const val = config[prop];
            if (prop === 'key') {
                    if (val !== undefined) {
                            key = '' + val;
                    }
                    continue;
            }

            if (prop === 'ref') {
                    if (val !== undefined) {
                            ref = val;
                    }
                    continue;
            }
            // 确定config[prop]是config自带的,而不是原型上的
            if ({}.hasOwnProperty.call(config, prop)) {
                    props[prop] = val;
            }

            const childrenLen = maybeChildren.length;
            if (childrenLen) {
                    if (childrenLen === 1) {
                            props.children = maybeChildren[0];
                    } else {
                            props.children = maybeChildren;
                    }
            }
	}

	return ReactElement(type, key, ref, props);
};

export const jsxDEV = jsx;

创建shared

├── ReactSymbols.ts
├── ReactTypes.ts
└── package.json

ReactTypes.ts

先把类型暂时设置成any

export type Type = any;
export type Key = any;
export type Ref = any;
export type Props = any;
export type ElementType = any;

export interface ReactElement {
    $$typeof: symbol | number;
    type: ElementType;
    key: Key;
    ref: Ref;
    props: Props;
    _mark: string;
}

ReactSymbols.ts

const supportSymbol = typeof Symbol === 'function' && Symbol.for; // 判断是否支持symbol

export const REACT_ELEMENT_TYPE = supportSymbol
    ? Symbol.for('react.element')
    : 0xeac7;

代码地址

github.com/wangyanduod…