MENU
noBannerImage__isTrue ? 'no-banner-image': ''?>" style=" height: 90;">

优雅解决项目中重复多次important

• October 27, 2021 • Read: 840 • Web Program

适用场景说明

当我们在React/Vue等使用webpack构建项目中需要大量使用important 来引入我们所需要的模块时。就像下面这样。

例如React/Vue 的路由或者store部分。

import A from 'components/A'
import B from 'components/B'
import C from 'components/C'
import D from 'components/D'
// ...

解决方法

require.context(directory, useSubdirectories, regExp)

  1. directory: 要查找的文件路径(String)
  2. useSubdirectories: 是否查找子目录(为布尔值)
  3. regExp: 要匹配文件的正则
就像下面一样使用
//寻找当前目录下所有ts文件(包含子目录)
const modulesFiles = require.context("./", true, /\.ts$/);
//一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块
值得注意的是

require.context函数执行后返回的是一个函数,并且这个函数有3个属性

  1. keys: 返回匹配成功模块的名字组成的数组
  2. resolve: 接受一个参数requestrequest返回这个匹配文件相对于整个工程的相对路径。
  3. id: 执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载。

当然上面的我也没看懂 ,直接整活就Vans了

在我的项目中使用到了mobx作为全局状态管理 ,把store要挂载到全局时,我是这么写的。

/*
 * @Author: XiaoHuwei
 * @Date: 2021-10-27 20:04:33
 * @LastEditors: XiaoHuwei
 * @LastEditTime: 2021-10-27 22:27:50
 * @FilePath: /txcb_mini/src/store/index.ts
 */
import React from "react";

//遍历同级目录包含ts子文件 自动加载./store下面所有store 实现全量注册
const modulesFiles = require.context("./", true, /\.ts$/);
//组成store的集合
const allStore = modulesFiles.keys().reduce((allStore, modulePath) => {
  //根据模块路径取到该模块
  const value = modulesFiles(modulePath);
  //不包含本文件
  if (modulePath !== "./index.ts") {
    //获取到仓库名 获取该模块下面所有初始值
    allStore[value.default.storeName] = value.default;
  }
  return allStore;
}, {});

const StoresContext = React.createContext({
  ...allStore,
});

export const useStores = () => React.useContext(StoresContext);

我的一个store之一代码如下

/*
 * @Author: XiaoHuwei
 * @Date: 2021-10-11 11:47:36
 * @LastEditors: XiaoHuwei
 * @LastEditTime: 2021-10-27 21:46:59
 * @FilePath: /txcb_mini/src/store/home/counter.ts
 */
import { observable } from "mobx";
import { getLogin } from "@/service/test";
const counterStore = observable({
  //////仓库名 重要部分!!storeName 该变量每次声明仓库必填!
  storeName: "counterStore",
  counter: 0,
  loading: "false",
  Login(data) {
    this.loading = "true";
    getLogin(data)
      .then((res) => {
        console.log(res.data);
        this.loading = "true";
      })
      .catch((error) => console.log(error));
  },
  increment() {
    this.counter++;
  },
  decrement() {
    this.counter--;
  },
  incrementAsync() {
    setTimeout(() => {
      this.counter++;
    }, 1000);
  },
});

export default counterStore;

市面上有一套架构体系(umi+dva),相信同学们用过,他的store写在modules文件下即可实现全局调用,效果跟这一样,实际上是umi在底部为我们单独做了处理。

Archives QR Code
QR Code for this page
Tipping QR Code