第一章、React + TypeScript + Webpack项目构建

React + TypeScript + Webpack项目构建(简版)

一、项目初始化

1. 创建项目文件夹

bash 复制代码
mkdir react-webpack-demo
cd react-webpack-demo

2. 初始化 package.json

npm init -y

二、安装基础依赖

① React 相关依赖

复制代码
npm install react react-dom

② Webpack 相关依赖

vbscript 复制代码
npm install -D webpack webpack-cli webpack-dev-server

③ Babel(转译 JSX 和现代 JS)

bash 复制代码
npm install -D @babel/core @babel/preset-env @babel/preset-react babel-loader

④ HTML 模板插件

css 复制代码
npm install -D html-webpack-plugin

⑤ CSS 支持

复制代码
npm install -D style-loader css-loader

⑥ 安装 TypeScript 相关依赖

bash 复制代码
npm install -D typescript @babel/preset-typescript ts-loader
npm install -D @types/react @types/react-dom

三、目录结构

pgsql 复制代码
react-demo/
├── package.json
└── /webpack
    ├── webpack.common.js
    ├── webpack.dev.js
    └── webpack.prod.js
├── tsconfig.json
├── .babelrc
├── /public
│   └── index.html
└── /src
    ├── index.tsx
    ├── App.tsx
    └── style.css

四、Babel 配置(支持 ts / tsx)

修改 .babelrc

perl 复制代码
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
    "@babel/preset-typescript"
  ]
}

这样 Babel 就可以转译 .ts.tsx 文件了。

五、添加 tsconfig.json

在根目录创建 tsconfig.json

json 复制代码
{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": ["src"]
}

六、配置 Webpack

我们可以把 webpack 配置拆分为三份

  1. 公共配置(common) :入口、输出、模块解析、Babel、HTML 插件等通用设置
  2. 开发配置(development) :css、devServer、sourceMap、热更新等
  3. 生产配置(production) :压缩、代码分割、提取 CSS、环境变量等

然后用 webpack-merge 来组合。

1️⃣ 安装依赖

sql 复制代码
npm install -D webpack-merge cross-env mini-css-extract-plugin css-minimizer-webpack-plugin terser-webpack-plugin

2️⃣ 目录结构示意

复制代码
webpack/
├── webpack.common.js
├── webpack.dev.js
├── webpack.prod.js

3️⃣ 公共配置(webpack.common.js)

js 复制代码
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "./src/index.tsx",
  output: {
    path: path.resolve(__dirname, "../dist"),//`__dirname` 表示当前 webpack 配置文件所在的目录。`../dist` 回到项目根目录再生成
    filename: "js/[name].js",
    assetModuleFilename: "assets/[hash][ext][query]",
    clean: true,
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".jsx"],
    alias: {
      "@": path.resolve(__dirname, "src"),
    },
  },
  module: {
    rules: [
      // JS/TS 文件由 babel-loader 处理
      {
        test: /\.[jt]sx?$/,
        exclude: /node_modules/,
        use: "babel-loader",
      },
      // 图片等资源
      {
        test: /\.(png|jpg|jpeg|svg|gif)$/i,
        type: "asset/resource",
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
};

4️⃣ 开发环境配置(webpack.dev.js)

js 复制代码
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");

module.exports = merge(common, {
  mode: "development",
  devtool: "eval-cheap-module-source-map",
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          "style-loader", // 将 CSS 注入 <head>
          "css-loader",   // 解析 CSS
        ],
      },
    ],
  },
  devServer: {
    static: "./public",
    port: 3000,
    open: true,
    hot: true,
    historyApiFallback: true,
  },
});

5️⃣ 生产环境配置(webpack.prod.js)

js 复制代码
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const { DefinePlugin } = require("webpack");

module.exports = merge(common, {
  mode: "production",
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader, // 提取 CSS 到单独文件
          "css-loader",
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/[name].[contenthash:8].css",
    }),
    new DefinePlugin({
      "process.env.NODE_ENV": JSON.stringify("production"),
    }),
  ],
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin(), new CssMinimizerPlugin()],
    splitChunks: {
      chunks: "all",
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
          chunks: "all",
        },
      },
    },
  },
});

七、HTML 模板

js 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>React + Webpack</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

八、React 入口文件

src/index.tsx

javascript 复制代码
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
import "./style.css";

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

src/App.tsx

javascript 复制代码
import React from "react";

const App: React.FC = () => {
  return (
    <div>
      <h1>React + TypeScript + Webpack ⚙️</h1>
      <p>现在支持 TS / JSX 转译!</p>
    </div>
  );
};

export default App;

九、添加启动命令

修改 package.json

js 复制代码
{
  "scripts": {
    "start": "cross-env NODE_ENV=development webpack serve",
    "build": "cross-env NODE_ENV=production webpack"
  },
  "devDependencies": {
    "cross-env": "^7.0.3"
  }
}

安装 cross-env

sql 复制代码
npm install -D cross-env

十、启动项目

开发模式

sql 复制代码
npm start

访问 http://localhost:3000

生产构建

arduino 复制代码
npm run build

输出到 /dist 文件夹,包含压缩后的 JS/CSS。

十一、 其他说明

相关推荐
cindershade3 小时前
用原生 HTML5 视频与 Canvas 实现浏览器端视频抽帧封面
前端
笨鸟先飞,勤能补拙4 小时前
Web 服务器与计算机网络全景原理
运维·服务器·前端·网络·人工智能·计算机网络·web安全
NutShell Wang4 小时前
Wails v3 Beta 实战:用显式对象模型重写你的第一个 Go 桌面应用
前端·人工智能·go·vibe coding
daols884 小时前
vue 甘特图 vxe-gantt 任务条拖拽自动更新日期
javascript·vue.js·甘特图
cindershade4 小时前
前端国际化工程实践:语言包拆分、动态加载与日期数字格式统一
前端
kisbad4 小时前
Day 036|OpenAI Agents SDK 快速开始:今天跑通第一个 Agent
java·前端·javascript
qq_267612894 小时前
Gitee CodePecker行业场景化落地指南:金融、车联网与IoT双引擎选型与工程化路径
前端·gitee·自动化
初晨未凉4 小时前
elementui自定义内容图片预览
前端
无糖可可果5 小时前
从零读懂一个 Next.js 全栈笔记应用
前端
Maxkim5 小时前
DeepSeek Harness 源码深度分析:像 VS Code 一样插件化的 Agent 框架
前端·架构