使用webpack5自己搭建react项目脚手架(手把手教,把手伸过来,好软~呸,好手)

:目前前端最火的两大框架react和vue官方都有自己的成熟的cli脚手架,为什么还要自己搭建脚手架了?
答:
一、自己搭建脚手架可以根据自己公司的项目特征来决定使用哪些具体的插件或者编译方式,官方的脚手架都是大众化的,大而全的,所以自己搭建的更灵活。
二、装逼

不管你是哪种原因,本教程都适用

教程目录

  • 一、初始化项目
  • 二、react 项目相关的包安装
  • 三、webpack配置文件代码编写
  • 四、页面运行测试

一、初始化项目

  1. 创建好自己的项目存放目录,在终端进入该目录
  2. 命令行中输入以下命令,会自动创建好项目的package.json文件
npm init -y
  1. package.json中需要做基础修改
{
  "name": "react-cli",
  "version": "1.0.0",
  "description": "",
  -"main": "index.js", //这个是入口文件,删除此行,不在这使用
  +"private":true, //添加此行,标识该项目是私有的
  "scripts": {
    -"test": "echo \"Error: no test specified\" && exit 1" //删除此行,暂时用不到测试命令
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

  1. 项目目录结构搭建,这是我的的项目目录
    使用webpack5自己搭建react项目脚手架(手把手教,把手伸过来,好软~呸,好手)_第1张图片

  2. 安装webpack、webpack-cli、webpack-merge、webpack-dev-server、html-webpack-plugin

    webpack:官方的处理包,打包什么的都需要这个来执行
    webpack-cli:能够在命令行中使用webpack命令
    webpack-merge:在开发环境和生产环境中的打包配置项有所不同,通过这个来合并两个环境中相同的配置项
    webpack-dev-server:本地服务器,能够边开发浏览器自动刷新页面或HMR(热模块替换)
    html-webpack-plugin:模板文件插件
    

在终端命令行中输入以下命令:

npm install webpack webpack-cli webpack-merge webpack-dev-server html-webpack-plugin -D
  1. 在项目根目录下创建三个webpack配置文件,webpack.common.js(公用的配置项)、webpack.dev.js(开发环境配置项)、webpack.prod.js(生产环境配置项)
    使用webpack5自己搭建react项目脚手架(手把手教,把手伸过来,好软~呸,好手)_第2张图片

二、react 项目相关的包安装

  1. 本地需要用的包:babel-loader、@babel/core、@babel/preset-env、@babel/preset-react、@pmmmwh/react-refresh-webpack-plugin、react-refresh、css-loader、style-loader、sass、sass-loader、mini-css-extract-plugin

    babel-loader:js文件使用的loader
    @babel/core:调用babel进行代码处理
    @babel/preset-env:将es6+的代码转换成兼容的es5代码
    @babel/preset-react:识别react中jsx的写法进行转换
    @pmmmwh/react-refresh-webpack-plugin:react 的HMR(热模块更新)插件,依赖于react-refresh
    react-refresh:react 的HMR(热模块更新)
    css-loader:识别css文件,并将css代码转换成js代码
    style-loader:将js代码中的css代码添加到head中,使用style标签的方式
    sass:编译scss/sass
    sass-loader:识别sass/scss文件
    mini-css-extract-plugin:在生产环境下替代style-loader,可以将css代码转换成css文件形式
    

在终端命令行中输入以下命令:

npm install babel-loader @babel/core @babel/preset-env @babel/preset-react react-refresh @pmmmwh/react-refresh-webpack-plugin css-loader style-loader sass sass-loader mini-css-extract-plugin -D
  1. 生产环境下需要用到的包:react、react-dom、react-router-dom

    react:处理react项目程序
    react-dom:渲染dom树
    react-router-dom:react路由
    

在终端命令行中输入以下命令

npm install react react-dom react-router-dom --save

三、webpack配置文件代码编写

  1. 在src目录下添加入口文件:
    使用webpack5自己搭建react项目脚手架(手把手教,把手伸过来,好软~呸,好手)_第3张图片
  2. 入口文件中写入react的代码
import ReactDom from "react-dom/client";

function App(){
    return(
        <div>
            测试
        </div>
    )
}

const root=ReactDom.createRoot(document.getElementById("root"));
root.render(
    <App />
);
  1. 根目录新建public文件夹,并添加html模板文件,咱们在入口文件里面写的需要找id为root的元素,所以模板文件里面必须存在一个root id 的标签
    使用webpack5自己搭建react项目脚手架(手把手教,把手伸过来,好软~呸,好手)_第4张图片
  2. webpack.common.js代码
const path=require("path");  //node环境当前路径
const HtmlWebpackPlugin=require("html-webpack-plugin");  //模板文件插件,能够自动将打包的css和js加入到模板文件中

module.exports={
    entry:{
        app:"./src/index.js" //找到咱们刚才在src下面的入口文件
    },
    output: {
        path:path.resolve(__dirname,"dist"), //打包文件输出的地址
        clean:true //webpack5新增的,每次打包前删除旧的dist包文件
    },
    module: {
        rules:[
            {
                test:/\.(jpg|png|gif|svg)$/, //处理图片文件打包
                type:"asset", //webpack5新增的处理静态资源的loader,替换之前的url-loder、file-loader,具体的可以官方文档
                parser:{
                    dataUrlCondition:{
                        maxSize:100*1024 //最大100kb的文件会被转成base64,大于100kb的文件会转成图片文件
                    }
                },
                generator:{
                    filename:"static/images/[name]_[contenthash:8][ext]" //最终图片文件输出的路径
                }
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:"./public/index.html", //找到咱们刚才创建的模板文件
            minify:{ //压缩html
                collapseWhitespace:true, //移除空格
                removeComments: true // 移除注释
            }
        })
    ]
}
  1. webpack.dev.js代码
const {merge}=require("webpack-merge"); //引入merge工具
const common=require("./webpack.common.js"); //引入刚才写的公共的webpack.common.js文件
const ReactRefreshPlugin=require("@pmmmwh/react-refresh-webpack-plugin");

//使用merge,可以把common里面写的所有配置项都合并过来,然后再单独写在开发环境下需要的配置即可
module.exports=merge(common,{
    mode:"development", //当前环境变量
    output:{
        filename:"[name].js", //开发环境没有缓存问题,所以不需要添加hash值,添加了会影响编译速度
        publicPath:"/" //公共路径,开发环境写根目录即可
    },
    devtool:"inline-source-map",  //开发开启source-map,方便开发有错误时定位文件位置
    devServer:{ //本地服务器
        open:true, //是否自动打开浏览器
        compress:true,
        port:"auto", //端口号,可以自定义也可以写成auto 
        client:{
            logging:"none",
            progress: true
        },
        historyApiFallback:true,
    },
    module:{
        rules:[
            {
                test:/\.(css|scss|sass)$/,
                use:[ //loader 顺序是自下而上执行,所以顺序一定不要错
                    "style-loader",
                    "css-loader", //如果需要使用css module模式的话,在这个loader里面添加配置即可,自己百度下
                    "sass-loader"
                ]
            },
            {
                test:/\.(js|jsx)$/,
                exclude:"/node_modules/", //处理js文件,剔除node_modules文件里面的文件
                use:[
                    {
                        loader:"babel-loader",
                        options:{
                            presets:[
                                "@babel/preset-env",
                                ["@babel/preset-react",{
                                    "runtime":"automatic"
                                }]
                            ],
                            plugins: [require.resolve("react-refresh/babel")]  //HMR 热模块更新
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        new ReactRefreshPlugin()
    ]
})
  1. webpack.prod.js代码
const {merge}=require("webpack-merge"); //引入merge工具
const common=require("./webpack.common.js"); //引入刚才写的公共的webpack.common.js文件
const MiniCssExtractPlugin=require("mini-css-extract-plugin");

//使用merge,可以把common里面写的所有配置项都合并过来,然后再单独写在生产环境下需要的配置即可
module.exports=merge(common,{
    mode:"production", //当前环境变量
    output:{
        filename:"static/js/[name].[contenthash:8].js", //将js文件放到对应的目录下,并使用hash值命名,当js内容修改后,文件名也会对应修改
        publicPath:"./" //公共路径,生产环境写相对路径,这样前端页面放到其他的目录下的时候不会出现白屏问题
    },
    devtool:"source-map",  //生产环境下用的source map 模式
    module:{
        rules:[
            {
                test:/\.(css|scss|sass)$/,
                use:[ //loader 顺序是自下而上执行,所以顺序一定不要错
                    {
                        loader:MiniCssExtractPlugin.loader,
                        options:{
                            publicPath:"../../" //这个路径是控制打包的css文件里面写的路径,因为把css文件放到了static/css文件下了,所以需要重置下css里面的公共路径配置
                        }
                    },
                    "css-loader", //如果需要使用css module模式的话,在这个loader里面添加配置即可,自己百度下
                    "sass-loader"
                ]
            },
            {
                test:/\.(js|jsx)$/,
                exclude:"/node_modules/", //处理js文件,剔除node_modules文件里面的文件
                use:[
                    {
                        loader:"babel-loader",
                        options:{
                            presets:[
                                "@babel/preset-env",
                                ["@babel/preset-react",{
                                    "runtime":"automatic"
                                }]
                            ] 
                            //生产环境下不需要HRM热模块更新,所以去掉
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename:"static/css/[name]_[contenthash:8].css" //配置css文件输出路径
        }),
    ]
})

四、页面运行测试

  1. 在package.json里面的scripts中添加运行命令
{
  "name": "react-cli",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
  +  "start": "webpack serve --config webpack.dev.js",
  +  "build": "webpack --config webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.18.6",
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-react": "^7.18.6",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.6.1",
    "react-refresh": "^0.14.0",
    "sass": "^1.53.0",
    "sass-loader": "^13.0.2",
    "style-loader": "^3.3.1",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3",
    "webpack-merge": "^5.8.0"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0"
  }
}

  1. 在终端命令行中输入以下命令:
npm run start

妥妥的没问题
使用webpack5自己搭建react项目脚手架(手把手教,把手伸过来,好软~呸,好手)_第5张图片
3. 添加路由页面,在src下pages文件下添加两个页面文件,然后在路由js文件中引入

import { BrowserRouter,Routes,Route } from "react-router-dom";

// 引入页面
import Page1 from "../pages/page1/index";
import Page2 from "../pages/page2/index";

export default function App(){
    return(
        <BrowserRouter>
            <Routes>
                <Route path="/" element={<Page1 />}></Route>
                <Route path="/page2" element={<Page2 />}></Route>
            </Routes>
        </BrowserRouter>
    )
}
  1. 在入口文件中,引入路由js
import ReactDom from "react-dom/client";

// 引入路由js
import App from "./routers/index";

const root=ReactDom.createRoot(document.getElementById("root"));
root.render(
    <App />
);

使用webpack5自己搭建react项目脚手架(手把手教,把手伸过来,好软~呸,好手)_第6张图片
使用webpack5自己搭建react项目脚手架(手把手教,把手伸过来,好软~呸,好手)_第7张图片

哦了,完活,后面自己想要添加eslint或者postcss自己添加就可了,然后根据自己的项目添加对应的插件。

手真白。。呸。。破键盘,手收回去吧,教完了~

你可能感兴趣的:(react,webpack,react.js,javascript,前端)