React one step at a time

Preparation environment:

  1. The node environment
  2. Vscode editor

Initialize the project

// Create a folder. You can also create a folder manually
mkdir my-react
// Go to the project directory
cd my-react
// Generate pakeage.json file, this file is mainly used to record the details of the project, it will be used in the project development package, as well as the details of the project record in the project
npm init Copy the code

Setting up the project environment

Since our goal is to implement a simple React, in order to focus more on React, we need some tools to help us deal with issues other than React.

  1. Webpack: We need to use Webapck to package our project and eventually generate a JS file
  2. Babel: helps us to translate the advanced ES syntax down to the lower version of the ES syntax that the browser recognizes

webpack

cnpm install --save-dev webapck webapck-cli
Copy the code

Then create a new webapck.config.js file in the root directory of our project to tell Webapck how to package our JS files

module.exports = {
  entry: './src/main.js'.};
Copy the code

Also create the SRC directory and create main.js as the entry file for the project

// main.js
const array = [1.2.3.4.5];
array.find((item) = > item === 1);
Copy the code

babel

Babel has a lot of packages to install

cnpm install --save-dev babel-loader @babel/core @babel/preset-env
Copy the code
  1. Babel-loader: When using babel-loader to process JS files, the syntax above ES5 will be escaped
  2. @babel/core: encapsulates the API used by babel-loader
  3. @babel/preset-env: Babel goes through three steps of “parse-transform – preset” internally. while@babel/coreThe library is responsible for “parsing,” and the specific “transformation” and “generation” steps are left to various plugins and preset

Tips1: The @babel prefix is used to declare scope

Tips2: @babel/preset-* is actually a package of various plug-ins, i.e., a uniform setting of various translation rules, to tell loader which rule to convert to the corresponding JS version

Ok, back to our project itself, we need to tell Webapck to use babel-loader to package our JS files and the corresponding configuration of babel-Loader.

module.exports = {
  entry: {
    main: "./src/main.js".  },
  module: {
 rules: [  {  test: /\.js$/. use: {  loader: 'babel-loader'. options: {  presets: ["@babel/preset-env"]. },  },  }, ]. }, }; Copy the code

First package compilation

Execute NPX webpack on the terminal to view the packaged file under the Dist file

Tips: Using NPX ensures that we are executing the current project

my-react
└ ─ ─ ─ dist│ │ main. Js└ ─ ─ ─ the SRC│ │ main. Js└ ─ ─ ─ package. Json| └ ─ ─ ─ webpack. Config. JsCopy the code

The Babel plug-in was introduced to support JSX syntax

Now let’s try declaring a different variable in main.js and then execute NPX webpack

const array = [1.2.3.4.5];

array.find((item) = > item === 1);

const ele = <div id="id" class="mr5" >  <span> zaoren </span> </div>; console.log(ele); Copy the code

We saw an error because we could not parse the JSX syntax

Therefore, we introduced another Babel plugin to help us parse JSX syntax – @babel/plugin-transform-react-jsx

cnpm install --save-dev @babel/plugin-transform-react-jsx
Copy the code

Then introduce the plugin in our webapck.config.js

{
    test: /\.js$/.    use: {
      loader: 'babel-loader'.      options: {
 presets: ["@babel/preset-env"]. plugins: ['@babel/plugin-transform-react-jsx']  },  },  }, Copy the code

Then use Webapck to package, found no error, packaging success!

Then we tried importing our packaged main.js with a main.html

<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
 <title>Document</title> </head> <body>  <script src="./main.js"></script> </body> </html> Copy the code

But when we run it in the browser, we get an error

Yi? React is undefined. What is the theme of this article? Implement a simple React. So, for now, we’re not going any further with tools to help simplify our workload. Totally on my own!!

Let’s start writing React

As you can see from the packaged code, first we need a React variable, whose createElement method takes three arguments

  1. DOM node type
  2. A property object on a DOM node
  3. Children on DOM

Let’s simply implement the React object and mount the created DOM object to the body of the HTML page

// main.js
let React = {
  createElement: (tagName, attributes, ... children) = > {
    let ele =  document.createElement(tagName);
      
 Object.keys(attributes || {}).forEach(key= > {  ele.setAttribute(key, attributes[key]);  });   children.forEach(child= > {  ele.appendChild(child);  })   return ele;  }, };  const ele = <div id="id" style="background: red" >  <span>zaoren1</span>  <span>zaoren2</span> </div>;  document.body.appendChild(ele);  Copy the code

After executing NPX webpack, we opened the browser and found an error!


After debugging, we found that the t is the text “zaoren”, and the native Web API createElement method does not support adding a text node, so we need to use createTextNode method (see MDN for details).


Therefore, when creating a child node, it is necessary to determine whether it is a text node.

children.forEach(child= > {
  if (typeof child === "string") {
    child = document.createTextNode(child);
  }
  ele.appendChild(child);
}) Copy the code

Re-npx webpack to see the effectYou can see ours<div>Child nodes<span>And some of our properties can be set successfully! Congratulations, you have completed the first step!

React doesn’t have the ability to handle events. You can filter function attributes and add event listeners.

. Omit the partObject.keys(attributes || {}).forEach(key= > {
  if (key.match(/^on/)) {
    let eventType = key.replace(/^on/.' ').toLocaleLowerCase();
    ele.addEventListener(eventType, attributes[key]);
 return  }  ele.setAttribute(key, attributes[key]); });  . Omit the partconst ele = <div id="id" style="background: red" >  <span onClick={()= >{console.log('add event success! ')}}>zaoren1</span>  <span>zaoren2</span> </div>; Copy the code

Click on Zaoren1 to see that we have successfully added the Click event!

Project source code

This article is formatted using MDNICE