如果不清楚JSX是如何转换的,请移步https://www.yuque.com/linhe-8mnf5/fxyxkm/mtt8ho

一、环境搭建

1.使用npm init初始化环境

这个应该都会!!!

2.配置webpack

1.安装插件,配置webpack build命令:”build”: “webpack”

  1. // package.json文件
  2. {
  3. "name": "mini-react",
  4. "version": "1.0.0",
  5. "description": "",
  6. "main": "main.js",
  7. "scripts": {
  8. "build": "webpack",
  9. "test": "echo \"Error: no test specified\" && exit 1"
  10. },
  11. "author": "",
  12. "license": "ISC",
  13. "dependencies": {
  14. "@babel/core": "^7.13.8",
  15. "@babel/plugin-transform-react-jsx": "^7.12.17",
  16. "@babel/preset-env": "^7.13.9",
  17. "babel-loader": "^8.2.2",
  18. "webpack": "^5.24.3",
  19. "webpack-cli": "^4.5.0"
  20. }
  21. }

2.创建webpack.config.js文件,具体配置如下:

  1. // webpack.config.js
  2. module.exports = {
  3. entry: {
  4. main: './main.js'
  5. },
  6. module: {
  7. rules: [
  8. {
  9. test: /\.js$/,
  10. use: {
  11. loader: 'babel-loader',
  12. options: {
  13. presets: ['@babel/preset-env'],
  14. plugins: ['@babel/plugin-transform-react-jsx']
  15. }
  16. }
  17. }
  18. ]
  19. },
  20. mode: "development",
  21. optimization: {
  22. minimize: false
  23. }
  24. }

二、实现过程

1.在根目录下创建main.js文件,写入jsx代码

  1. const a = <div id="a" class="c">
  2. <div>abc</div>
  3. <div></div>
  4. <div></div>
  5. </div>

此时目录结构
image.png

2.运行命令:npm run build

image.png

此时已经生成构建文件。
image.png

3.引入main文件查看效果

我们在dist文件夹下创建一个html文件,引入main.js文件

  1. // index.html
  2. <body></body>
  3. <script src="./main.js"></script>

此时目录结构
image.png

打开html查看一下效果,我们发现webpack构建成功了,JSX也被转换成React.createElement方法了,我们今天的目标就是实现这么一个方法。

image.png

4.代码实现

在webpack修改下插件,使React.createElement方法转换成lin方法

  1. plugins: [['@babel/plugin-transform-react-jsx', { pragma: 'lin' }]]

image.png

目标使用lin方法来创建出真实的dom,然后渲染到页面

编写代码

  1. function lin(tagName, attributes, ...children) {
  2. // 第一个参数直接创建,创建出dom节点
  3. let e = document.createElement(tagName)
  4. // 设置属性,attributes是对象
  5. for (let p in attributes) {
  6. e.setAttribute(p, attributes[p])
  7. }
  8. // 遍历子节点
  9. for (let child of children) {
  10. // child是字符串类型,说明是文本
  11. if (typeof child === 'string') {
  12. child = document.createTextNode(child)
  13. }
  14. //添加到创建的节点上
  15. e.appendChild(child)
  16. }
  17. return e
  18. }
  19. // 通过lin方法转换成真实dom
  20. const a = <div id="a" class="c">
  21. <div>abc</div>
  22. <ul>
  23. <li>123</li>
  24. <li>456</li>
  25. </ul>
  26. </div>
  27. // 页面渲染
  28. document.body.appendChild(a)

重新构建npm run webpack查看效果。结合图片好好理解一下代码,不难。
image.png

页面结构
image.png