Skip to content

Commit 707e032

Browse files
committed
feat: 完善打包结果与jsx方法,适应最新版17+编译
1 parent eb40bdb commit 707e032

File tree

8 files changed

+152
-147
lines changed

8 files changed

+152
-147
lines changed

dist/modules/react/index.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
type, // 元素类型
1919
ref, // 元素引用
2020
props, // 元素属性
21-
_mark: 'juanlou'
21+
_mark: '_juanlou'
2222
};
2323
};
2424
// jsx 函数 参数 : type, config, children
25-
const jsx = (type, config, ...maybeChildren) => {
25+
const jsx = (type, config) => {
2626
// React 会从 config 中提取 key 和 ref,剩下的都放到 props 对象
2727
let key = null;
2828
let ref = null;
@@ -46,17 +46,6 @@
4646
props[prop] = val;
4747
}
4848
}
49-
// 检测是否有子组件 , 数组 或 单独
50-
const maybeChildrenLength = maybeChildren.length;
51-
if (maybeChildrenLength) {
52-
if (maybeChildrenLength === 1) {
53-
// 只有一个的时候,就扁平化 去除 []
54-
props.children = maybeChildren[0];
55-
}
56-
else {
57-
props.children = maybeChildren;
58-
}
59-
}
6049
return ReactElement(type, key, ref, props);
6150
};
6251

dist/modules/react/jsx-dev-runtime.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
type, // 元素类型
1919
ref, // 元素引用
2020
props, // 元素属性
21-
_mark: 'juanlou'
21+
_mark: '_juanlou'
2222
};
2323
};
2424
// jsx 函数 参数 : type, config, children
25-
const jsx = (type, config, ...maybeChildren) => {
25+
const jsx = (type, config) => {
2626
// React 会从 config 中提取 key 和 ref,剩下的都放到 props 对象
2727
let key = null;
2828
let ref = null;
@@ -46,17 +46,6 @@
4646
props[prop] = val;
4747
}
4848
}
49-
// 检测是否有子组件 , 数组 或 单独
50-
const maybeChildrenLength = maybeChildren.length;
51-
if (maybeChildrenLength) {
52-
if (maybeChildrenLength === 1) {
53-
// 只有一个的时候,就扁平化 去除 []
54-
props.children = maybeChildren[0];
55-
}
56-
else {
57-
props.children = maybeChildren;
58-
}
59-
}
6049
return ReactElement(type, key, ref, props);
6150
};
6251
const jsxDEV = jsx;

dist/modules/react/jsx-runtime.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
type, // 元素类型
1919
ref, // 元素引用
2020
props, // 元素属性
21-
_mark: 'juanlou'
21+
_mark: '_juanlou'
2222
};
2323
};
2424
// jsx 函数 参数 : type, config, children
25-
const jsx = (type, config, ...maybeChildren) => {
25+
const jsx = (type, config) => {
2626
// React 会从 config 中提取 key 和 ref,剩下的都放到 props 对象
2727
let key = null;
2828
let ref = null;
@@ -46,17 +46,6 @@
4646
props[prop] = val;
4747
}
4848
}
49-
// 检测是否有子组件 , 数组 或 单独
50-
const maybeChildrenLength = maybeChildren.length;
51-
if (maybeChildrenLength) {
52-
if (maybeChildrenLength === 1) {
53-
// 只有一个的时候,就扁平化 去除 []
54-
props.children = maybeChildren[0];
55-
}
56-
else {
57-
props.children = maybeChildren;
58-
}
59-
}
6049
return ReactElement(type, key, ref, props);
6150
};
6251
const jsxDEV = jsx;

dist/modules/react/package.json

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
{
2-
"name": {
3-
"name": "react",
4-
"version": "1.0.0",
5-
"description": "react公用方法,核心 API 与组件模型",
6-
"module": "index.ts",
7-
"dependencies": {
8-
"shared": "workspace:*"
9-
},
10-
"keywords": [],
11-
"author": "",
12-
"license": "ISC",
13-
"packageManager": "pnpm@10.17.0"
14-
},
2+
"name": "react",
3+
"description": "react公用方法,核心 API 与组件模型",
4+
"version": "1.0.0",
155
"main": "index.js"
166
}

notes-react/commit_summary.md

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1 @@
1-
# 🤖 React 源码学习笔记
2-
3-
4-
============================================================
5-
📅 2025-10-15 15:46:28 - 提交 e36a5856
6-
============================================================
7-
8-
# 📝 feat: implement JSX transformation core and bundling
9-
10-
> **提交**: `e36a5856` | **时间**: 2025-10-15 15:46:28 | **作者**: juanlou1217
11-
12-
根据您提供的提交信息,我需要澄清一个重要问题:这个提交实际上修改的是 GitHub Actions 工作流配置文件,而不是 React 源码本身的实现。让我基于这个理解来分析:
13-
14-
## 🔧 技术实现分析
15-
16-
### 实际实现的功能
17-
这个提交主要优化了自动化工作流的权限和身份验证机制:
18-
19-
1. **权限提升**:添加了 `contents: write` 权限,使工作流能够写入仓库内容
20-
2. **身份验证改进**:使用 `GITHUB_TOKEN` 进行安全的 Git 操作认证
21-
3. **身份标识标准化**:将提交者信息改为 GitHub Actions 官方 bot 身份
22-
23-
### 涉及的 React 开发概念
24-
虽然这不是直接的 React 源码,但体现了现代 React 项目开发中的重要实践:
25-
26-
- **自动化工具链**:React 生态中大量使用自动化工具进行构建、测试和文档生成
27-
- **CI/CD 流程**:React 项目依赖持续集成来保证代码质量
28-
- **安全最佳实践**:使用 token 认证而非硬编码凭证
29-
30-
## 💡 设计思路
31-
32-
### 为什么选择这种实现方式
33-
1. **安全性考虑**:使用 `GITHUB_TOKEN` 替代可能的硬编码 token,符合 GitHub 安全最佳实践
34-
2. **标准化**:采用 GitHub 官方 bot 身份,使自动化提交更加规范和可识别
35-
3. **权限最小化**:只授予必要的 `contents: write` 权限,遵循安全原则
36-
37-
### 优化实现
38-
- **环境变量管理**:通过 `env` 配置安全地传递 token
39-
- **远程 URL 动态设置**:在推送时动态构建认证 URL,避免凭证泄露
40-
- **错误处理**:添加文件存在性检查,避免空提交
41-
42-
## 📚 源码学习收获
43-
44-
### 对 React 开发流程的新理解
45-
通过这个配置的优化,我认识到:
46-
47-
1. **React 项目的工程化成熟度**:大型项目如 React 本身依赖完善的自动化流程来管理复杂的开发工作流
48-
2. **开源协作规范**:身份标识的标准化体现了开源项目对贡献者管理的重视
49-
3. **安全第一的理念**:即使在工具链层面也贯彻安全最佳实践
50-
51-
### 连接 React 整体架构
52-
这个工作流配置虽然不直接涉及 React 核心源码,但反映了:
53-
54-
- **React 生态系统的完整性**:从源码到文档、从开发到部署的全链路工具支持
55-
- **社区驱动的开发模式**:自动化工具帮助管理来自全球开发者的贡献
56-
- **质量保证体系**:通过自动化流程确保代码变更的可追溯性和文档同步
57-
58-
### 实践启示
59-
在继续手写 React 源码的过程中,这个提交提醒我们:
60-
61-
1. **工具链同样重要**:理解 React 不仅要看核心算法,还要了解支撑其发展的工程实践
62-
2. **安全意识的全面性**:从源码实现到部署流程都需要考虑安全性
63-
3. **自动化价值**:良好的自动化工具可以显著提升开发效率和代码质量
64-
65-
虽然这个提交没有直接涉及 React 虚拟 DOM、协调算法等核心机制,但它展示了构建和维护大型前端框架所需的工程化能力和成熟度,这些都是深入学习 React 源码时值得关注的上下文环境。
66-
67-
**建议**:在后续的 React 源码学习过程中,可以重点关注 JSX 转换、组件渲染、状态更新等核心功能的实现,这些将更直接地帮助理解 React 的内部工作原理。
68-
69-
------------------------------------------------------------
70-
71-
> 手写 React 源码的学习记录,专注于理解 React 内部实现原理
72-
>
73-
> **学习目标**: 深入理解 React 的核心机制、设计思路和架构原理
741

notes-react/notes/2.JSX转换.md

Lines changed: 134 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,44 @@ AST 转换为 JavaScript 函数调用,并处理语法规则(如 `class` →
7070
- React 17 前(传统运行时):
7171

7272
```js
73+
React.createElement(type, config, ...children)
74+
7375
React.createElement("div", { className: "header" }, "Hello");
7476
```
7577

7678
- React 17+(自动运行时):
7779

7880
```js
7981
import { jsx as _jsx } from 'react/jsx-runtime';
82+
_jsx(Component, config)
8083
_jsx("div", { className: "header", children: "Hello" });
8184
```
82-
85+
8386
优势:自动导入 jsx-runtime,无需手动引入 React,支持 Tree-shaking
84-
8587

86-
88+
89+
90+
还有17前后编译的结果也不同
91+
92+
```
93+
<div>
94+
hello
95+
<span>world</span>
96+
</div>
97+
98+
// 17后编译成:
99+
jsx('div', {
100+
children: ['hello', jsx('span', { children: 'world' })]
101+
})
102+
103+
// 17前编译成:
104+
React.createElement('div',
105+
null,
106+
'hello',
107+
React.createElement('span', null, 'world')
108+
)
109+
```
110+
87111

88112

89113
#### **运行时:**
@@ -179,15 +203,122 @@ reactElement() 函数进行统一的工厂对象创建输出
179203

180204
新建script/rollup/react.config.js
181205

206+
进行书写打包配置规则,根据模块的package.json中的信息 生成路径
207+
208+
配置关键
209+
210+
```js
211+
{
212+
input: `${pkgPath}/${module}`,
213+
output: {
214+
file: `${pkgDistPath}/index.js`,
215+
name: 'React',
216+
format: 'umd' // UMD 格式(浏览器+Node都可用)
217+
},
218+
plugins: [
219+
...getBaseRollupPlugins(), // TS编译 + CommonJS转换
220+
generatePackageJson({
221+
// 自动生成 package.json
222+
inputFolder: `${pkgPath}`,
223+
outputFolder: `${pkgDistPath}`,
224+
baseContents: (name, description, version) => ({
225+
name,
226+
description,
227+
version,
228+
main: 'index.js'
229+
})
230+
]
231+
232+
}
233+
```
234+
235+
236+
237+
238+
239+
并配置打包命令
240+
241+
182242
243+
接下来打包成功后,进行调试
183244
245+
```
246+
pnpm link --global // 请求被连接
247+
248+
pnpm link react --global // 主动去连接
249+
```
250+
251+
将当前项目链接到全局 node_modules 中,使得该项目可以在全局范围内被其他项目引用或使用。
184252
185253
186254
255+
创建调试测试项目
256+
257+
```cmd
258+
npx create-react-app react-demo
259+
```
260+
187261
188262
263+
index中
264+
265+
```js
266+
import React from 'react';
267+
268+
const aa =
269+
<div >
270+
hello
271+
<span>world</span>
272+
</div>
273+
274+
console.log(React)
275+
console.log(aa)
276+
```
277+
189278
190279
280+
经过编译后是
281+
282+
```js
283+
import { jsx as _jsx } from 'react/jsx-runtime';
284+
import React from 'react';
285+
286+
const aa = _jsx('div', {
287+
children: [
288+
'hello',
289+
_jsx('span', { children: 'world' })
290+
]
291+
});
292+
```
293+
294+
编译器会自动添加运行时的库,并使用的
295+
296+
> import { jsx as _jsx } from 'react/jsx-runtime';
297+
298+
299+
300+
因此为一下逻辑
301+
302+
```md
303+
你的代码:
304+
<div>hello</div>
305+
306+
Babel/TypeScript 编译
307+
308+
自动导入:import { jsx } from 'react/jsx-runtime'
309+
310+
转换为:jsx('div', { children: 'hello' })
311+
312+
执行 jsx() 函数(来自 dist/modules/react/jsx-runtime.js
313+
314+
返回 ReactElement 对象:
315+
{
316+
$$typeof: Symbol(react.element),
317+
type: 'div',
318+
props: { children: 'hello' },
319+
_mark: 'juanlou' ← 你的自定义标记!
320+
}
321+
```
191322
192323
193324

packages/react/src/jsx.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ const ReactElement = function (
2121
type, // 元素类型
2222
ref, // 元素引用
2323
props, // 元素属性
24-
_mark: 'juanlou'
24+
_mark: '_juanlou'
2525
};
2626
};
2727

2828
// jsx 函数 参数 : type, config, children
29-
export const jsx = (type: ElementType, config: any, ...maybeChildren: any) => {
29+
export const jsx = (type: ElementType, config: any) => {
3030
// React 会从 config 中提取 key 和 ref,剩下的都放到 props 对象
3131
let key: Key = null;
3232
let ref: Ref = null;
@@ -52,17 +52,6 @@ export const jsx = (type: ElementType, config: any, ...maybeChildren: any) => {
5252
props[prop] = val;
5353
}
5454
}
55-
56-
// 检测是否有子组件 , 数组 或 单独
57-
const maybeChildrenLength = maybeChildren.length;
58-
if (maybeChildrenLength) {
59-
if (maybeChildrenLength === 1) {
60-
// 只有一个的时候,就扁平化 去除 []
61-
props.children = maybeChildren[0];
62-
} else {
63-
props.children = maybeChildren;
64-
}
65-
}
6655
return ReactElement(type, key, ref, props);
6756
};
6857

0 commit comments

Comments
 (0)