第一章、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。

十一、 其他说明

相关推荐
悟能不能悟几秒前
jsp怎么拿到url参数
java·前端·javascript
程序猿小蒜15 分钟前
基于SpringBoot的企业资产管理系统开发与设计
java·前端·spring boot·后端·spring
Mapmost18 分钟前
零代码+三维仿真!实现自然灾害的可视化模拟与精准预警
前端
程序猿_极客25 分钟前
JavaScript 的 Web APIs 入门到实战全总结(day7):从数据处理到交互落地的全链路实战(附实战案例代码)
开发语言·前端·javascript·交互·web apis 入门到实战
suzumiyahr27 分钟前
用awesome-digital-human-live2d创建属于自己的数字人
前端·人工智能·后端
萧曵 丶40 分钟前
Python 字符串、列表、元组、字典、集合常用函数
开发语言·前端·python
申阳43 分钟前
Day 10:08. 基于Nuxt开发博客项目-关于我页面开发
前端·后端·程序员
拉不动的猪1 小时前
Webpack 与 Rollup 中 Tree-shaking 的实现原理与效果
前端·webpack·rollup.js
林太白1 小时前
跟着TRAE SOLO学习两大搜索
前端·算法
yunyi1 小时前
使用go的elastic库来实现前后端模糊搜索功能
前端·后端