react ts 项目搭建

182 阅读2分钟

创建项目

md webpack-ts-react-demo  
cd .\webpack-ts-react-demo\
npm init -y

新建src文件夹和public文件夹

  • src 存放源码 新建一个index.js文件作为入口文件
  • public 存放页面及一些静态资源文件 新建一个index.html文件

下载webpack作为构建和启动工具

npm i -D webpack webpack-cli webpack-dev-server
npm i -D html-webpack-plugin copy-webpack-plugin clean-webpack-plugin
# html-webpack-plugin webpack渲染html的插件
# copy-webpack-plugin webpack打包不会将public里的内容打包进去 需要此插件将public里的内容复制到打包后的文件夹内
# clean-webpack-plugin 清理上次webpack打包缓存
npm i -D esbuild-loader 
# esbuild-loader 打包处理 ts tsx js jsx等文件
npm i -D style-loader postcss-loader sass-loader
# 处理sass css 等文件

根目录新建webpacK.config.js

const CopyPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const path = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
        publicPath: '/',
        clean: true,/* 编译前清除目录 */
        path: path.join(__dirname, "/dist"),
        filename: `static/js/[name].[hash].js`,
        hashDigestLength: 6,
        assetModuleFilename: 'static/img/[name].[contenthash][ext]' /* 静态资源 */
    },
    // 别名配置
    resolve: {
        extensions: ['.tsx', '.ts', '.js', '.jsx'],
        alias: {
            '@': path.resolve(__dirname, 'src'),
            'src:': path.resolve(__dirname, 'src')
        }
    },
    module: {
        rules: [
            {
                test: /\.(png|jpg|svg|gif)$/,
                type: 'asset/resource',
                generator: {
                    filename: 'static/img/[name].[contenthash][ext]'
                }
            },
            {
                test: /\.(js|ts|jsx|tsx)$/,
                exclude: /node_modules/,
                use: ['esbuild-loader']
            },
            {
                test: /\.(css)$/,
                use: [
                    'style-loader',
                    'css-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: {
                                plugins: [['postcss-preset-env', {}]]
                            }
                        }
                    }
                ]
            },
            {
                test: /\.(sass|scss)$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true,
                            importLoaders: 1
                        }
                    },
                    'postcss-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            // 模板路徑
            template: 'public/index.html',
            //配置minify,进行html文件的压缩
            minify: {
                collapseWhitespace: true
            }
        }),
        // 复制public文件
        new CopyPlugin({
            patterns: [{ from: 'public/static', to: 'static' }]
        }),
        // 清理上次打包缓存
        new CleanWebpackPlugin(),
    ],
    devServer: {
        static: {
            publicPath: 'public'
        },
        port: 8080,
        open: true,
        historyApiFallback: true,
    }
};

下载 react 和 babel解析器

npm i react react-dom react-router-dom
# react 核心库
# react-dom 官方DOM渲染器
# react-router-dom 官方路由库
npm i @babel/core @babel/plugin-proposal-class-properties babel-loader babel-preset-env babel-preset-react
# @babel/core 编译器的核心包可以将es6以后的代码转为es5
# @babel/plugin-proposal-class-properties 在标准 ECMAScript 中类属性的定义需要在构造函数内,而此插件允许你在类的外部定义类属性
# babel-loader 可以让Webpack支持Babel的插件,以便在打包时对代码进行转译
# babel-preset-env  预设不同的环境配置
# babel-preset-react 可以在代码中使用 JSX 语法,并进行相应的转译为标准的 JavaScript 代码

新建 babel.config.js

module.exports = {
  presets: ["@babel/react", "@babel/env"],
  plugins: ["@babel/plugin-proposal-class-properties"],
};

兼容ts

npm i -D typescript
# 相关的声明文件
npm i -D @types/node @types/react @types/react-dom

整理项目文件

src 下的index.js 该文main.tsx 作为入口文件

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { RouterView } from "src/router/index.tsx"
const root = document.createElement('div');
root.id = 'root';
document.body.appendChild(root);
ReactDOM.createRoot(root).render(
  <BrowserRouter>
      <RouterView /> 下面文件
  </BrowserRouter>
);

新建路由文件src/router/index.tsx

import { Navigate,useRoutes } from "react-router-dom"
const _routes = [
    {
        path: '/',
        element: < PageView />,
        children: [
            {
                path: '/home',
                element: <Home />
            }
        ]
    },
    {
        path: '/login',
        element: <Login></Login>
    },
    {
        path: '/error/:id',
        element: <ErrPage errId={404} />
    },
    {
        path: '*',
        element: <Navigate to='/error/500' />
    }
];

export const RouterView = useRoutes(UserRoutes.MyRoutes);