1、在项目文件夹下执行npm init生成package.json文件
2、创建src文件夹,并创建以下文件夹结构
3、安装相关依赖
// webpack、webpack-cli、webpack-dev-server
npm install webpack webpack-cli webpack-dev-server -D
// babel-loader、@babel/core、@babel/preset-env、@babel/preset-react、@babel/preset-typescript
npm install babel-loader -D
npm install @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript -D
// typescript
npm install typescript ts-loader -D
// react、react-dom、react-router、react-router-dom 及其类型声明
npm install react、react-dom、react-router、react-router-dom
npm install @types/react @types/react-dom @types/react-router @types/react-router-dom -D
// less、less-loader、css-loader、min-css-extract-plugin -D
npm install less less-loader css-loader -D
npm install min-css-extract-plugin -D
// 其他重要插件:cross-env、html-webpack-plugin、clean-webpack-plugin
npm install cross-env html-webpack-plugin clean-webpack-plugin -D
4、进行最基本的webpack配置,webpack.config.js、tsconfig.json和babel.config.json文件内容如下
// babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
// "targets": {
// "edge": "17",
// "firefox": "60",
// "chrome": "67",
// "safari": "11.1"
// },
// "useBuiltIns": "usage",
// "corejs": "3.6.5"
"targets": {
"browsers": "last 2 versions"
}
}
],
"@babel/preset-react",
["@babel/preset-typescript"]
]
}
// tsconfig.json
{
"compilerOptions": {
"esModuleInterop": true,
"removeComments": true,
"strict": true,
"rootDir": "./src",
"outDir": "./bundles",
"noUnusedLocals": true,
"noUnusedParameters": true,
"jsx": "react",
"sourceMap": true,
// baseUrl、paths属性配置很重要,不然引入组件可能会报错:Cannot find module ‘xxx‘ or its corresponding type declarations
"baseUrl": ".",
"paths": {
"*": ["src/*", "node_modules/*"]
}
},
"include": ["src/"]
}
// webpack.config.js
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
// 在最新的v2.5.0版本中使用的exports.default导出的,需得使用import引入,但是在这个配置文件中直接用import引入又会报错:Cannot use import statement outside a module。所以这里mini-css-extract-plugin使用的是v2.4.6版本
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const isProduction = process.env.NODE_ENV === "production";
const devConfig = {
devtool: "inline-source-map",
devServer: {
allowedHosts: "all",
hot: true,
port: 9003,
open: true,
historyApiFallback: true, // 未命中自动render index.html
},
};
const config = {
mode: isProduction ? "production" : "development",
context: path.join(__dirname, "./src/entries"),
entry: {
// 该配置是以多页面为例,其中模板使用的跟src并齐的templates文件夹中的index.html和task.html
index: "./index.tsx",
task: "./task.tsx",
},
output: {
path: path.join(__dirname, "dist"), // 绝对路径
filename: "[name].bundle.js",
chunkFilename: "[id].chunk.js",
},
resolve: {
extensions: [".ts", ".tsx", ".js", "/json"],
},
module: {
rules: [
{
test: /\.(ts|tsx)?$/,
include: path.resolve(__dirname, "./src"),
use: ["babel-loader", "ts-loader"],
},
{
test: /\.(less|css)$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: "css-loader",
},
{
loader: "less-loader",
},
],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
inject: "body", // 将资源注入在body底部,默认是头部
title: "index.html",
filename: "index.html",
template: path.join(__dirname, "templates/index.html"),
chunks: ["index"], // 只会将index对应的bundle插入到html中
entry: "index",
}),
new HtmlWebpackPlugin({
inject: "body",
title: "task.html",
filename: "task.html",
template: path.join(__dirname, "templates/task.html"),
chunks: ["task"],
entry: "task",
}),
new MiniCssExtractPlugin(),
],
optimization: {
splitChunks: {},
},
};
module.exports = isProduction ? config : { ...config, ...devConfig };
5、配合react-router,搭建一个页面开发基础。文件内容如下:
// entries/index.tsx 入口文件
import React from "react";
import { render } from "react-dom";
import App from "../pages/App";
render(<App />, document.querySelector("#app"));
// pages/App.tsx
import React from "react";
import { HashRouter, useRoutes } from "react-router-dom";
import routes from "../router";
import "./App.less";
const App = () => {
const element = useRoutes(routes);
return element;
};
// 注意:在reactRouter的V6版本中一定要这么包裹一层才可行,不然会报错
const AppWrapper = () => {
return (
<HashRouter>
<App />
</HashRouter>
);
};
export default AppWrapper;
// router/index.tsx
import React from "react";
import { RouteObject } from "react-router";
import Home from "../pages/Home";
import Page1 from "../pages/page1";
import Page2 from "../pages/page2";
const route: RouteObject[] = [
{ path: "/", element: <Home /> }, // 首页
{ path: "/page1", element: <Page1 /> },
{ path: "/page2", element: <Page2 /> },
];
export default route;
以上就完成了开发结构的基本实现,具体的功能可以在路由对应的页面中进行开发。
改变url即可实现页面之间的切换,以Home页面为例,点击按钮即可将整个页面切换成路由对应页面:
import React from "react";
import { useNavigate } from "react-router";
const Home = () => {
const navigate = useNavigate();
return (
<>
<button
onClick={() => {
navigate("/page1");
}}
>
去page1
</button>
<button
onClick={() => {
navigate("/page2");
}}
>
去page2
</button>
home
</>
);
};
export default Home;
好了,现在就可以愉快的开始业务功能开发啦~