webpack5项目搭建React-Cli(开发模式)
Posted 天界程序员
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack5项目搭建React-Cli(开发模式)相关的知识,希望对你有一定的参考价值。
step1–新建项目目录
创建一个新的目录,用于搭建React
项目。
mkdir react-cli
cd react-cli
step2–初始化项目
初始化项目生成package.json
文件。
npm init -y
step3–新建webpack开发模式配置文件
新建config
目录文件夹,在创建开发配置文件,并定义好初始配置结构。
文件名:webpack.dev.js
module.exports =
// 入口
entry: '',
// 输出
output: '',
// 存放loader的module
module:
rules: []
,
// 需要加载的插件plugins
plugins: [],
// 关于压缩的配置项
optimization: ,
// 开发模式mode
mode: 'development'
step4–详细配置开发模式
1、指定入口文件
entry: './src/main.js'
2、指定输出目录以及文件命名
output:
path: undefined, // 开发环境不需要打包,可以设置路径为undefined
filename: 'static/js/[name].js', // 指定bundle资源的路径以及命名
chunkFilename: 'static/js/[name].chunk.js', // 一般是动态导入的一些资源
assetModuleFilename: 'static/media/[hash:10][ext][query]', // 一些静态资源如图片等
,
3、配置loader用于处理为webpack可识别的资源
需要处理的有css资源、图片资源、js资源。
- 处理css资源
主要的loader有:style-loader
、css-loader
、less-loader
、sass-loader
、stylus-loader
。
处理样式的兼容性:postcss-loader
配置兼容的程度:需要在package.json
里面配置browserslist
属性
1、封装通用样式处理loader函数
由于样式文件有多种(.css|.less|.sass|.scss|.styl),一个个配置会代码冗余,所以使用通用函数来复用代码,减少配置代码的冗余。
// 处理样式loader的通用函数
const getStyleLoader = (pre) =>
return [
'style-loader','css-loader',
// 处理css兼容性
// 需要配合package.json的browserlist属性来决定兼容性
loader: 'postcss-loader',
options:
postcssOptions:
plugins: ['postcss-preset-env']
,
pre
].filter(Boolean)
2、结合通用函数配置样式loader
module:
rules: [
test: /\\.css$/i, // 以css结尾的文件
use: getStyleLoader()
,
test: /\\.less$/i, // 以less结尾的文件
use:getStyleLoader('less-loader')
,
test: /\\.s[ac]ss$/i, // 以sass/scss结尾的文件
use:getStyleLoader('sass-loader')
,
test: /\\.styl$/i, // 以styl结尾的文件
use:getStyleLoader('stylus-loader')
]
,
3、配置browserlist
"browserslist": [
"last 2 version",
"> 1%",
"not dead"
]
- 处理图片资源
// 处理图片资源
test: /\\.(jpe?g|png|webp|svg|gif)$/,
type: 'asset',
parser:
dataUrlCondition:
maxSize: 10 * 1024, // 当图片小于10kb时转为base64
,
- 处理其他资源
// 处理其他资源
test: /\\.(woff2?|ttf|mp3|mp4)$/,
type: 'asset/resource'
- babel处理js|jsx资源
// webpack.dev.js
const path = require('path')
//...省略
test: /\\.(jsx|js)$/,
include: path.resolve(__dirname, "../src"),
loader: "babel-loader",
options:
cacheDirectory: true,
cacheCompression: false,
plugins: [
// "@babel/plugin-transform-runtime", // presets中包含了
"react-refresh/babel", // 开启js的HMR功能
],
,
,
- 编写babel配置文件
// babel.config.js
module.exports =
// 使用react官方规则
presets: ["react-app"],
;
- ESlint监测语法插件
// webpack.dev.js
const path = require('path')
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
//...省略
plugins: [
new ESLintWebpackPlugin(
context: path.resolve(__dirname, "../src"),
exclude: "node_modules", // 排除的目录
cache: true, // 开启缓存
cacheLocation: path.resolve(
__dirname,
"../node_modules/.cache/.eslintcache"
),
),
]
- 编写ESlint配置文件
// .eslintrc.js
module.exports =
extends: ["react-app"], // 继承 react 官方规则
parserOptions:
babelOptions:
presets: [
// 解决页面报错问题
["babel-preset-react-app", false],
"babel-preset-react-app/prod",
],
,
,
;
- 处理HTML资源
// webpack.dev.js
const path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
//...省略
plugins: [
new ESLintWebpackPlugin(
context: path.resolve(__dirname, "../src"),
exclude: "node_modules",
cache: true,
cacheLocation: path.resolve(
__dirname,
"../node_modules/.cache/.eslintcache"
),
),
new HtmlWebpackPlugin(
template: path.resolve(__dirname, "../public/index.html"),
),
]
- 设定开发模式
// webpack.dev.js
// 开发模式mode
mode: 'development'
- 配置sourceMap
// webpack.dev.js
devtool: "cheap-module-source-map"
- 配置代码分割
optimization:
splitChunks:
chunks: "all",
,
runtimeChunk:
name: (entrypoint) => `runtime~$entrypoint.name`,
,
,
- 开发模式自动化服务器配置
devServer:
open: true,
host: "localhost",
port: 3000,
hot: true,
compress: true,
historyApiFallback: true, // 解决react-router刷新404问题
,
step5–编写react文件
src/main.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(
<App />
);
src/App.jsx
import React from "react";
function App()
return (
<div>
<h1>App</h1>
</div>
);
export default App;
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
step6–安装所需依赖
- webpack相关依赖
npm i webpack webpack-cli webpack-dev-server -D
- 资源处理相关
npm i eslint-webpack-plugin -D
npm i html-webpack-plugin -D
npm i style-loader css-loader less-loader sass-loader sass stylus-loader -D
npm i postcss-loader postcss-preset-env -D
npm i babel-loader @babel/core babel-preset-react-app eslint-config-react-app -D
- react相关
npm i react react-dom
step7–启动项目
- 编写启动命令
"scripts":
"start": "npm run dev",
"dev": "webpack serve --config ./config/webpack.dev.js"
,
- 运行项目
npm start
- 报错
Error: [BABEL] D:\\MyWorkSpace\\VUE3_WORKSPACE\\react-cli\\node_modules\\webpack-dev-server\\client\\index.js: Using `babel-preset-react-app` requires that you specify `NODE_ENV` or `BABEL_ENV` environment variables. Valid values are "development", "test", and "production". Instead, received: undefined.
- 解决方案
1、安装cross-env
npm i cross-env -D
2、修改启动命令
"scripts":
"start": "npm run dev",
"dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.dev.js"
,
将开发环境变量传给配置
- 再次启动
npm start
- 遇到新的错误
ERROR in ./src/main.js 4:0-24
Module not found: Error: Can't resolve './App' in 'D:\\MyWorkSpace\\VUE3_WORKSPACE\\react-cli\\src'
resolve './App' in 'D:\\MyWorkSpace\\VUE3_WORKSPACE\\react-cli\\src'
原因是后缀为jsx的文件,webpack无法识别。
- 解决方案-修改配置增加扩展名
resolve:
extensions: [".jsx", ".js", ".json"], // 自动补全文件扩展名,让jsx可以使用
,
再次启动就可以正常运行了。
step8–激活HMR功能
css默认在style-loader里面就已经激活了HMR功能,我们只需要激活js的HMR功能就好。
- 安装依赖
npm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh
- 配置
1、配置babel-loader
test: /\\.(js|jsx)$/,
loader: 'babel-loader',
options:
cacheDirectory: true,
cacheCompression: false,
plugins: [
// "@babel/plugin-transform-runtime", // presets中包含了
require.resolve('react-refresh/babel'), // 开启js的HMR功能
],
,
2、开启插件
plugins: [
// ...省略
new ReactRefreshWebpackPlugin(), // 解决js的HMR功能运行时全局变量的问题
]
step9–解决react-router刷新404问题
- 修改文件
1、src/main.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import BrowserRouter from 'react-router-dom'
import App from './App'
//..
const root = ReactDOM.createRoot(document.getElementById('app'))
root.render(<div>
<BrowserRouter>
<App />
</BrowserRouter>
</div>)
2、src/App.jsx
import React from "react";
import Link, Route, Routes from "react-router-dom"
import Home from "./pages/home"
import About from "./pages/about"
function App()
return (
<div>
<h1>App1</h1>
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<Routes>
<Route path="/home" element=<Home /> />
<Route path="/about" element=<About /> />
</Routes>
</div>
);
export default App;
3、src/pages/home/index.jsx
import React from "react";
export default function Home()
return <h1>Home~~~</h1>;
4、src/pages/about/index.jsx
import React from "react";
export default function Home()
return <h1 >about~~~</h1>;
- 安装依赖
npm i react-router-dom
- 启动项目
npm run dev
在浏览器可以切换路由,但是在路由下刷新页面会出现404错误。
GET http://localhost:3000/home 404 (Not Found)
- 解决方案
devServer:
//...
historyApiFallback: true, // 解决react-router刷新404问题
重新启动项目即可。
step10–关于react的路由懒加载
- 修改文件
1、src/App.jsx
import React, Suspense, lazy from 'react'
import Link, Route, Routes from 'react-router-dom'
// import Home from './pages/home'
// import About from './pages/about'
const Home = lazy(()=>import(/*webpackChunkName: 'Home'*/"./pages/home"))
const About = lazy(()=>import(/*webpackChunkName: 'About'*/"./pages/about"))
function App()
return (
<div>
<h1>App1</h1>
<ul>
<li>
<Link to="/home">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
<Suspense fallback=<div>loading...</div>>
<Routes>
<Route path="/home" element=<Home /> />
<Route path="/about" element=<About /> />
</Routes>
</Suspense>
</div>
)
export default App
- 启动项目
npm run dev
开启懒加载后,其路由代码会被单独打包到一个chunk里面,实现按需加载。
step11–现阶段的详细开发模式配置
const path = require('path')
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
// 处理样式loader的通用函数
const getStyleLoader = (pre) =>
return [
'style-loader','css-loader',
// 处理css兼容性
// 需要配合package.json的browserlist属性来决定兼容性
loader: 'postcss-loader',
options:
postcssOptions:
plugins: ['postcss-preset-env']
,
pre
].filter(Boolean)
module.exports =
// 入口
entry: './src/main.js',
// 输出
output:
path: undefined, // 开发环境不需要打包,可以设置路径为undefined
filename: 'static/js/[name].js'以上是关于webpack5项目搭建React-Cli(开发模式)的主要内容,如果未能解决你的问题,请参考以下文章