运行效果
原生React项目可正常运行,由于业务要求,需要改用webpack打包。
本最初使用create-react-app创建,后面使用webpack进行了改造,两种方式均可运行或打包。Demo运行效果如下。
webpack运行使用端口是8888(命令 npm run dev ),原生 react-scripts start 运行(命令:npm run start0)使用的端口是3000。具体命令可通过package.json文件进行自定义。
以下是webpack运行效果(注意“页脚”,使用的是src/index.html):
以下是react-scripts start 运行的效果(使用的是public/index.html)
不多说,直接放附件。
使用步骤
- npm i 安装依赖包。
- 使用以下命令启动(二选一):
- npm run dev
- npm run start0
核心代码
- pages/Home.jsx
import React from 'react';
import {useRef, useEffect} from "react";
import "../resource/css/main.css";
export default function Home() {
let inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
})
return (
<div>
<h1>首页</h1>
<div className="green_text">路由基础</div>
<input type="text" ref={inputRef}/>
</div>
)
};
- 路由代码RouteSetting.jsx:
import React from "react";
import {BrowserRouter as Router, Routes, Route, Link} from 'react-router-dom'; // HashRouter 有#, BrowserRouter没有#
import FirstComponent from "./pages/First";
import SecondComponent from "./pages/Second";
import Home from "./pages/Home";
function RouteSetting() {
return (
<Router>
<div>
<h1>React路由基础</h1>
{/* 指定路由入口 */}
<ul>
<li><Link to="/">首页</Link></li>
<li><Link to="/first">页面一</Link></li>
<li><Link to="/second?a=2">页面二</Link></li>
</ul>
{/*//路由出口:路由地址对应的组件会在这里进行渲染*/}
<Routes>
{/* 指定路由出口 */}
{/*//指定路径和组件之间的映射关系。path:路径;element:组件,成对出现*/}
<Route exact path="/" element={<Home/> }></Route>
<Route path="/first" element={<FirstComponent/>}></Route>
<Route path="/second" element={<SecondComponent/>}></Route>
</Routes>
</div>
</Router>
);
}
export default RouteSetting;
- package.json
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"less": "^4.1.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start0": "react-scripts start",
"build0": "react-scripts build",
"test0": "react-scripts test",
"eject": "react-scripts eject",
"lint": "umi g tmp && npm run lint:js && npm run lint:style && npm run lint:prettier",
"lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ",
"lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src && npm run lint:style",
"lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src",
"lint:prettier": "prettier --check \"src/**/*\" --end-of-line auto",
"lint:style": "stylelint --fix \"src/**/*.less\" --syntax less",
"prettier": "prettier -c --write \"src/**/*\"",
"precommit": "lint-staged",
"precommit:fix": "npm run lint:fix && npm run prettier && npm run lint:prettier && npm run lint:style",
"dev": "webpack-dev-server --hot --config config/webpack.dev.conf.js",
"start": "npm run dev",
"build": "webpack --progress --config config/webpack.prod.conf.js"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@umijs/fabric": "^4.0.1",
"babel-core": "^6.26.3",
"babel-eslint": "^10.1.0",
"babel-loader": "^7.1.5",
"babel-plugin-import": "^1.13.5",
"babel-preset-latest": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.7.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"less-loader": "^11.0.0",
"node-less": "^1.0.0",
"style-loader": "^3.3.1",
"url-loader": "^4.1.1",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.10.1",
"webpack-merge": "^5.8.0"
},
"lint-staged": {
"**/*.less": "stylelint--syntaxless",
"**/*.{js,jsx,ts,tsx}": "npmrunlint-staged:js",
"**/*.{js,jsx,tsx,ts,less,md,json}": [
"prettier--write"
]
},
"husky": {
"hooks": {
"pre-commit": "npmrunlint-staged"
}
}
}
- config\webpack.base.conf.js
"use strict";
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口起点
entry: {
ICSApp: "./src/index.js",
},
// 输出
output: {
path: path.resolve(__dirname, "../dist"),
filename: "[name].js",
},
// 解析
resolve: {
extensions: [".ts", ".tsx", ".js", ".json",".jsx"],
alias: {
"@components": path.join(__dirname, "../src/components"),
"@utils": path.join(__dirname, "../src/utils"),
"@pages": path.join(__dirname, "../src/pages"),
},
},
// loader
module: {
rules: [
{
test: /\.js|jsx$/,
exclude: /(node_modules|bower_components)/, // 屏蔽不需要处理的文件(文件夹)(可选)
loader: "babel-loader",
},
{
//支持less
// npm install style-loader css-loader less-loader less --save-dev
test: /\.(le|c)ss$/, // .less and .css
use: ["style-loader", "css-loader", "less-loader"], // 创建的css文件存在html的头部
},
],
},
// 插件
plugins: [
new HtmlWebpackPlugin({
filename: "index.html", //写入HTML的文件。默认为index.html(必须放置在src目录下)。也可以指定一个子目录(例如:)assets/admin.html
template: "src/index.html", //以该文件下的本地index.html作为模板,打包的时候自动生成服务器html并自动引入打包的js文件
inject: "body",
hash: false,
minify: {
collapseWhitespace: true, //把生成文件的内容的没用空格去掉,减少空间
},
})
],
};
- config\webpack.dev.conf.js
"use strict";
const { merge } = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");
const path = require("path");
const webpack = require("webpack");
module.exports = merge(baseWebpackConfig, {
// 模式
mode: "development",
// 调试工具
devtool: "inline-source-map",
// 开发服务器
devServer: {
static: path.resolve(__dirname, "static"),
historyApiFallback: true, // 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
compress: true, // 启用gzip压缩
hot: true, // 模块热更新,取决于HotModuleReplacementPlugin
host: "127.0.0.1", // 设置默认监听域名,如果省略,默认为“localhost”
port: 8888, // 设置默认监听端口,如果省略,默认为“8080”
},
optimization: {
nodeEnv: "development",
},
});
- config/webpack.prod.conf.js
"use strict";
const { merge } = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");
const path = require("path");
const webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = merge(baseWebpackConfig, {
// 模式
mode: "production",
// 调试工具
devtool: "source-map",
// 输出
output: {
path: path.resolve(__dirname, "../dist"),
filename: "js/[name].[chunkhash].js",
},
// 插件
plugins: [new CleanWebpackPlugin()],
// 代码分离相关
optimization: {
nodeEnv: "production",
runtimeChunk: {
name: "manifest",
},
splitChunks: {
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
name: false,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendor",
chunks: "initial",
},
},
},
},
});
config/webpack.config.js 无需使用。
参考:https://blog.csdn.net/Shen_zhihao/article/details/126270958