【个人笔记】2023年搭建基于webpack5与typescript的react项目
写在前面
由于我在另外的一些文章所讨论或分析的内容可能基于一个已经初始化好的项目,为了避免每一个文章都重复的描述如何搭建项目,我在本文会统一记录下来,今后相关的文章直接引用文本,方便读者阅读。此文主要为个人笔记,不会有太多的关于思路的描述;另外,本文仅仅描述如何搭建基础react项目,不涉及图片等资源的加载,关于图片等资源的处理,我会单独编写一期。
项目初始化
创建一个目录,例如:webpack5-react-demo,然后进入目录执行初始化指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ mkdir webpack5-react-demo $ cd webpack5-react-demo $ yarn init yarn init v1.22.19 question name (webpack5-react-demo): question version (1.0.0): question description: question entry point (index.js): question repository url: question author: question license (MIT): question private: success Saved package.json ✨ Done in 10.32s.
|
添加gitignore文件,路径为项目根目录/.gitignore
:
1 2 3 4
| .idea .vscode node_modules dist
|
初始化git仓库:
1 2 3
| $ git init $ git add . $ git commit -m 'init'
|
(0)NPM依赖添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| echo '【1】基于webpack的项目核心相关内容' echo '添加webpack基础四件套依赖' yarn add -D webpack webpack-cli webpack-dev-server html-webpack-plugin
echo '【2】处理js(x)、ts(x)的相关模块' echo '添加babel核心模块' yarn add -D @babel/core echo '添加babel相关preset欲集' yarn add -D @babel/preset-env @babel/preset-react @babel/preset-typescript echo '添加babel相关plugin插件' yarn add -D @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread echo '添加babel-loader' yarn add -D babel-loader
echo '【3】处理style样式的相关模块' echo '添加css-loader以及MiniCssExtractPlugin' yarn add -D css-loader mini-css-extract-plugin yarn add -D less less-loader
echo '【4】添加react/react-dom的类型定义以及运行依赖' yarn add react react-dom yarn add -D @types/react @types/react-dom
|
(1)webpack.config.js
作用:webpack基本配置,定义入口、各种loader、plugin等。
路径:项目根目录/webpack.config.js
内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| const {resolve} = require('path'); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { mode: "development", entry: { main: resolve(__dirname, 'src', 'index.tsx') }, output: { filename: "index.js", path: resolve(__dirname, 'dist') }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] }, module: { rules: [ { test: /\.tsx?/, use: [ 'babel-loader' ], exclude: /node_moudles/ }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader' ] }, { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'less-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: resolve(__dirname, 'public', 'index.html'), inject: 'body' }), new MiniCssExtractPlugin({ filename: 'app.css' }) ], devServer: { port: 8080 } }
|
(2).babelrc
作用:被@babel/core读取使用,其中定义了@babel/core要用到的preset、plugin等组件,对ts文件进行编译。想要深入理解,可以阅读另一篇文章:【长文详解】TypeScript与Babel、webpack的关系以及IDE对TS的类型检查 - 知乎 (zhihu.com)。
路径:项目根目录/.babelrc
内容:
1 2 3 4 5 6 7 8 9 10 11
| { "presets": [ "@babel/preset-env", "@babel/preset-typescript", ["@babel/preset-react", {"runtime": "automatic"}] ], "plugins": [ "@babel/plugin-proposal-object-rest-spread", "@babel/plugin-proposal-class-properties" ] }
|
(3)tsconfig.json
作用:仅作为IDE进行TypeScript类型检查服务的文件,与ts代码编译没有直接关系。可以阅读另一篇文章来了解:【长文详解】TypeScript与Babel、webpack的关系以及IDE对TS的类型检查 - 知乎 (zhihu.com)
路径:项目根目录/tsconfig.json
内容:
1 2 3 4 5 6 7 8
| { "compilerOptions": { "module": "commonjs", "rootDir": "./src", "outDir": "./dist", "jsx": "react-jsx" } }
|
(4)项目代码
src目录下,三个文件:index.tsx、index.module.less、react-app.d.ts。
src/index.tsx
路径:项目根目录/src/index.tsx
内容:
1 2 3 4 5 6 7 8
| import {createRoot} from "react-dom/client"; import styles from './index.module.less';
const App = () => { return <div className={styles.app}>Hello, <span>App</span></div> }
createRoot(document.querySelector('#app')).render(<App/>)
|
src/index.module.less
路径:项目根目录/src/index.module.less
内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| html, body { height: 100%; width: 100%; margin: 0; }
div { box-sizing: border-box; }
.app { height: 100%; width: 100%; font-size: 20px;
span { color: rgb(0, 111, 222); font-size: 24px; } }
|
src/react-app.d.ts(特别)
作用:仅仅用于类型定义,目前定义的是模块化less文件的结构定义。
路径:项目根目录/src/react-app.d.ts
内容:
1 2 3 4 5 6
| declare module '*.module.less' { const content: { [className: string]: any } export default content; }
|
public/index.html
作用:指定的html模板,根webpack.config.js里面HtmlWebpackPlugin所制定的模板路径保持一致。
路径:项目根目录/public/index.html
内容:
1 2 3 4 5 6 7 8 9 10
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> </body> </html>
|
运行
在package.json中添加运行脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| { "name": "webpack5-react-demo", "version": "1.0.0", "main": "index.js", "license": "MIT", + "scripts": { + "dev": "webpack-dev-server --config webpack.config.js" + }, "devDependencies": { ... ... }, "dependencies": { ... ... } }
|
效果:
附录
图解webpack配置与NPM包关系
github仓库
w4ngzhen/webpack5-react-demo (github.com)