如果不清楚JSX是如何转换的,请移步https://www.yuque.com/linhe-8mnf5/fxyxkm/mtt8ho
一、环境搭建
1.使用npm init初始化环境
这个应该都会!!!
2.配置webpack
1.安装插件,配置webpack build命令:”build”: “webpack”
// package.json文件
{
"name": "mini-react",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@babel/core": "^7.13.8",
"@babel/plugin-transform-react-jsx": "^7.12.17",
"@babel/preset-env": "^7.13.9",
"babel-loader": "^8.2.2",
"webpack": "^5.24.3",
"webpack-cli": "^4.5.0"
}
}
2.创建webpack.config.js文件,具体配置如下:
// webpack.config.js
module.exports = {
entry: {
main: './main.js'
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-react-jsx']
}
}
}
]
},
mode: "development",
optimization: {
minimize: false
}
}
二、实现过程
1.在根目录下创建main.js文件,写入jsx代码
const a = <div id="a" class="c">
<div>abc</div>
<div></div>
<div></div>
</div>
此时目录结构
2.运行命令:npm run build
此时已经生成构建文件。
3.引入main文件查看效果
我们在dist文件夹下创建一个html文件,引入main.js文件
// index.html
<body></body>
<script src="./main.js"></script>
此时目录结构
打开html查看一下效果,我们发现webpack构建成功了,JSX也被转换成React.createElement方法了,我们今天的目标就是实现这么一个方法。
4.代码实现
在webpack修改下插件,使React.createElement方法转换成lin方法
plugins: [['@babel/plugin-transform-react-jsx', { pragma: 'lin' }]]
目标使用lin方法来创建出真实的dom,然后渲染到页面
编写代码
function lin(tagName, attributes, ...children) {
// 第一个参数直接创建,创建出dom节点
let e = document.createElement(tagName)
// 设置属性,attributes是对象
for (let p in attributes) {
e.setAttribute(p, attributes[p])
}
// 遍历子节点
for (let child of children) {
// child是字符串类型,说明是文本
if (typeof child === 'string') {
child = document.createTextNode(child)
}
//添加到创建的节点上
e.appendChild(child)
}
return e
}
// 通过lin方法转换成真实dom
const a = <div id="a" class="c">
<div>abc</div>
<ul>
<li>123</li>
<li>456</li>
</ul>
</div>
// 页面渲染
document.body.appendChild(a)
重新构建npm run webpack查看效果。结合图片好好理解一下代码,不难。
页面结构