Recently learning react.js, I found that the configuration of the project framework is basically the same except for the different JS libraries (vue. Js and react.js)

Vue Project Framework (PART 1)

The Framework of the VUE Project (Part 2)

React With Your Bare hands

React Project Framework (Part 2)

First, preparation

1. Create the reactProject folder

Go to the root directory and initialize the project

cdReactProject NPM init -y // -y is the default configurationCopy the code

The package.json file appears in the directory

2. Create a project structure

Create a new SRC folder under the root directory, and temporarily create a js file named index under SRC as the entry file

Create an index.html file in the root directory as the entry page

3. Use webpack

When you download Webpack, you may have problems downloading WebPack-CLI indefinitely because you didn’t install WebPack and Webpack-CLI globally first

// WebPack4. X start Webpack-CLI is brought out as a standalone package
Webpack-cli must be downloaded at the same time as webpack, and must be downloaded at the same time otherwise an error will be reported because the version does not match
cnpm install webpack-cli webpack --save-dev
Copy the code

Webpack can only pack JS modules by default, it can pack multiple JS modules you write into a SINGLE JS file, and finally introduce it in the entry page

Webpack4 starts out larger than configuration by default, in other words it doesn’t have to introduce a configuration file to package the project, so it has a lot of defaults

The default entry file is index.js from SRC, and the output is main.js from dist (it will be created automatically if there is no dist).

However, it is still highly configured, if necessary we can just create webpack.config.js in the project root directory to configure everything

Compared to previous versions of Webpack4, there is a mode option for configuration items with the option of “development” or “production” (the default). The difference is that development packages output files that are not compressed versions

4. Use the react. Js

React differs from Vue in that React uses two packages to work together

  • React package: Responsible for components or virtual DOM
  • The React – DOM package is responsible for inserting components or virtual DOM into the root node
cnpm install react react-dom --save-dev
Copy the code

The index of js

// index.js
import React from 'react'
// The package name must be written like this
import ReactDOM from 'react-dom'
/* *createElement: Creates a virtual DOM element * the first parameter is the tag type * the second parameter is the tag attribute object * the remaining parameters are child nodes */
const dom = React.createElement("h1", {id: "test"},"hello react")
// The render function inserts the virtual DOM into the Target container
ReactDOM.render(
    dom,
    document.getElementById("root"))Copy the code

index.html

//  index.html
<div id ="root"></div>
Copy the code

The page displays the words hello React, with the following review element

<div id="root"><h1 id="test">hello react</h1></div>
Copy the code

This means that our preparations have been successfully completed

Second, improve the functions of the framework

1. Use the webpack – dev server. –

Every time something new is written, it must be packaged using WebPack in order to see the effect, and we prefer it to be packaged and compiled automatically when the code changes

Webpack-dev-server can do that for us!

Download a.
cnpm i webpack-dev-server --save-dev
Copy the code
B. the use of

We cannot use the webpack-dev-server command as we would use the webpack command, because webpack-dev-server is locally installed, and only globally installed packages can be used in the command line. We need to configure scripts using package.json

// package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."dev": "webpack-dev-server --hot"
},
Copy the code

Then use NPM run dev on the command line

npm run dev
Copy the code

Note the code excerpt below

NPM run dev > [email protected] dev C:\myProject\reactProject > webpack-dev-server I "WDS" : Project is running at http://localhost:8080/ I "WDS" : Webpack output is served from/I "WDS" : Content Not from Webpack is served from C:\myProject\reactProject I "WDM" : Hash: e70fb3AE9BF074915CAD Version: Webpack 4.35.0Copy the code

From here we know two things: first, our project is running on native port 8080, and second, webpack’s output is in the root directory, so remember to change the path in index.html to main.js, otherwise you won’t see the new effects

But we don’t see the file in the root directory, because it’s in memory (which makes it faster to read and write), not on disk, and we can change the port and even open the browser automatically after compiling

The specific configuration can be the devServer item in WebPack

devServer:{
    host: '127.0.0.1',
    port: 8081,
    open: true
}
Copy the code

It can also be in the CLI, which is the most violent way, but the ports are still in devServer for later project configuration

// package.json
"scripts": {
    "dev": "webpack-dev-server --open --port 30000"
},
Copy the code

2. Use HTML – webpack – the plugin

Since putting main.js in memory can speed up reading and writing, can putting pages in memory speed up reading and writing even more?

The answer is yes! This can be done using the HTML-webpack-plugin

Download a.
cnpm i html-webpack-plugin --save-dev
Copy the code
B. the use of
// webpack.config.js
const htmlWebpackPlugin = require('html-webpack-plugin')... plugins: [new htmlWebpackPlugin({
      template: path.join(__dirname, "./index.html"),
      filename: "index.html"})].Copy the code

The above code generates an index. HTML file in memory based on the index. HTML file on disk. When we check the page in the browser, we find that there is an extra script tag

// index.html
<body>
    <div id="app"></div> <! Delete or comment out <script SRC ="./main.js"></script> -->
</body>
Copy the code

Now it can run on its own and automatically listen for changes

Third, continue to improve the framework (project) function

1. Use JSX syntax

While it works perfectly, writing the React virtual DOM like above always feels complicated. As front-end engineers, we would prefer to write the DOM like this and insert it as before

const dom = <h1 id="test">hello react</h1>
ReactDOM.render(
    dom,
    document.getElementById("root"))Copy the code

React babel-loader is the only way to use the react extension JSX syntax

Download a.

Based on my experience in the previous article, I found that if I download babel-loader now, it is better to use the following form, because Babel has been updated to 7.x.x and is written quite differently from the previous version, otherwise I will always get some version incompatibility errors

CNPM i@babel /core babel-loader --save-dev // download plugin CNPM i@babel /plugin-transform-runtime --save-dev // download default  cnpm i @babel/preset-env @babel/preset-react --save-devCopy the code
B. the use of

Two ways to use Babel have been described before, but here are a few more simple ways to use Babel

First, configure babel-loader in rules and provide options

// The first way. // Except for the basic configurationtest// Presets are default Babel syntax conversion rules. // Plugins are used to specify which plugins to use. Module: {rules: [{test: /\.js|jsx$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"."@babel/preset-react"],
            plugins: ["@babel/plugin-transform-runtime"]}}}]},Copy the code

The second method is to create a. Babelrc file in the same format as JSON

{
    presets: ["@babel/preset-env"."@babel/preset-react"],
    plugins: ["@babel/plugin-transform-runtime"} // It will automatically recognize the file // delete the options in the first methodCopy the code

The third method adds the Babel node to package.json

{
  "name": "my-package"."version": "1.0.0"."babel": {
    "presets": ["@babel/preset-env"."@babel/preset-react"]."plugins": ["@babel/plugin-transform-runtime"]}}Copy the code

Babelrc.js is the same configuration as before, but can be written in JS

const presets = ["@babel/preset-env"."@babel/preset-react"];
const plugins = ["@babel/plugin-transform-runtime"]; // The nice thing about this is that you can call the Node APIif (process.env["ENV"= = ="prod") { plugins.push(...) ; } module.exports = { presets, plugins };Copy the code

There are also cli methods, or the option to convert babel.confog.js to node_modules, but these are more complicated or less popular

2. Use style sheets

Create a new CSS style sheet folder under SRC, write your own style for your component, and then import it in the JSX files you need, as I did

/* CSS /index.css file */
.test{
    color: green   
}
Copy the code
// Introduce styles in the index.jsx file
import React from "react";
import "@/css/index.css"

export default function Index() {
    return <div className="test" id="index">index page</div>;
}

// No styles are introduced in login. JSX, but classes are added
import React from "react";

export default class Login extends React.Component {
  render() {
  // Since class is the js keyword, JSX uses className as the HTML class
    return <div className="test">login page</div>; }}Copy the code

An error message is displayed, prompting you to use the appropriate loader

Like VUE, you must use loader to use stylesheets because they are generated by JSX syntax and JSX cannot parse stylesheets

Download a.
cnpm i style-loader css-loader --save-dev
Copy the code
B. the use of

After downloading, configure the file like the VUE project

rules: [
    ...
    {
        test: /\.css$/,
        use: ["style-loader"."css-loader"]}]Copy the code
C. the problem

Although you can use styles at this point, you’ll notice that the Login component page where you didn’t introduce styles is also green

Fortunately, CSS-Loader can provide modularity, so we only need to make the following changes

rules: [
    ...
    {
        test: /\.css$/, //"style-loader"."css-loader? modules"]}]Copy the code

At this point we need a parameter to accept the CSS exposed module (this is of course the csS-loader’s function).

// Introduce styles in the index.jsx file
import React from "react";
import indxCss from "@/css/index.css"
console.log(indxCss) // => {test: "q7KCiLIWvHKVJp6HMfV2y"}
export default function Index() {
    return <div className={indxCss.test} id="index">index page</div>;
}
Copy the code

It’s also interesting to note that csS-loader has a lot more parameters than modules. If you don’t like random strings as style identifiers, you can set the localIdentName parameter, which is a combination of the following

  • Path: indicates the file path
  • Name: indicates the file name
  • Local: style name
  • Hash: 32 hash value, the length can be defined later
rules: [
    ...
    {
        test: /\.css$/ I, // Use: /\.css$/ I, //"style-loader"."css-loader? modules"Use: [{loader: 3.0.0);"style-loader" },
          {
            loader: "css-loader",
            options: {
              modules: {
                localIdentName: "[path][name]-[local]-[hash:base64:5]"}}}]}]Copy the code

Although it looks perfect now, the problem is that if we introduce a third-party library now, it will also be A CSS file and will be modularized, but we want it to be globally valid, it is better for the third-party library to use CSS style, and your style will be SCSS or LESS enabled, so you have to install their loader

cnpm i less-loader --save-dev
Copy the code

Add the loader

rules: [
    ...
    {
        test: /\.css$/,
        use: ["style-loader"."css-loader"] {},test: /\.less$/i,
        use: [
          { loader: "style-loader" },
          {
            loader: "css-loader",
            options: {
              modules: {
                localIdentName: "[path][name]-[local]-[hash:base64:5]"
              }
            }
          },
          {loader: "less-loader"}}]]Copy the code

3. Use pictures

If you add the following style to the style

.test{ background-image: url(.. /imgs/11.jpg) }Copy the code

JSX can’t handle image urls either, so add loader to handle these

Download a.

Url-loader uses file-loader internally, so both loaders need to be downloaded at the same time

cnpm i url-loader file-loader --save-dev
Copy the code
B. the use of

The basic usage is as follows

module: {
    rules: [
        ...
        {
            test: /\.(png|jpe? g|gif|svg|eot|ttf|woff|woff2)$/, loader:"url-loader"}},Copy the code
c.options

This is the same as the CSS-loader setup

 module: {
    rules: [
      {
        test: /\.(jpg|png|jpeg)$/,
        loader: "url-loader",
          options: {
            limit: 8000, // Trigger the following setting name when the file byte size exceeds the limit:"[hash:8]-[name].[ext]"// This is an eight-bit hash code before the original name and suffix}}]},Copy the code

Four, conclusion

At present, basic functions are available, but they are still not perfect. In the next phase, React-Router will be introduced to encapsulate services. At present, both vUE project framework and React framework have great similarities. Learning React from VUE is much easier, and the understanding of VUE from React is also improved to a higher level.

I’m sure you’ll feel the same way if you do this

Endeavor, struggle