Build a React-hooks project from scratch

  • The react, Redux,typescript project will be configured from webpack, and the configuration of the project will be recorded in real time
  • Start with a basic WebPack environment

Webpack project construction

  • On the front base, the computer has the Node environment installed and can use the NPM tool
  • Create a new folder, name the project name (react-admin), go to the folder, use NPM init, and make sure to generate package.json along the way
  • To install webpack, run the NPM I webpack webpack-cli webpack-dev-server command
  • After the installation dependency is complete, the basic configuration of Webpack needs to be carried out. We build the webpack.config.js file in the root directory to configure Webpack
  • Then create an index.js entry file in the root directory. We construct the index.js entry file as follows
function a(number){
  console.log(number)
}
a(12)
Copy the code
  • Then we start to configure our Webpack. Webpack needs to configure the entry and output positions, corresponding to the entry and output attributes respectively
  • Entry can accept a string as the file path for the main entry, but can only be used for single-entry items. You can also receive an object as an entry file path, as shown below
  • Output which used to describe the file should be on the packaging, what is the name, there are two basic properties, one is the file name after packaging, one is the file path after the packaging, we here by [name]. Js to get his name in the corresponding entry file and generate a file name, if the string is a single entry and directly use the specified file path, For example, entry: ‘./index.js’, the final file name will be main.js. If the entry property is set as an object, such as Entry: {app: ‘./index.js’}, the final generated file will be the corresponding key app.js. The path uses path.resolve() to generate the dist folder in the root directory and put the packaged files there
const path = require('path') // The Node environment comes with no download required
// single entry file
module.exports = {
  entry: './index.js'.// The entry is index.js
  output: {  Dist /main.js
    filename: '[name].js'.path: path.resolve(__dirname, 'dist')}}// Multi-entry file
module.exports = {
  entry: { // The entry is also index.js
    app: './index.js'
  }, 
  output: {  Dist /app.js
    filename: '[name].js'.path: path.resolve(__dirname, 'dist')}}Copy the code
  • Json: “webpack –config webpack.config.js”, “webpack –config webpack.config.js”
  • You can then execute NPM run start to see that the packaging process is performed and the dist folder is generated
  • Here we have completed the basic configuration, but there is a problem, when we modify the entry corresponding to the file name, to implement the packaging, will find before packaging file exists, it will lead to our dist folder will contain a lot of packaging has nothing to do with the current code of the file before, so it doesn’t really friendly for our project, Here we want to remove dist and regenerate it every time we pack
  • The clean-webpack-plugin plugin can help us achieve this requirement by downloading the package NPM I clean-webpack-plugin-d
  • We then configure it in webpack.config.js, as follows. Plugins are used to configure the plugins we want, and receive an array of values so that our project can empty dist before each package so that there are no useless files in it
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  entry: {
    app: './index.js'
  },
  output: {
    filename: '[name].js'.path: path.resolve(__dirname, 'dist'),
    chunkFilename: '[name].bundle.js'
  },
  plugins: [
    new CleanWebpackPlugin()
  ]
}
Copy the code
  • We will use JSX or ES6 syntax in react development. These syntax are not compatible with older browsers, so we need to configure Babel to be compatible with older browsers
  • Here we need to download babel-loader @babel/preset-env(preset code according to the environment) @babel/preset-react @babel/preset-polyfill(Babel only converts new JavaScript syntax by default, but not new apis, for exampleIterator,Generator,Set,Maps,Proxy,Reflect,Symbol,PromiseAnd some methods defined on global objects (e.gObject.assign) will not transcode. while@babel/preset-polyfillTranscoding is possible.) @babel/proposal-object-rest-spread @babel/proposal-object-rest-spread @babel/proposal-object-rest-spread After downloading, you need to configure Babel
  • We build the.babelrc file in the root directory with the following configuration inside
{
  "presets": [
    "@babel/preset-env"."@babel/preset-react"]."plugins": [
    "@babel/proposal-object-rest-spread".// Handle the rest writing of the object
    "@babel/proposal-class-properties" // Handle arrow function bindings, static properties, etc]}Copy the code
  • Then you need to configure the compilation rules in webpack, again in webpack.config.js, add the module, add the different file parsing rules, as follows
module.exports = {
  entry: {
    app: './index.js'
  },
  output: {
    filename: '[name].js'.path: path.resolve(__dirname, 'dist'),
    chunkFilename: '[name].bundle.js'
  },
  module: {
    rules: [{test: /\.(js)x? $/.use: ['babel-loader'].exclude: /node-modules/ // files in node_modules are not parsed}},plugins: [
    new CleanWebpackPlugin()
  ]
}

Copy the code
  • Create an index. HTML file for dom display, index. JSX file for react mount, and SRC file for react components and their internal logic. And create a new app.jsx to do the initial component, the code is as follows
// index.html<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, Initial =1.0"> <title>Document</title> </head> <body> <div id="app"></div> <script SRC ="./dist/app.js"></script> <script src="./dist/test.js"></script> </body> </html>Copy the code
// index.jsx
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import App from './src/app.jsx'
ReactDOM.render(
  <App/>
  ,document.querySelector('#app'))Copy the code
// app.jsx
import * as React from 'react'
class App extends React.Component{
  render(){
    return (
      <div>123</div>)}}export default App

Copy the code
  • Then we need to add a new entry file to our WebPack configuration, as we did in HTML, called Test, and configure it as follows
module.exports = {
  entry: {
    app: './index.js'.test: './index.jsx'},.../ / to omit
}
Copy the code
  • Next, execute NPM run start to perform packaging. After packaging, open the page index.html to check and find that 123 has been inserted
  • Here we can see that we need to create a new index.html file and then actively import it based on the generated file path. It would be very troublesome to generate a large number of files, so we will use the plug-in to generate it automatically
  • First download the html-webpack-plugin, NPM I html-webpack-plugin
  • This is then configured in webpack.config.js, again in the plugins module, as shown below
const path = require('path')
const webpack = require('webpack')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HTMLWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: {
    app: './index.js'.test: './index.jsx'
  },
  output: {
    filename: '[name].js'.path: path.resolve(__dirname, 'dist'),
    chunkFilename: '[name].bundle.js'
  },
  module: {
    rules: [{test: /\.(js)x? $/.use: ['babel-loader'].exclude: /node-modules/}},plugins: [
    new HTMLWebpackPlugin({
      inject: true.// All js scripts are placed after the body
      hash: true.// Generate hash for static resources for clear caching
      cache: true.// Issue files only when they are changed
      title: 'react admin'.filename: 'index.html'.template: path.resolve(__dirname, 'index.html'),
      minify: {
        collapseWhitespace: true.// Fold white space
        removeComments: true.// Delete comments
        removeRedundantAttributes: true.removeScriptTypeAttributes: true.removeStyleLinkTypeAttributes: true}}),new CleanWebpackPlugin()
  ]
}
Copy the code
  • Then place our template index.html in the root directory, without actively importing the JS file, as follows
// index.html<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, React admin</title> </head> <body> <div id="app"></div> </body> </ HTML >Copy the code
  • We then execute our NPM run start to automatically generate our index. HTML file in Dist and open it to see that we already have the content we want to render
  • React configuration is complete. Next, we need to configure the CSS, using less as an example in development
  • Install the dependent less-loader style-loader postCSs-loader autoprefixer. The command is NPM I less-loader style-loader postcss-loader css-loader autoprefixer -d
  • Next, the WebPack configuration handles parsing and processing of less files
  • Again, configure the rules in rules under Module as follows
const path = require('path')
const webpack = require('webpack')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HTMLWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: {
    app: './index.js'.test: './index.jsx'
  },
  output: {
    filename: '[name].js'.path: path.resolve(__dirname, 'dist'),
    chunkFilename: '[name].bundle.js'
  },
  module: {
    rules: [{test: /\.(le|c)ss$/.use: [ // The resolution rule is right-to-left, namely, less-loader, postCSs-loader, CSS-loader, and style-loader
          'style-loader',
          {
            loader: 'css-loader'.options: {
              sourceMap: true // Whether to enable style lookup}}, {loader: 'postcss-loader'.// Prefix the browser
            options: {
              ident: 'postcss'.sourceMap: true.plugins: loaders= > [
                require('autoprefixer')({})]}}, {loader: 'less-loader'.// Parse the style file
            options: {
              sourceMap: true}}]}, {test: /\.(js)x? $/.use: ['babel-loader'].exclude: /node-modules/}},plugins: [
    new HTMLWebpackPlugin({
      inject: true.// All js scripts are placed after the body
      hash: true.// Generate hash for static resources for clear caching
      cache: true.// Issue files only when they are changed
      title: 'react admin'.filename: 'index.html'.template: path.resolve(__dirname, 'index.html'),
      minify: {
        collapseWhitespace: true.// Fold white space
        removeComments: true.// Delete comments
        removeRedundantAttributes: true.removeScriptTypeAttributes: true.removeStyleLinkTypeAttributes: true}}),new CleanWebpackPlugin()
  ]
}
Copy the code
  • After the configuration is completed, we simply do a test, create a new app.less file in the app.jsx directory, and write a simple style
.red{ color: red; .blue{ background: blue; } .orange{ background: orange; }}Copy the code
  • Change the render content in app.jsx to
import * as React from 'react'
import './app.less'

class App extends React.Component{
  render(){
    return (
      <div className="red">
        <div className="blue">123</div>
        <div className="orange">345</div>
      </div>)}}export default App
Copy the code
  • Then execute NPM run start, open the index.html in Dist, and find that the style has taken effect. Then F12 opens the developer tool for debugging, and can find the location of the effective style of the corresponding div
  • Now that you’ve done a simple demo, it’s time to do some configuration for your project