从0到1构建react完整项目2022最新无坑版

Posted 桃子叔叔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从0到1构建react完整项目2022最新无坑版相关的知识,希望对你有一定的参考价值。

react更新很快,现在搜到的搭建react项目的博客,经常搭建到一半就卡住了,因此总结了一套从0到1构建react的方法,是对自己亲身实践项目的总结,也对研究学习使用react的小伙伴提供一点借鉴。

本文对大量博客进行研究,进行实际配置填坑后,整理修改完成,是全网难得的可以顺利跑通的项目,望且学且珍惜

整个项目包括以下内容:

  1. 安装NodeJS环境
  2. 安装webpack环境
  3. 新建项目目录和文件
  4. 配置babel将es6等高级语法转为es5
  5. 配置less/sass预处理器处理css
  6. 配置解析字体、图片等静态资源
  7. 配置压缩打包的js、css文件
  8. 配置抽离公共代码
  9. 配置热更新
  10. 配置删除上一次的打包结果及记录
  11. 集成React全家桶
  12. 集成react-router
  13. 集成react-redux
平时工作中一直在用React提供的脚手架工具搭建React项目,一行命令全都搞定,自己只管做需求开发即可,从来没仔细研究过各个模块代码怎么去配置,相互之间怎么去进行交互。这周正好有时间,所以决定仔细研究下React项目中的各个功能模块,所以我们来讲解下如何从零搭建一个完整的React项目,现在我们开始喽。

一、安装NodeJS环境

在开始之前,我们本机首先要安装部署Node环境。Node环境安装部署其实很简单,只需要去官网https://nodejs.org/zh-cn/下载安装包,然后双击安装即可。安装完后在命令行查看安装的版本信息:

node -v
npm -v

我这里的版本如下:

node环境搭建完成后,我们开始新建项目文件夹并且初始化一个基础项目框架:

mkdir react-project
cd ./react-project/
npm init

当运行npm init命令后,会初始化一个基础的项目框架,命令行中会出现一些问答信息,我们可以根据个人喜好输入一些自定义的信息,每一项填完按回车即可。

现在在我们的reactproject项目文件夹中有了一个“packagejson”文件

里面有我刚才配置的基本信息:

二. 安装webpack

webpack是一个模块打包工具,它会自动分析我们项目中的依赖以及项目编码中所用的高级语法这些东西,然后将它们打包编译成浏览器可以解析运行的js和css等文件。我们可以将webpack的API和CLI配合使用,API不用过多解释,这是webpack提供给我们调用和配置的接口,CLI是webpack提供的一个类似于脚手架的东西,它允许我们在命令行中可以使用webpack命令、运行webpack,所以在此处我们安装两个东西。
在项目根目录下运行命令行或powershell工具,然后通过以下命令安装webpack和webpack-cli工具:

npm install webpack webpack-cli --save-dev


安装完成之后可以在项目根目录下看到,多了一个”node_modules”文件夹和一个”package-lock.json”文件。

同时在我们的”package.json”文件中也多了些信息:

"devDependencies": 
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0"
  

三、新建项目目录和文件

项目根目录下新建”src”文件夹,用来存放后期的项目源码,然后里面新建一个“index.js”文件作为被webpack编译的文件,同时也是webpack配置的入口文件;项目根目录下再新建一个“build”文件夹,存放项目的webpack配置文件,然后在文件夹中新建”webpack.config.js”文件,用于编写webpack的核心配置代码;在项目根目录新建一个”index.html”文件,是后期我们的项目打包运行的主页面,同时项目打包后自动将打包的文件添加在该文件中。

文件目录新建完成后是如下所示的结构:

接下来我们在各个文件中添加基础代码,最后再测试一下搭建的基础环境是否成功。

首先在webpack.config.js文件,添加以下代码:

const path = require('path')

module.exports = 
    mode: 'development',
    entry: './src/index.js',
    output: 
        filename: 'bundle.js',
        path: path.resolve(__dirname, '../dist')
    

接下来在index.js文件中,添加测试代码,仅仅测试是否打包成功:

function sum (a, b) 
    return a + b;

var result = sum (12, 23);
console.log(result);

最后将package.json文件中的script属性修改一下,使它能够让在我们命令行中输入启动命令后自动完成打包过程,如下:

"scripts": 
    "build": "webpack --config ./build/webpack.config.js"
  ,

到此为止呢,我们编辑和修改代码已经完成了,index.html文件中并没有增加任何代码,此时它只是一个空文件,我们后期再增加。在项目根目录下运行命令行或powershell工具,然后通过“npm run build”来启动我们的项目,此处其实并不叫启动,因为我们没有为项目配置调试服务器这些插件,准确点应该说是通过这个命令来进行项目打包,如下:

由上图可看到我们的项目已经顺利打包,这时候在我们项目根目录自动创建了“dist”文件夹,并且里面生成了结果文件bundle.js,如下:

打开bundle.js文件,我们可以看到打包后的代码,如下所示:

此时说明我们项目安装和配置的webpack是正确的。

四、核心配置

ES6、ES7、ES8、ES9等高级语法转换成ES5

ES6、ES7、ES8、ES9等这些高级语法在浏览器中是无法直接编译运行的,所以需要我们在编译运行之前对这些高级语法进行转换,将它们转换成ES5代码,以便在浏览器中进行编译运行。这个事情是babel-loader来做的,它主要是将ES6等高级语法转换成浏览器能解析运行的低级语法,所以我们要在项目根目录中安装这些插件:

1、安装babel-loader及插件
npm install babel-loader @babel/core @babel/preset-env @babel/preset-react --save-dev

以上插件中babel-loader主要用于高级语法转换成低级语法,它是webpack的一个loader,用来预处理文件;@babel/core是babel的核心模块,提供转换的API;@babel/preset-env可以根据配置的目标浏览器或者运行环境将ES5+代码自动转换为ES5代码,也是babel的一个模块;@babel/preset-react用来解析React中的JSX语法,同样也是babel的模块。以上的模块写法中,前面加有”@”符号的写法是babel 7.0+版本的写法,具体的可以查看babel官网。

相关的babel依赖安装完成后,我们在项目根目录新建“babel.config.js”文件,用来配置babel。如果不创建此文件的话babel的配置信息我们直接写到webpack配置文件中的对应规则下的options属性中即可,在此处我们用babel.config.js配置文件的方式。在配置文件中我们加入如下代码:

2、配置babel.config.js
module.exports = 
    presets: [
        [
            // babel预设
            '@babel/preset-env',
            
                // 使用corejs 3的版本
                corejs: 2,
                // 按需加载
                useBuiltIns: 'entry',
                // 不使用模块化  交给其它打包工具处理
                modules: false
            
        ]
    ],
    plugins: []
;
3、配置webpack.config.js

在webpack.config.js配置文件中,我们配置一下babel-loader,代码如下:

module: 
        rules: [
            
                test: /\\.js|jsx$/,
                use: [
                    
                        loader: 'babel-loader',
                        options:
                            presets:['@babel/preset-env']
                        
                    
                ],
                include: path.join(__dirname, '../src'),
                exclude:/node_modules/
            
        ]

配置完成之后,我们修改下index.js中的代码,来测试下是否可以成功打包我们的ES5+的代码文件:

let taoziUncle = () => 
    console.log('测试箭头函数');

taoziUncle()

终端运行npm run build可以看到编译成功了。

以上的配置还存在两个问题,第一个首先是虽然我们打包成功了项目,这也表示着ES5+的代码我们可以顺利打包,但是我们在代码中用Promise、Set、Symbol等全局对象或者一些定义在全局对象上的方法时它都不会转换,这是因为我们的babel-loader只能转换高级语法,并不会转换新的API,所以这时候我们就需要用@babel/polyfill来为当前环境提供一个垫片;还有第二个问题是,当我们执行打包后,打包的文件里会有大量的重复代码,那我们这时候就需要提供统一的模块化的helper来减少这些helper函数的重复输出。所以就需要我们安装以下插件模块:

4、安装@babel/polyfill
npm install @babel/polyfill --save-dev


@babel/polyfill安装完之后我们不再需要进行额外的配置,因为在上面babel的配置文件中我们已经指定了@babel/polyfill是按需引入。

5、安装babel/polyfill的插件
npm install @babel/runtime @babel/plugin-transform-runtime @babel/plugin-syntax-dynamic-import --save-dev


以上三个插件安装完成之后,我们需要在babel.config.js和webpack.config.js中进行相应的配置,如下:

6、babel.config.js文件中如下修改:
// babel.config.js文件中如下修改:
module.exports = 
    presets: [
        [
            // babel预设
            '@babel/preset-env',
            
                // 使用corejs 3的版本
                corejs: 2,
                // 按需加载
                useBuiltIns: 'entry',
                // 不使用模块化  交给其它打包工具处理
                modules: false
            
        ]
    ],
    plugins: [
        ["@babel/plugin-transform-runtime"],//就是在此处添加了两个@babel/runtime中的插件
        "@babel/plugin-syntax-dynamic-import"
    ]
;
7、 webpack.config.js文件中如下修改:
//webpack.config.js文件中如下修改:

    test: /\\.js|jsx$/,
    use: [
        
            loader: 'babel-loader',
            options:
                presets:['@babel/preset-env','@babel/preset-react']
            
        
    ],
    include: path.join(__dirname, '../src'),
    exclude:/node_modules/

最后我们在index.js文件中添加Promise相关的代码来查看打包结果,如下:

let taoziUncle = () => 
    console.log('测试箭头函数');

taoziUncle()
let promise = new Promise((resolve, reject) => 
    setTimeout(() => 
        resolve(123);
    , 1000);
)
promise.then(res => 
    console.log(res);
)

终端运行npm run build 测试没有问题,说明我们配置成功了。

五、less/sass等css预处理器代码转换为css

在项目中如果我们使用了css预处理器,那就需要在打包的时候将less、sass等预处理器编写的代码转换成浏览器可以执行的css代码,这就需要我们安装以下插件,此处介绍less预处理器代码的转换配置:

1、安装基本依赖
npm install stylus stylus-loader less less-loader sass-loader node-sass css-loader style-loader --save-dev


以上安装的依赖插件中:css-loader主要的作用是解析css文件, 像@import等动态语法;style-loader主要的作用是解析的css文件渲染到html的style标签内;stylus、less、sass是CSS的常见预处理器;stylus-loader、less-loader、sass-loader主要是将其对应的语法转换成css语法。
然后我们webpack的配置文件module–rules数组中添加代码如下:

2、配置webpack文件

   test: /\\.less$/,
   use: [
       
           loader: 'style-loader'
       , 
           loader: 'css-loader'
       , 
           loader: 'less-loader'
       
   ]

在src目录下新建”index.less”文件,添加如下代码:

@color: red;
#div1 
    color: @color;
    font-size: 23px;

然后在index.js文件中我们引入新建的index.less文件,运行启动命令来执行打包,结果验证没有问题,说明我们配置成功了。

但是如果我们使用CSS3的一些新特性时,需要为不同的浏览器在CSS代码中添加不同的前缀,在开发中手动添加太麻烦,所以我们可以通过postcss来自动添加各种浏览器前缀。首先我们先要安装以下依赖插件:

3、安装postcss依赖
npm install postcss-loader autoprefixer --save-dev

然后在webpack配置文件中添加postcss的配置信息即可,如下:

4、配置文件中添加postcss

    test: /\\.less$/,
    use: [
        
            loader: 'style-loader'
        , 
            loader: 'css-loader'
        , 
            loader: 'postcss-loader'
        , 
            loader: 'less-loader'
        
    ]

六、解析字体、图片等静态资源

在我们的项目中会使用到图片等静态资源,在此处我们来添加配置。首先是安装相关依赖,如下:

npm install file-loader url-loader --save-dev

以上依赖中:file-loader可以用来帮助webpack打包处理一系列的图片文件,比如:.png 、 .jpg 、.jepg等格式的图片。打包的图片会给每张图片都生成一个随机的hash值作为图片的名字;url-loader封装了file-loader,它的工作原理:1、文件大小小于limit参数,url-loader将会把文件转为Base64;2、文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。
安装完依赖后,我们进行webpack.config.js文件中module–rules数组中添加代码如下:

 //配置图片静态资源的打包信息
   test: /\\.(jpg|png|jpeg|gif)$/,
   use: [
       
           loader: 'url-loader',
           options: 
               limit: 1024,
               fallback: 
                   loader: 'file-loader',
                   options: 
                       name: 'img/[name].[hash:8].[ext]'
                   
               
           
       
   ]
,  //配置多媒体资源的打包信息
   test: /\\.(mp4|webm|ogg|mp3|wav)$/,
   use: [
       
           loader: 'url-loader',
           options: 
               limit: 1024,
               fallback: 
                   loader: 'file-loader',
                   options: 
                       name: 'media/[name].[hash:8].[ext]'
                   
               
           
       
   ]

然后我们在项目src目录下新建”assets”文件夹,里面放置两张图片,在index.js中引入这两张图片

运行启动命令来打包项目代码,最后查看结果,没有报错说明我们配置成功了。

七、压缩打包后的JS、CSS文件

我们打包后的JS和CSS文件中存在大量的空格和引号等,这些会严重影像我们打包后的文件体积,所以接下来我们通过安装配置相应的依赖插件来压缩我们打包后的代码文件。首先安装如下依赖:

npm install mini-css-extract-plugin --save-dev

然后在webpack配置文件中增加我们依赖插件的配置,在plugins和module–rules中都需要修改

//首先引入我们新安装的依赖插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

plugins: [
        new MiniCssExtractPlugin( // 瘦身css
            filename: '[name].[contenthash].css',
            chunkFilename: '[id].[contenthash].css'
        )
    ],
    module: 
        rules: [
            
                test: /\\.js|jsx$/,
                use: [
                    
                        loader: 'babel-loader',
                        options:
                            presets:['@babel/preset-env','@babel/preset-react']
                        
                    
                ],
                include: path.join(__dirname, '../src'),
                exclude:/node_modules/
            ,   //最后添加这个依赖插件的配置信息
                test: /\\.css$/,
                use: [
                    
                        loader: MiniCssExtractPlugin.loader,
                        options: 
                            publicPath: '../'
                        
                    ,
                    'css-loader',
                ]
            , 
                test: /\\.less$/,
                use: [
                    
                        loader: 'style-loader'
                    , 
                        loader: 'css-loader'
                    , 
                        loader: 'postcss-loader'
                    , 
                        loader: 'less-loader'
                    
                ]
            ,  //配置图片静态资源的打包信息
                test: /\\.(jpg|png|jpeg|gif)$/,
                use: [
                    
                        loader: 'url-loader',
                        options: 
                            limit: 1024,
                            fallback: 
                                loader: 'file-loader',
                                options: 
                                    name: 'img/[name].[hash:8].[ext]'
                                
                            
                        
                    
                ]
            ,  //配置多媒体资源的打包信息
                test: /\\.(mp4|webm|ogg|mp3|wav)$/,
                use: [
                    
                        loader: 'url-loader',
                        options: 
                            limit: 1024,
                            fallback: 
                                loader: 'file-loader',
                                options: 
                                    name: 'media/[name].[hash:8].[ext]'
                                
                            
                        
                    
                ]
            
        ]
    

然后我们在src目录下新建”index.css”文件,在此文件中添加css测试代码,如下:

.test 
    color: red

接下来在index.js文件中引入新建的这个index.css文件和我们之前新建的index.less文件,最后运行启动命令来进行打包,最后结果如下:

由结果可以看到,最后css文件被打包,重新在dist目录下生成了一个打包后的文件,但是我们的less文件依然是直接打包在了bundle.js的文件中,这是因为mini-css-extract-plugin这个依赖插件只针对于css文件的。

八、抽离公共代码

我们在打包后的JS或者CSS文件中会有很多公共代码,如果不将这些代码进行抽离,我们最后的打包文件会变得很大,所以抽离公共代码这件事情是由SplitChunksPlugin插件来做,我们只需要在webpack配置文件中加入如下代码即可:

module.exports = 
    mode: 'development',
    entry: './src/index.js',
    output: 
        filename: 'bundle.js',
        path: path.resolve(__dirname, '../dist')
    ,
    optimization:   //添加抽离公共代码插件的配置
        splitChunks: 
            cacheGroups: 
                //打包公共模块
                commons: 
                    chunks: 'initial', //initial表示提取入口文件的公共部分
                    minChunks: 2, //表示提取公共部分最少的文件数
                    minSize: 0, //表示提取公共部分最小的大小
                    name: 'commons' //提取出来的文件命名
                
            
        ,
    
    ......

九、添加resolve选项

这个选项的作用是为了方便我们开发者,比如文件的别名、文件的扩展名等,webpack.config.js配置加如下代码:

resolve:                                     //resolve核心配置
        extensions: ['.js', '.jsx', '.json'],
        alias: 
            pages: path.join(__dirname, '../src/pages'),
            components: path.join(__dirname, '../src/components'),
            actions: path.join(__dirname, '../src/redux/actions'),
            reducers: path.join(__dirname, '../src/redux/reducers'),
            images: path.join(__dirname, '../src/images')
        
    

十、代码热更新

首先安装如下依赖:

npm install webpack-dev-server --save-dev
npm install html-webpack-plugin --save-dev

其中第一个依赖插件是热更新插件,第二个是我们的html-webpack-plugin插件,这个插件的作用是它可以每次动态的将我们打包后的js、css文件加入到index.html页面中。其中webpack的配置信息如下:

const path = require('path')
//首先引入我们新安装的依赖插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');      //引入html模板插件

module.exports = 
    mode: 'development',
    entry: './src/index.js',
    output: 
        centos7安装Docker详细步骤(无坑版教程)

ubuntu 20.04+ORB_SLAM3 安装并行全记录(无坑版)

极智AI | 昇腾开发环境搭建 CANN & MindStudio (无坑版)

Docker 部署centos7安装Docker详细步骤(无坑版教程)

如何利用Truffle React框架构建完整的智能合约

react全家桶从0搭建一个完整的react项目(react-router4reduxredux-saga)