最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在react項(xiàng)目中webpack使用mock數(shù)據(jù)的操作方法

 更新時(shí)間:2024年06月21日 11:35:34   作者:d312697510  
這篇文章主要介紹了在react項(xiàng)目中webpack使用mock數(shù)據(jù)的操作方法,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

1. 創(chuàng)建react項(xiàng)目

使用 create-react-app 創(chuàng)建項(xiàng)目

npx create-react-app react-mock

執(zhí)行 eject 命令

npm run eject

 刪除 package.json 文件中的 eslintConfig 選項(xiàng)

2. 安裝依賴包

npm i path-to-regexp fast-glob chokidar axios

3. 創(chuàng)建中間件

在 config 文件夾中創(chuàng)建 WebpackMiddlewareMock.js 文件

讓webpack-dev-server加載中間件,把mock配置文件的請(qǐng)求地址和響應(yīng)數(shù)據(jù)映射到dev server的路由上

const { pathToRegexp } = require("path-to-regexp");
const fg = require("fast-glob");
const path = require("path");
const chokidar = require("chokidar");
const VALID_METHODS = [
  "GET",
  "POST",
  "PUT",
  "DELETE",
  "PATCH",
  "HEAD",
  "OPTIONS",
];
const DEFAULT_METHOD = "GET";
const MOCK_FILE_PATTERN = "mock/**/*.{js,ts}";
const DEFAULT_OPTIONS = {
  rootDir: "",
  exclude: [],
};
class WebpackMiddlewareMock {
  constructor(options = {}) {
    this.options = { ...DEFAULT_OPTIONS, ...options };
    const { rootDir, exclude } = this.options;
    this.mockConfigs = this.getConfigs(rootDir, exclude);
  }
  parseMockKey(key) {
    const keyItems = key.split(/\s+/);
    if (keyItems.length === 1) {
      return {
        method: DEFAULT_METHOD,
        path: keyItems[0],
      };
    } else {
      const [method, path] = keyItems;
      const upperCaseMethod = method.toLocaleUpperCase();
      if (!VALID_METHODS.includes(upperCaseMethod)) {
        console.error(`method ${method} is not supported`);
      }
      if (!path) {
        console.error(`${key} path is not defined`);
      }
      return {
        method,
        path,
      };
    }
  }
  getConfigs(rootDir, exclude) {
    const ignore = exclude.map(
      (ele) => `mock${ele.startsWith("/") ? "" : "/"}${ele}`
    );
    const mockFiles = fg
      .sync(MOCK_FILE_PATTERN, {
        cwd: rootDir,
        ignore,
      })
      .map((file) => path.join(rootDir, file));
    const mockConfigs = [];
    mockFiles.forEach((mockFile) => {
      // disable require cache
      delete require.cache[mockFile];
      let mockModule;
      try {
        mockModule = require(mockFile);
      } catch (error) {
        console.error(`Failed to parse mock file ${mockFile}`);
        console.error(error);
        return;
      }
      const config = mockModule.default || mockModule || {};
      for (const key of Object.keys(config)) {
        const { method, path } = this.parseMockKey(key);
        const handler = config[key];
        if (
          !(
            typeof handler === "function" ||
            typeof handler === "object" ||
            typeof handler === "string"
          )
        ) {
          console.error(
            `mock value of ${key} should be function or object or string, but got ${typeof handler}`
          );
        }
        mockConfigs.push({
          method,
          path,
          handler,
        });
      }
    });
    return mockConfigs;
  }
  matchPath(req, mockConfigs) {
    for (const mockConfig of mockConfigs) {
      const keys = [];
      if (req.method.toLocaleUpperCase() === mockConfig.method) {
        const re = pathToRegexp(mockConfig.path, keys);
        const match = re.exec(req.path);
        if (re.exec(req.path)) {
          return {
            keys,
            match,
            mockConfig,
          };
        }
      }
    }
  }
  decodeParam(val) {
    if (typeof val !== "string" || val.length === 0) {
      return val;
    }
    try {
      return decodeURIComponent(val);
    } catch (error) {
      if (error instanceof URIError) {
        error.message = `Failed to decode param ' ${val} '`;
        error.status = 400;
        error.statusCode = 400;
      }
      throw error;
    }
  }
  createWatch() {
    const watchDir = this.options.rootDir;
    const watcher = chokidar
      .watch(watchDir, {
        ignoreInitial: true,
        ignored: [/node_modules/],
      })
      .on("all", () => {
        const { rootDir, exclude } = this.options;
        this.mockConfigs = this.getConfigs(rootDir, exclude);
      });
    return watcher;
  }
  createMiddleware() {
    const middleware = (req, res, next) => {
      const matchResult = this.matchPath(req, this.mockConfigs);
      if (matchResult) {
        const { match, mockConfig, keys } = matchResult;
        const { handler } = mockConfig;
        if (typeof handler === "function") {
          const params = {};
          for (let i = 1; i < match.length; i += 1) {
            const key = keys[i - 1];
            const prop = key.name;
            const val = this.decodeParam(match[i]);
            if (val !== undefined) {
              params[prop] = val;
            }
          }
          req.params = params;
          handler(req, res, next);
          return;
        } else {
          return res.status(200).json(handler);
        }
      } else {
        next();
      }
    };
    this.createWatch();
    return {
      name: "mock",
      middleware: middleware,
    };
  }
  static use(options) {
    const instance = new WebpackMiddlewareMock(options);
    const middleware = instance.createMiddleware();
    return middleware;
  }
}
module.exports = WebpackMiddlewareMock;

4. 修改webpackDevServer

修改 config/webpackDevServer.config.js 文件

引入 WebpackMiddlewareMock 中間件

const WebpackMiddlewareMock = require("./WebpackMiddlewareMock");

刪除 onBeforeSetupMiddleware 和 onAfterSetupMiddleware 選項(xiàng),替換 setupMiddlewares 選項(xiàng)

    setupMiddlewares: (middlewares, devServer) => {
      const mockMiddleware = WebpackMiddlewareMock.use({
        rootDir: paths.appPath,
      });
      middlewares.unshift(mockMiddleware);
      return middlewares;
    },

在項(xiàng)目根目錄創(chuàng)建 mock 文件夾,并創(chuàng)建 user.js 文件

module.exports = {
  // 返回值是 String 類型
  "GET /api/name": "tom",
  // 返回值 Array 類型
  "POST /api/users": [
    { name: "foo", id: 0 },
    { name: "bar", id: 1 },
  ],
  "GET /api/users/:id": (req, res) => {
    res.send({
      params: req.params,
    });
  },
  // 返回值是 Object 類型
  "DELETE /api/users/1": { name: "bar", id: 1 },
};

5. 測試mock請(qǐng)求

修改 App.js 文件

import { useState } from "react";
import axios from "axios";
function App() {
  const [resultGet, setResultGet] = useState("");
  const [resultPost, setResultPost] = useState("");
  const [resultParams, setResultParams] = useState("");
  const [resultDelete, setResultDelete] = useState("");
  const handleGet = async () => {
    const res = await axios.get("/api/name");
    setResultGet(res.data);
  };
  const handlePost = async () => {
    const res = await axios.post("/api/users");
    setResultPost(JSON.stringify(res.data));
  };
  const handleParams = async () => {
    const res = await axios.get("/api/users/100");
    setResultParams(JSON.stringify(res.data));
  };
  const handleDelete = async () => {
    const res = await axios.delete("/api/users/1");
    setResultDelete(JSON.stringify(res.data));
  };
  return (
    <div className="App">
      <button onClick={handleGet}>"GET /api/name"</button>
      <h2>{resultGet}</h2>
      <hr />
      <button onClick={handlePost}>"POST /api/users"</button>
      <h2>{resultPost}</h2>
      <hr />
      <button onClick={handleParams}>"GET /api/users/:id"</button>
      <h2>{resultParams}</h2>
      <hr />
      <button onClick={handleDelete}>"DELETE /api/users/1"</button>
      <h2>{resultDelete}</h2>
      <hr />
    </div>
  );
}
export default App;

啟動(dòng)項(xiàng)目測試

到此這篇關(guān)于在react項(xiàng)目中讓webpack使用mock數(shù)據(jù)的文章就介紹到這了,更多相關(guān)react項(xiàng)目webpack使用mock數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React組件復(fù)用導(dǎo)致的閃爍問題及通用解決方案

    React組件復(fù)用導(dǎo)致的閃爍問題及通用解決方案

    在現(xiàn)代前端開發(fā)中,React已成為一種流行的開發(fā)庫,因其組件化的特性能夠提高代碼的可復(fù)用性和可維護(hù)性,設(shè)計(jì)一個(gè)可復(fù)用的React組件不僅能減少代碼冗余,但我們?cè)谠谑褂酶咏M件時(shí),經(jīng)常會(huì)遇到閃爍問題,所以本文給大家介紹了React組件復(fù)用導(dǎo)致的閃爍問題及通用解決方案
    2025-10-10
  • react實(shí)現(xiàn)動(dòng)態(tài)表單

    react實(shí)現(xiàn)動(dòng)態(tài)表單

    這篇文章主要為大家詳細(xì)介紹了react實(shí)現(xiàn)動(dòng)態(tài)表單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • React自定義Hook-useForkRef的具體使用

    React自定義Hook-useForkRef的具體使用

    本文主要介紹了React自定義Hook-useForkRef的具體使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • React?狀態(tài)管理中的Jotai詳解

    React?狀態(tài)管理中的Jotai詳解

    Jotai是一個(gè)簡單、靈活、高效的React狀態(tài)管理庫,通過原子和派生狀態(tài)的設(shè)計(jì),使得狀態(tài)管理變得直觀和高效,它適用于小型應(yīng)用、組件庫和大型項(xiàng)目的局部狀態(tài)管理,且與TypeScript兼容,Jotai的社區(qū)正在壯大,提供了豐富的資源和支持,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例

    Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例

    這篇文章主要介紹了Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • react如何實(shí)現(xiàn)側(cè)邊欄聯(lián)動(dòng)頭部導(dǎo)航欄效果

    react如何實(shí)現(xiàn)側(cè)邊欄聯(lián)動(dòng)頭部導(dǎo)航欄效果

    這篇文章主要介紹了react如何實(shí)現(xiàn)側(cè)邊欄聯(lián)動(dòng)頭部導(dǎo)航欄效果,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 關(guān)于getDerivedStateFromProps填坑記錄

    關(guān)于getDerivedStateFromProps填坑記錄

    這篇文章主要介紹了關(guān)于getDerivedStateFromProps填坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • React Suspense 異步渲染完全指南

    React Suspense 異步渲染完全指南

    React Suspense為異步數(shù)據(jù)獲取提供了一種全新的編程范式,本文主要介紹了React Suspense異步渲染完全指南,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03
  • React根據(jù)當(dāng)前頁面路由進(jìn)行自動(dòng)高亮示例代碼

    React根據(jù)當(dāng)前頁面路由進(jìn)行自動(dòng)高亮示例代碼

    要根據(jù)當(dāng)前頁面路由自動(dòng)高亮頂部菜單項(xiàng),可以使用 React Router 的 useLocation 鉤子來獲取當(dāng)前路徑,并根據(jù)路徑動(dòng)態(tài)設(shè)置菜單項(xiàng)的高亮效果,本文給大家介紹了一個(gè)完整的示例,展示如何根據(jù)當(dāng)前頁面路由自動(dòng)高亮頂部菜單項(xiàng),需要的朋友可以參考下
    2024-07-07
  • 關(guān)于React中使用window.print()出現(xiàn)頁面無響應(yīng)問題解決記錄

    關(guān)于React中使用window.print()出現(xiàn)頁面無響應(yīng)問題解決記錄

    這篇文章主要介紹了React中使用window.print()出現(xiàn)頁面無響應(yīng)問題解決記錄,首先問題原因可能是操作了document但是并未進(jìn)行銷毀(可能是),具體問題解決思路參考下本文吧
    2021-11-11

最新評(píng)論

宝应县| 中超| 莱阳市| 齐河县| 莎车县| 荣昌县| 潜江市| 辉南县| 墨江| 荆州市| 那坡县| 金门县| 大港区| 长泰县| 平度市| 大田县| 茂名市| 康马县| 昌宁县| 武冈市| 祥云县| 中山市| 临颍县| 修水县| 齐齐哈尔市| 塔河县| 南靖县| 永和县| 西青区| 吴堡县| 巴南区| 梁山县| 嘉义市| 抚州市| 正蓝旗| 达州市| 沛县| 民勤县| 阆中市| 奎屯市| 郑州市|