likes
comments
collection
share

webpack(v5.7)+React(v18.0)+react-router(v6.3)+Mobx(v6.5)+TS(v4.6)从零开始构建

作者站长头像
站长
· 阅读数 11

万丈高楼平地起

先找块地,挖个坑

  • 进入项目根目录,执行npm init -y生成初始的package.json文件,并将其配置项的入口main删除,添加private:true
  • 执行yarn add -D webpack webpack-cli webpack-merge安装webpack相关的东东。
  • 在根目录下创建.gitignore文件,其内用来忽略一些我们不需要提交到远程的目录或文件。

webpack的配置

坑已挖好,开始打地基

坑里边打钢筋柱子

  • 在根目录下创建build目录,用来存放我们后期用于打包的一些配置文件。
  • build目录下创建webpack.config.js文件,写入基本的配置,如下:
  • 在根目录下创建src目录,在其内创建index.html模板文件。同时创建index.tsx入口文件
const path = require('path');
module.exports = {
    entry: {
        app: path.join(__dirname, '../src/index.tsx')
    },
    output: {
        path: path.join(__dirname, '../dist'),
        filename: '[name].[chunkhash:8].bundle.js',
        // publicPath: "/",
        chunkFilename: 'chunk/[name].[chunkhash:8].js',
    },
    resolve: {
        // 解析这些文件
        extensions: ['.js', '.jsx', '.ts', '.tsx', '.json']
    },
}

配置babel-loader解析resolve.extensions中的多种类型文件

  • 安装yarn add -D @babel/core bable-loader @babel/preset-env
  • Babel 的核心功能包含在 @babel/core 模块中,必须安装

插件和预设

  • 代码转换功能以插件的形式出现,插件是小型的 JavaScript 程序,用于指导 Babel 如何对代码进行转换。
  • @babel/preset-env可以让你使用最新的javaScript。
  • @babel/preset-react用来转换JSX片段。
  • bable-loader使用 Babel 加载 ES2015+ 代码并将其转换为 ES5。
  • babel 会在每个文件都插入辅助代码,这就会使得代码体积过大。可以使用Babel runtime作为一个独立模块,来避免重复引入一些不需要的代码。你必须执行yarn add -D @babel/plugin-transform-runtime 来把它包含到你的项目中,然后使用yarn add @babel/runtime@babel/runtime安装为一个依赖。
module.exports = {
    module: {
        // 将缺失的导出提示成错误而不是警告
        strictExportPresence: true,
        // loaders
        rules: [{
            test: /\.(js|mjs|jsx)$/,
            include: path.join(__dirname, 'src'),
            use: {
                // 当有设置cacheDirectory时,指定的目录将用来缓存 loader 的执行结果。
                loader: 'babel-loader?cacheDirectory',
                options: {
                  presets: ['@babel/preset-env', "@babel/preset-react"],
                  // 'transform-runtime' 插件告诉 Babel,要引用runtime来代替注入
                  // 引入 @babel/plugin-transform-runtime 并且使所有辅助代码从这里引用。
                  plugins: ['@babel/plugin-transform-runtime'],
                }
              }
          },{
              test: /\.(ts|tsx)$/,
              include: path.join(__dirname, 'src'),
              use: {
                loader: 'ts-loader',
              }
          }]
    },
}

添加TS支持

  • npm install --save typescript awesome-typescript-loader source-map-loader
  • awesome-typescript-loader可以让Webpack使用TypeScript的标准配置文件 tsconfig.json编译TypeScript代码。
  • source-map-loader使用TypeScript输出的sourcemap文件来告诉webpack何时生成 自己的sourcemaps。方便我们调试。
  • 在根目录下创建tsconfig.json文件。配置如下:
{
    "compilerOptions": {
        "target": "ESNext",
        "useDefineForClassFields": true,
        "lib": ["DOM", "DOM.Iterable", "ESNext"],
        "allowJs": false,
        "skipLibCheck": false,
        // 允许export=导出,由import from 导入
        "esModuleInterop": true,
        // 允许从没有设置默认导出的模块中默认导入。这并不影响代码的输出,仅为了类型检查。
        "allowSyntheticDefaultImports": true,
        "removeComments": false,  // 删除注释 
        "alwaysStrict": true, // 在代码中注入'use strict'
        // 禁止对同一个文件的不一致的引用
        "forceConsistentCasingInFileNames": true,
        "module": "ESNext",
        "moduleResolution": "Node",
        "noUnusedLocals": true, // 检查只声明、未使用的局部变量(只提示不报错)
        "importHelpers": true, // 通过tslib引入helper函数,文件必须是模块
        "experimentalDecorators": true,  // 启用实验性的ES装饰器。
        "resolveJsonModule": true,  //是否允许把json文件当做模块进行解析
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "react-jsx"
    },
    "include": [
        "src",
        "*.d.ts"//配置的.d.ts文件,用于定义一些 declare
    ],
}

添加符合ts的路径别名

  • build目录下,创建alias.js文件,用于书写我们使用到的路径别名。
const path = require('path')

module.exports = {
  "@img": path.resolve(__dirname, '../src/assets/images'),
  "@svg": path.resolve(__dirname, '../src/assets/svg'),
  "@pages": path.resolve(__dirname, '../src/pages'),
  "@store": path.resolve(__dirname, '../src/store'),
  "@components": path.resolve(__dirname, '../src/components'),
  "@routes": path.resolve(__dirname, '../src/routes'),
}
  • 然后将其配置在webpack的resolve选项下的alias属性中。
  • 接着,在项目根目录下创建paths.json文件,用于配置ts的路径别名。内容如下:
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "*"
      ],
      "@src/*": [
        "src/*"
      ],
      "@pages/*": [
        "src/pages/*"
      ],
      "@components/*": [
        "src/components/*"
      ],
      "@routes/*": [
        "src/routes/*"
      ],
      "@assets/*": [
        "src/assets/*"
      ],
      "@store/*": [
        "src/store/*"
      ]
    }
  }
}
  • tsconfig.json文件中使用extends配置项继承上面的paths.json文件。
  • 大功告成。 注意: 后续如果要添加新的路径的别名的话,必须要在alias.jspaths.json两个文件中分别添加!!!

配置html模板

  • 安装 yarn add -D html-webpack-plugin
  • 该插件将为你生成一个 HTML5 文件, 在 body 中使用 script 标签引入你所有 webpack 生成的 bundle。 只需添加该插件到你的 webpack 配置中。如下:
  • 在根目录下创建src目录,在其内创建index.html模板文件。同时创建index.tsx入口文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    plugins: [
        new HtmlWebpackPlugin({
            template: `${path.join(__dirname, "../src")}/index.html`
        })
    ],
}

配置本地开发服务以及热更新

  • 安装 yarn add -D webpack-dev-server
  • 利用webpack-dev-server搭建本地的web server,并启用模块热更新

module.exports = {
    mode: 'development',
    devServer: {
        client: {
            // 当出现编译错误或警告时,在浏览器中显示全屏覆盖。
            overlay: true,
            // 在浏览器中以百分比显示编译进度。
            progress: false,
            // 告诉 dev-server 它应该尝试重新连接客户端的次数。当为 true 时,它将无限次尝试重新连接。
            reconnect: true,
        },
        // 项目使用了react-router-dom的BrowserRouter,所以此项必须设置为true。否则会导致配置的路由404
        // 也就是说,当使用h5的history API时,必须将 historyApiFallback设置为true。
        historyApiFallback: true,
        // 启用gzip 压缩
        compress: true,
        port: 9000,
        // 启用webpack的模块热替换
        hot: true,
        // 告诉 dev-server 在服务器已经启动后打开默认的浏览器
        open: true,
        // 代理---处理跨域转发
        proxy: {

        }
    },
}
  • package.json文件的scripts选项中添加"dev": "webpack-dev-server --config build/webpack.config.js"
  • 接着我们执行yarn dev命令,在服务启动之后就可以看到会自动打开一个浏览器窗口,显示我们index.tsx文件中的内容。

配置样式loader

  • yarn add -D less less-loader style-loader css-loader postcss-loader postcss
  • 再安装一些postcss需要的插件yarn add -D postcss-flexbugs-fixes postcss-preset-env postcss-normalize 配置如下:(后面再做公共代码的提取)
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const lessRegex = /\.(less)$/;
const lessModuleRegex = /\.module\.(less)$/;
module.exports = {
    // ...
    module: {
        // ...
        rules: [
            // ...
            // 配置css-loader
            {
                test: cssRegex,
                exclude: cssModuleRegex,
                use: [
                    // style-loader将css插入到DOM中, 推荐将 style-loader 与 css-loader 一起使用
                    require.resolve('style-loader'),
                    // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
                    {
                        loader: 'css-loader',
                        options: {
                            // 启用/禁用@import规则进行处理,控制@import的解析,默认值为true
                            import: true, 
                            // importLoaders 选项允许你配置在 css-loader 之前有多少 loader 应用于 @imported 资源与 CSS 模块/ICSS 导入。
                            importLoaders: 1,
                            // 启用/禁用css模块或者icss及其配置
                            modules: {
                                mode: 'icss',
                                // 允许配置生成的本地标识符(ident)
                                // 建议:开发环境使用 '[path][name]__[local]'  生产环境使用 '[hash:base64]'
                                localIdentName: "[path][name]__[local]--[hash:base64:5]",
                                // 允许为本地标识符名称重新定义基本的 loader 上下文。
                                localIdentContext: path.resolve(__dirname, "src"),
                            },
                            sourceMap: true,
                        },
                    },
                    // 自动添加css浏览器前缀
                    {
                        loader: require.resolve('postcss-loader'),
                        options: {
                          postcssOptions: {
                            ident: 'postcss',
                            config: false,
                            plugins: [
                                  'postcss-flexbugs-fixes', // 此插件用来修复flexbug的问题
                                  [
                                    'postcss-preset-env', // 包含了autoprefixer
                                    {
                                      autoprefixer: {
                                        flexbox: 'no-2009',
                                      },
                                      // 规定按照哪个阶段的css来实现polyfill
                                      stage: 3, // 默认启用阶段2的功能
                                    },
                                  ],
                                  'postcss-normalize', // PostCSS归一化,可让您使用formantize.css或Sanitize.css的各个部分。
                            ]
                          },
                          sourceMap: true,
                        },
                    },
                ],
                // 注意,所有导入文件都会受到 tree shaking 的影响。
                // 这意味着,如果在项目中使用类似 css-loader 并 import 一个 CSS 文件,
                // 则需要将其添加到 side effect 列表中,以免在生产模式中无意中将它删除:
                sideEffects: true,
            },
            // 处理.module.css文件
            {
                test: cssModuleRegex,
                use: [
                    require.resolve('style-loader'),
                    {
                        loader: 'css-loader',
                        options: {
                            // 启用/禁用@import规则进行处理,控制@import的解析,默认值为true
                            import: true, 
                            // importLoaders 选项允许你配置在 css-loader 之前有多少 loader 应用于 @imported 资源与 CSS 模块/ICSS 导入。
                            importLoaders: 1,
                            // 启用/禁用css模块或者icss及其配置
                            modules: {
                                mode: 'local',
                                // 允许配置生成的本地标识符(ident)
                                // 建议:开发环境使用 '[path][name]__[local]'  生产环境使用 '[hash:base64]'
                                localIdentName: "[path][name]__[local]--[hash:base64:5]",
                                // 允许为本地标识符名称重新定义基本的 loader 上下文。
                                localIdentContext: path.resolve(__dirname, "src"),
                            },
                            sourceMap: true,
                        },
                    },
                    // 自动添加css浏览器前缀
                    {
                        loader: require.resolve('postcss-loader'),
                        options: {
                          postcssOptions: {
                            ident: 'postcss',
                            config: false,
                            plugins: [
                                  'postcss-flexbugs-fixes', // 此插件用来修复flexbug的问题
                                  [
                                    'postcss-preset-env', // 包含了autoprefixer
                                    {
                                      autoprefixer: {
                                        flexbox: 'no-2009',
                                      },
                                      // 规定按照哪个阶段的css来实现polyfill
                                      stage: 3, // 默认启用阶段2的功能
                                    },
                                  ],
                                  'postcss-normalize', // PostCSS归一化,可让您使用formantize.css或Sanitize.css的各个部分。
                            ]
                          },
                          sourceMap: true,
                        },
                    },
                ]
            },
            // 配置支持less
            {
                test: lessRegex,
                exclude: lessModuleRegex,
                use: [
                    // style-loader将css插入到DOM中, 推荐将 style-loader 与 css-loader 一起使用
                    require.resolve('style-loader'),
                    // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
                    {
                        loader: 'css-loader',
                        options: {
                            // 启用/禁用@import规则进行处理,控制@import的解析,默认值为true
                            import: true, 
                            // importLoaders 选项允许你配置在 css-loader 之前有多少 loader 应用于 @imported 资源与 CSS 模块/ICSS 导入。
                            importLoaders: 3,
                            // 启用/禁用css模块或者icss及其配置
                            modules: {
                                mode: 'icss',
                                // 允许配置生成的本地标识符(ident)
                                // 建议:开发环境使用 '[path][name]__[local]'  生产环境使用 '[hash:base64]'
                                localIdentName: "[path][name]__[local]--[hash:base64:5]",
                                // 允许为本地标识符名称重新定义基本的 loader 上下文。
                                localIdentContext: path.resolve(__dirname, "src"),
                            },
                            sourceMap: true,
                        },
                    },
                    // 自动添加css浏览器前缀
                    {
                        loader: require.resolve('postcss-loader'),
                        options: {
                          postcssOptions: {
                            ident: 'postcss',
                            config: false,
                            plugins: [
                                  'postcss-flexbugs-fixes', // 此插件用来修复flexbug的问题
                                  [
                                    'postcss-preset-env', // 包含了autoprefixer
                                    {
                                      autoprefixer: {
                                        flexbox: 'no-2009',
                                      },
                                      // 规定按照哪个阶段的css来实现polyfill
                                      stage: 3, // 默认启用阶段2的功能
                                    },
                                  ],
                                  'postcss-normalize', // PostCSS归一化,可让您使用formantize.css或Sanitize.css的各个部分。
                            ]
                          },
                          sourceMap: true,
                        },
                    },
                    'less-loader',
                ],
                sideEffects: true,
            },
            // 支持.module.less文件
            {
                test: lessModuleRegex,
                use: [
                    require.resolve('style-loader'),
                    {
                        loader: 'css-loader',
                        options: {
                            // 启用/禁用@import规则进行处理,控制@import的解析,默认值为true
                            import: true, 
                            // importLoaders 选项允许你配置在 css-loader 之前有多少 loader 应用于 @imported 资源与 CSS 模块/ICSS 导入。
                            importLoaders: 3,
                            // 启用/禁用css模块或者icss及其配置
                            modules: {
                                mode: 'local',
                                // 允许配置生成的本地标识符(ident)
                                // 建议:开发环境使用 '[path][name]__[local]'  生产环境使用 '[hash:base64]'
                                localIdentName: "[path][name]__[local]--[hash:base64:5]",
                                // 允许为本地标识符名称重新定义基本的 loader 上下文。
                                localIdentContext: path.resolve(__dirname, "src"),
                            },
                            sourceMap: true,
                        },
                    },
                    // 自动添加css浏览器前缀
                    {
                        loader: require.resolve('postcss-loader'),
                        options: {
                          postcssOptions: {
                            ident: 'postcss',
                            config: false,
                            plugins: [
                                  'postcss-flexbugs-fixes', // 此插件用来修复flexbug的问题
                                  [
                                    'postcss-preset-env', // 包含了autoprefixer
                                    {
                                      autoprefixer: {
                                        flexbox: 'no-2009',
                                      },
                                      // 规定按照哪个阶段的css来实现polyfill
                                      stage: 3, // 默认启用阶段2的功能
                                    },
                                  ],
                                  'postcss-normalize', // PostCSS归一化,可让您使用formantize.css或Sanitize.css的各个部分。
                            ]
                          },
                          sourceMap: true,
                        },
                    },
                    'less-loader'
                ],
            }
        ]
    }
}

tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块语法的 静态结构 特性

抽取css文件(MiniCssExtractPlugin)建议用于生产环境

  • MiniCssExtractPlugin插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。
  • 本插件基于 webpack v5 的新特性构建,并且需要 webpack 5 才能正常工作。
  • 与 extract-text-webpack-plugin 相比:
    • 异步加载
    • 没有重复的编译(性能)
    • 更容易使用
    • 特别针对 CSS 开发
  • 建议 mini-css-extract-plugin 与 css-loader一起使用。

提取公共的样式loader处理

  • build目录下新建rules目录同时创建子文件styleRules.js,用于存放webpack配置项module中的一些rules规则配置。
  • 同时我们将之前的对js、ts等文件的处理loader也抽取到名为jsRules.js的文件中。

webpack(v5.7)+React(v18.0)+react-router(v6.3)+Mobx(v6.5)+TS(v4.6)从零开始构建

webpack(v5.7)+React(v18.0)+react-router(v6.3)+Mobx(v6.5)+TS(v4.6)从零开始构建 具体详细代码查看

处理图片、字体文件等资源

  • 资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。
  • 在 webpack 5 之前,通常使用:
  • 资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:
    • asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
    • asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现。
    • asset/source 导出资源的源代码。之前通过使用 raw-loader 实现。
    • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现。 此外,当在 webpack 5 中使用旧的 assets loader(如 file-loader/url-loader/raw-loader 等)和 asset 模块时,你可能想停止当前 asset 模块的处理,并再次启动处理,这可能会导致 asset 重复,你可以通过将 asset 模块的类型设置为 'javascript/auto' 来解决。 此处,我们使用type模块类型为asset,让其自动处理:
module: {
    rules: [
     {
        test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 10000,
          },
        },
    },
    {
        test: /\.svg$/,
        use: [
            {
                // @svgr/webpack允许将svg作为组件使用
                loader: require.resolve('@svgr/webpack'),
                options: {
                prettier: false,
                svgo: false,
                svgoConfig: {
                    plugins: [{ removeViewBox: false }],
                },
                titleProp: true,
                ref: true,
                },
            },
            {
                loader: require.resolve('file-loader'),
                options: {
                name: 'static/media/[name].[hash].[ext]',
                },
            },
        ],
        // 一个条件,用来与被发出的 request 对应的模块项匹配。
        issuer: {
            and: [/\.(ts|tsx|js|jsx|md|mdx)$/],
        },
    },
    ]
}

详细代码查看

区分webpack打包环境

我们先将webpack分为开发环境、生产环境。

  • 首先我们在build目录下创建constants.js文件用于存放一些我们经常用到的变量。
// 存放一些用到的常量
const IS_DEV = process.env.NODE_ENV === "development"
const APP_ENV = process.env.APP_ENV || "prod"
const FILE_EXTENSIONS = [".ts", ".tsx", ".js", "jsx", '.json']

module.exports = {
  IS_DEV,
  APP_ENV,
  FILE_EXTENSIONS
}
  • yarn add -D webpack-merge 使用webpack-merge来对一些公共的配置和不同环境下的配置进行自动合并。
  • 在build目录下创建webpack.dev.config.js
  • 我们将之前写好的webpack.config.js修改其内部的代码,区分开发环境和生产环境的配置。
  • webpack.dev.config.js中添加devServer选项。

打包优化

  • 在build目录下创建optimization.js文件,用于书写打包优化的配置。
  • webpack v5 自带了terser-webpack-plugin,如果想自定义配置,则仍需要安装该插件。
  • terser-webpack-plugin插件使用terser来压缩js
  • 使用css-minimizer-webpack-plugin插件来压缩css,该插件内部使用了cssnano来优化和压缩css。 详情配置查看

代码规范配置

手摸手教你使用最新版husky(v7.0.1)让代码更优雅规范

配置antd库 按需引入

  • yarn add antd 并根据官方文档配置即可

配置react路由管理

  • yarn add react-router-dom 此时会安装v6.3.0版本。
  • import { Outlet,useParams,NavLink, useSearchParams, useLocation } from "react-router-dom" Outlet保证了路由切换时,父级路由页面的内容会一直存在。
  • <Route path="*"/>仅在路由不存在时才会匹配该路由。
  • useParams用来获取路由上的参数。
  • NavLink用来改变路由按钮激活时的颜色。查看
  • useSearchParams用来获取和设置路由上的?后边的参数。const [searchParams, setSearchParams] = useSearchParams(); 查看
  • useLocation 自定义路由行为,该钩子返回一路由数据的对象。具体查看 具体的react-router-dom v6版本的详细介绍 请看 或者 查阅官方文档

配置全局的store

  • yarn add mobx mobx-react-lite
  • 在src目录下创建store目录,其内创建index.tsx文件。内容如下:
import User from './modules/user'

export default {
  userStore: new User(),
}
  • 在store目录下新建modules目录,其下用于存放各个模块的单独store,最终在index.tsx文件中统一导出。
  • 例如:modules下的user.tsx文件用来创建我们上述代码中的User类,最终实例化得到了userStore。代码如下:
import { makeAutoObservable } from 'mobx'

export default class User {
  /**
   * this上绑定的变量需要在此处声明,否则ts检查会报错
   */
  state: { token: string }
  
  constructor() {
    /**
     * state
     */
    this.state = {
      token: 'aaa',
    }
    // 自动将已经存在的对象属性并且使得它们可观察
    makeAutoObservable(this)
  }
  /**
   * computed
   */
  get isLogin() {
    return this.state.token;
  }
  /**
   * action
   */
  setToken(val) {
    this.state.token = val || ''
  }
}
  • 接着在src目录下,新建contexts目录,其内用于存放一些需要数据共享的Context对象。此时我们先创建一个storeContext.tsx文件用来将store数据创建成Context对象,利用Context对象的Provider最终将全局的store传递到各个组件中去。
  • storeContext.tsx代码如下:
import React from "react";
import store from '@store/index';
// 使用react的context向下级传递数据,从而共享全局的可观察数据
const StoreContext = React.createContext(store);

export default StoreContext;
  • 此时已经有了全局共享的Context对象了,那么在hooks中如何使用呢?
  • 紧接着,我们在src目录下创建hooks目录,用来存放一些自定义的hook。此时我们先创建一个名为storeHook.tsx的文件,用来处理store,代码如下:
/**
 * 创建store状态管理的hook
 */

import { useContext } from 'react'
// observer该方法也不可以不在此处导出
import { observer } from 'mobx-react-lite'

import StoreContext from '../contexts/storeContext'

function useStore() {
  const store = useContext(StoreContext)
  return store;
}

export {
  observer,
  useStore
}
  • 到这一步,已经是万事具备了!!!只需要我们在入口文件下注入即可。代码如下:
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
// 重置浏览器样式
import "normalize.css";
// 引入文件
import App from "./App";
import store from '@store/index'
import StoreContext from './contexts/storeContext';

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(
  <BrowserRouter>
    <StoreContext.Provider value={store} >
      <App />
    </StoreContext.Provider>
  </BrowserRouter>
);
  • 验证:在子组件中这么用
import { useRoutes } from "react-router-dom";
import routes from "@router/index";
import { useStore } from '@hooks/storeHook'
import { toJS } from 'mobx'

function App() {
  const { userStore } = useStore();
  userStore.setToken('ttt')
  console.log(toJS(userStore), 'store-=-=-=', userStore)
  return useRoutes(routes);
}

export default App;

console的输出如下图所示: webpack(v5.7)+React(v18.0)+react-router(v6.3)+Mobx(v6.5)+TS(v4.6)从零开始构建 可以看到,userStore中的state对象下的token变量已经从'aaa'变成了'ttt'。

二次封装axios

mock数据

  • npm install -g json-server
  • 然后在你需要的任意位置创建一个名为db.json的文件,用来存放mock的数据。
  • 比如我们在项目根目录下创建__json_server_mock__文件夹,其内创建db.json文件。
  • package.json文件的scripts选项下新增该命令:"json-server": "json-server --watch __json_server_mock__/db.json"

webpack(v5.7)+React(v18.0)+react-router(v6.3)+Mobx(v6.5)+TS(v4.6)从零开始构建

  • 然后我们执行 yarn json-server 启动json-server,会在控制台看到如下所示:

webpack(v5.7)+React(v18.0)+react-router(v6.3)+Mobx(v6.5)+TS(v4.6)从零开始构建

  • 可以看到我们的资源地址为http://localhost:3000/users
  • 将此地址复制到 postman中 并执行。

webpack(v5.7)+React(v18.0)+react-router(v6.3)+Mobx(v6.5)+TS(v4.6)从零开始构建

  • 上图中,我们发送了get请求,得到了一个空数组。是因为我们文件中就是一个空数组。
  • 接下来,我们执行post请求,添加一些数据:

webpack(v5.7)+React(v18.0)+react-router(v6.3)+Mobx(v6.5)+TS(v4.6)从零开始构建

webpack(v5.7)+React(v18.0)+react-router(v6.3)+Mobx(v6.5)+TS(v4.6)从零开始构建

  • 可以看到,我们文件中的json数据会自动的更新为对应的结果。
  • 其他的请求方式,可以自行尝试。
  • json-server可以很快速的配置出一个REST API Server。 官网详情查看

写在最后

本篇实战型文章,会不定时持续的更新,直到项目框架搭建完毕。 欢迎一键三连!!! 文中,有不对的地方,或者有更好的写法的话,欢迎各位在评论区留言指出!!!

项目github地址:github.com/clr1235/rea…

有兴趣的可以fork或者给个star!!!