大型React前端工程基础配置实践片 -- 麦克阿瑟点赞

大型React前端工程基础配置实践

React是当前最流行的前端开发框架之一,它具有高效、组件化、可扩展等特点,非常适用于大型前端工程的开发。在实际的工程开发中,为了提高开发效率、优化用户体验,我们通常会配置一些基础设置。本文将介绍如何进行大型React前端工程的基础配置实践。

一、引入依赖

入口文件作为整个项目的基础配置,从依赖上就可以看出其基础配置有哪几个模块组成;对于一般大型项目其依赖大概可以分成以下几类:

    1. react
    1. redux
    1. antd
    1. network - api
    1. international
    1. router
    1. css
javascript 复制代码
// react
import React, { useState, useEffect } from "react";

// store相关
import { Provider } from "react-redux";
import { storeInstance } from "./store";

// 组件库
import { ConfigProvider, theme } from "antd";

// 网络请求--网络数据
import {
  api1,
  getLocaleFromLocalStorageFromLocalStorage,
  api2,
  api3,
} from "./utils/api";

// 国际化相关
import { IntlProvider } from "react-intl";
import enUS from "antd/locale/en_US";
import zhCN from "antd/locale/zh_CN";
import { initKeys, initLocales } from "./locales";

// 路由以及核心组件
import { BrowserRouter, useNavigate } from "react-router-dom";
import App from "./routes";

// 全局样式文件
import "./index.less";

二、动态修改网站icon的函数

下面的这个函数提供了修改网站icon的能力,其原理就是找到head标签,然后在其中新增一个link标签,通过此link标签就可以设置、修改网站过的icon了!

javascript 复制代码
function setBroIcon(): void {
  const constant = api1();
  const imgSrc = constant?.features?.browserIcon;
  if (imgSrc) {
    const link = document.createElement("link");
    link.rel = "icon";
    link.href = `${imgSrc}`;
    document.getElementsByTagName("head")[0].appendChild(link);
  }
}

三、国际化支持

对于大型前端工程来说,国际化是一个重要的考虑因素。因此需要引入了React Intl库来实现多语言支持:

javascript 复制代码
const [lang, setLang] = useState(getLocaleFromLocalStorageFromLocalStorage()); // 获取localStorage中的语言类型
const [message, setMessage] = useState(initKeys); // 设置国际化资源
// const navigate = useNavigate();
// const [reload, setReload] = useState(false);

使用useState钩子来管理语言和国际化信息的状态。通过调用相应的API,可以获取当前的语言设置和对应的文案资源。在语言切换或文案资源更新时,使用setMessage和setLang函数来更新状态值。

四、事件处理

接下来,需要对页面上与用户交互相关的事件进行处理,以便进行相应的操作。例如:

javascript 复制代码
document.oncontextmenu = function (event) {
  event.preventDefault();
};

上述代码屏蔽了浏览器的默认右键菜单,以防止用户在页面上弹出默认的菜单选项。

javascript 复制代码
document.addEventListener('mousewheel', function (e) {
  if (((e as any)?.wheelDelta && (event as any)?.ctrlKey) || (e as any).detail) {
    event.preventDefault();
  }
}, {
  capture: false,
  passive: false
});
document.addEventListener('keydown', function (event) {
  if ((event.ctrlKey === true || event.metaKey === true) && (event.keyCode === 61 || event.keyCode === 107 || event.keyCode === 173 || event.keyCode === 109 || event.keyCode === 187 || event.keyCode === 189)) {
    event.preventDefault();
  }
}, false);

上述代码屏蔽了浏览器的缩放功能和特定的键盘操作,以防止用户对页面进行缩放或使用快捷键进行特殊操作。

五、定时清空控制台信息

javascript 复制代码
useEffect(() => {
  const id = setInterval(() => {
    console.clear();
  }, 10 * 60 * 1000);
  return () => {
    clearInterval(id);
  };
}, []);

以上代码利用了React的useEffect钩子,在组件加载后每隔10分钟清除一次控制台信息。这样可以避免因为控制台输出过多导致页面卡顿的问题。

六、全局信息配置

在入口文件中进行组件的渲染。使用Context,将状态管理和多语言支持的相关信息传递给子组件:

javascript 复制代码
return reload ? (
  <></>
) : (
  <ConfigProvider
    theme={{
      algorithm: theme.compactAlgorithm,
    }}
    locale={lang !== "zh-CN" ? enUS : zhCN}
  >
    <Provider store={storeInstance}>
      <IntlProvider locale={lang} messages={message}>
        <App />
      </IntlProvider>
    </Provider>
  </ConfigProvider>
);
  • 使用ConfigProvider提供了一些全局的配置项,比如主题和布局
  • 使用Provider将状态管理的上下文信息传递给子组件
  • 使用IntlProvider实现了多语言支持

七、内部更新

在在组件中监听特定几个事件,事件被触发的时候就强行刷新根组件,从而导致整个页面刷新;从而实现内部强制刷新整个页面的功能

jsx 复制代码
  useEffect(() => {
    const OtherReload = () => {
      setReload(true);
      setTimeout(() => {
        setReload(false);
      }, 100);
    };
    const handleLangChange = async (event) => {
      await initLocales();
      setMessage(() => initKeys);
      setLang(() => getLocaleFromLocalStorage());
      OtherReload();
    };

    const refresh = () => {
      OtherReload();
    };

    document.addEventListener("language-change", handleLangChange);
    document.addEventListener("other-reload", publishReload);
    document.addEventListener("force-refresh", refresh);
    return () => {
      document.removeEventListener("publish-reload", OtherReload);
      document.removeEventListener("other-change", handleLangChange);
      document.removeEventListener("force-refresh", refresh);
    };
  }, [navigate, setReload, setMessage, setLang]);

八、路由管理

将整个应用包裹在BrowserRouter组件中,实现路由管理的功能:

javascript 复制代码
export default function Root(props) {
  return (
    <BrowserRouter>
      <BigWrapper />
    </BrowserRouter>
  );
}

全部代码

jsx 复制代码
// react
import React, { useState, useEffect } from "react";

// store相关
import { Provider } from "react-redux";
import { storeInstance } from "./store";

// 组件库
import { ConfigProvider, theme } from "antd";

// 网络请求--网络数据
import {
  api1,
  getLocaleFromLocalStorageFromLocalStorage,
  api2,
  api3,
} from "./utils/api";

// 国际化相关
import { IntlProvider } from "react-intl";
import enUS from "antd/locale/en_US";
import zhCN from "antd/locale/zh_CN";
import { initKeys, initLocales } from "./locales";

// 路由以及核心组件
import { BrowserRouter, useNavigate } from "react-router-dom";
import App from "./routes";

// 全局样式文件
import "./index.less";

function setBroIcon(): void {
  const constant = api1();
  const imgSrc = constant?.features?.browserIcon;
  if (imgSrc) {
    const link = document.createElement("link");
    link.rel = "icon";
    link.href = `${imgSrc}`;
    document.getElementsByTagName("head")[0].appendChild(link);
  }
}

function BigWrapper(props) {
  const [lang, setLang] = useState(getLocaleFromLocalStorage());
  const [message, setMessage] = useState(initKeys);
  const navigate = useNavigate();
  const [reload, setReload] = useState(false);

    setBroIcon();

  // 屏蔽浏览器默认右键菜单
  document.oncontextmenu = function (event) {
    event.preventDefault();
  };

  // 屏蔽浏览器缩放功能
  document.addEventListener('mousewheel', function (e) {
      if (((e as any)?.wheelDelta && (event as any)?.ctrlKey) || (e as any).detail) {
        event.preventDefault();
      }
    }, {
      capture: false,
      passive: false
  });
  document.addEventListener('keydown', function (event) {
      if ((event.ctrlKey === true || event.metaKey === true) && (event.keyCode === 61 || event.keyCode === 107 || event.keyCode === 173 || event.keyCode === 109 || event.keyCode === 187 || event.keyCode === 189)) {
        event.preventDefault();
      }
  }, false);

  useEffect(() => {
    const id = setInterval(() => {
      console.clear();
    }, 10 * 60 * 1000);
    return () => {
      clearInterval(id);
    };
  }, []);

  useEffect(() => {
    const OtherReload = () => {
      setReload(true);
      setTimeout(() => {
        setReload(false);
      }, 100);
    };
    const handleLangChange = async (event) => {
      await initLocales();
      setMessage(() => initKeys);
      setLang(() => getLocaleFromLocalStorage());
      OtherReload();
    };

    const refresh = () => {
      OtherReload();
    };

    document.addEventListener("language-change", handleLangChange);
    document.addEventListener("other-reload", publishReload);
    document.addEventListener("force-refresh", refresh);
    return () => {
      document.removeEventListener("publish-reload", OtherReload);
      document.removeEventListener("other-change", handleLangChange);
      document.removeEventListener("force-refresh", refresh);
    };
  }, [navigate, setReload, setMessage, setLang]);

  return reload ? (
    <></>
  ) : (
    <ConfigProvider
      theme={{
        algorithm: theme.compactAlgorithm,
      }}
      locale={lang !== "zh-CN" ? enUS : zhCN}
    >
      <Provider store={storeInstance}>
        <IntlProvider locale={lang} messages={message}>
          <App />
        </IntlProvider>
      </Provider>
    </ConfigProvider>
  );
}

export default function Root(props) {
  return (
    <BrowserRouter>
      <BigWrapper />
    </BrowserRouter>
  );
}
相关推荐
IT女孩儿1 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡2 小时前
commitlint校验git提交信息
前端
虾球xz2 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇3 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒3 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员3 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐3 小时前
前端图像处理(一)
前端
程序猿阿伟3 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒3 小时前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪3 小时前
AJAX的基本使用
前端·javascript·ajax