import是如何“占领满屏“
import是如何“占领满屏“的?
《拒绝使用模块重导(Re-export)》
模块重导是一种通用的技术。在腾讯、字节、阿里等各大厂的组件库中都有大量使用。
如:字节的arco-design
组件库中的组件:github.com/arco-design…
通过重导在comonents/index.tsx
文件暴露所有组件,在使用时一个import就可以使用N个组件了。
javascript
// 不使用重导
import Modal from '@arco-design/web-react/es/Modal'
import Checkbox from '@arco-design/web-react/es/Checkbox'
import Message from '@arco-design/web-react/es/Message'
...// 使用模块重导
import { Modal, Checkbox, Message} from '@arco-design/web-react'
Re-export一般用于收拢同类型的模块、一般都是以文件夹为单位,如components、routes、utils、hooks、stories
等都通过各自的index.tsx暴露,这样就能极大程度的简化导入路径、提升代码可读性、可维护性。
Re-export的几种形式
1. 直接重导出
直接从另一个模块重导出特定的成员。
javascript
export { foo, bar } from './moduleA';
2. 重命名并重导出(含默认导出)
从另一个模块导入成员,可能会重命名它们,然后再导出。
默认导出也可以重命名并重导出
javascript
// 通过export导出的
export { foo as newFoo, bar as newBar } from './moduleA';
// 通过export default导出的
export { default as ModuleDDefault } from './moduleD';
3. 重导出整个模块(不含默认导出)
将另一个模块的所有导出成员作为单个对象重导出。(注意:整个导出不会包含export default)
javascript
export * from './moduleA';
4. 收拢、结合导入与重导出
首先导入模块中的成员,然后使用它们,最后将其重导出。
javascript
import { foo, bar } from './moduleA';
export { foo, bar };
通过这些形式,我们可以灵活地组织和管理代码模块。每种形式都有其适用场景,选择合适的方式可以帮助我们构建出更清晰、更高效的代码结构。
《从不使用require.context》
require.context
是一个非常有用的功能,它允许我们动态地导入一组模块,而不需要显式地一个接一个地导入。
只需一段代码让你只管增加文件、组件,将自动收拢重导。
在项目路由、状态管理等固定场景下极其好使(能提效、尽可能避免了增加一个配置要动N个文件的情况)
尤其是在配置路由时、产生大批量的import(多少个页面就得导入多少个import😅)
javascript代码解读
复制代码
// 不使用require.context
import A form '@/pages/A'
import B form '@/pages/B'
...// routes/index.ts文件统一处理
// 创建一个context来导入routes目录下所有的 .ts 文件
const routesContext = require.context('./routes', false, /.ts$/);
const routes = [];
// 遍历 context 中的每个模块
routesContext.keys().forEach(modulePath => {// 获取模块的导出const route = routesContext(modulePath);// 获取组件名称【如果需要话】,例如:从 "./Header.ts" 提取 "Header"// const routeName = modulePath.replace(/^./(.*).\w+$/, '$1');// 将组件存储在组件对象中routes.push(route.default || route)
});export default routes;
在大项目、多路由的情况下,使用 require.context
在处理路由导入上大有可为。
《从不使用import动态导入》
动态import也能实现类似require.context
的功能、动态收拢模块。关于import
动态导入的更多内容可以看下这篇文章内的介绍《如何在Vite5➕React➕Ts项目中优雅的使用Mock数据?》
《对ProvidePlugin不感兴趣》
webpack.ProvidePlugin
是个好东西,但也不能滥用。
项目中用到的变量/函数/库或工具,只要配置后就可以在任何地方使用了。
相信我--看完这个示例,如果你没用过、那你肯定会迫不及待的想要尝试了🤗
php代码解读
复制代码
const webpack = require('webpack');module.exports = {// 其他配置...plugins: [new webpack.ProvidePlugin({React: 'react',_: 'lodash',dayjs: 'dayjs',// 假设项目中自己定义的utils.js在src目录下Utils: path.resolve(__dirname, 'src/utils.js')
})})]// 其他配置...
};
现在你可以在任何地方使用 dayjs、lodash、Utils等,而不需要导入它
小结:
- webpack.ProvidePlugin是一个强大的工具,它可以帮助我们减少重复的导入语句,使代码更加干净整洁。但是,它不会减少构建大小,因为这些库仍然会被包含在你的最终打包文件中。正确使用这个插件可以提高开发效率,但需要谨慎使用,以避免隐藏依赖关系,导致代码难以理解和维护。
- 对于需要按需加载的模块或组件,考虑使用动态 import() 语法,这样可以更有效地控制代码的加载时机和减小打包体积。
- 谨慎使用 ProvidePlugin,只为那些确实需要在多个地方使用的模块配置全局变量,以避免不必要的代码打包。
另外,如果是Vite
项目可以使用vite-plugin-inject
代替ProvidePlugin
的功能
ts代码解读
复制代码
// 配置
import inject from 'vite-plugin-inject'; // 实测暂不可用,有替代方案再更新
...
plugins: [
inject({// 键是你想要提供的全局变量,值是你要提供的模块dayjs: 'dayjs', // 例如,这将在全局范围内提供 'dayjs',可以通过 dayjs 访问// 你可以继续添加其他需要全局提供的模块
}),
]
...
如果使用了TS,记得配置下类型:
ts代码解读
复制代码
// globals.d.ts文件 处理全局类型
import dayjs from 'dayjs';
declare global {const dayjs: typeof dayjs;
}// tsconfig.json文件 也配置一下
{
"compilerOptions": {
// 编译选项...
},
"include": [ "src/**/*", "globals.d.ts" // 确保 TypeScript 包括这个文件 ]
}
《大量使用Typescript导入类型》
在TS项目中,满屏import肯定少不了TS的份。但如果合理配置,必定能急剧减少import的导入
这里介绍下自己在项目中使用最多的方法:TS命名空间。有了它既能让类型模块化,更过分的是在使用时可以直接不导入类型😅。
同样,它和ProvidePlugin
一样炸裂,可以直接灭掉import
导入。
使用示例:
typescript代码解读
复制代码
// accout.ts
declare namespace IAccount {type IList<T = IItem> = {count: numberlist: T[]}interface IUser {id: number;name: string;avatar: string;}
}// 任意文件直接使用,无需导入
const [list, setList] = useState<IAccount.IList|undefined>();
const [user, setUser] = useState<IAccount.IUser|undefined>();
注意⚠️eslint可能需要配置下开启🔛使用命名空间
《不去充分利用bable特性》
React
似乎也意识到不妥:在17版本之前,由于jsx
的特性每个组件都需要明文引入import React from 'react'
,但在这之后由编译器自行转换,无需引入 React。如果你使用的React17之前的版本也可以通过修改babel达到这个目的,更多细节可参考React官网,有非常详细的说明。(也提供了自动去除引入的脚本)
其它
1. 设置webpack、ts别名。
既能缩短导入路径、也能更有语义化
javascript代码解读
复制代码
resolve: {alias: {"@src": path.resolve(__dirname, 'src/'),"@components": path.resolve(__dirname, 'src/components/'),"@utils": path.resolve(__dirname, 'src/utils/')}
}// 使用别名前
import MyComponent from '../../../../components/MyComponent';// 使用别名后
import MyComponent from '@components/MyComponent';
2. 设置格式化prettier.printWidth
值设置的太小可能会导致频繁换行、给够难以阅读。其值在120较为合适吧(看团队实际的使用情况)。
json代码解读
复制代码
{"printWidth": 120,...
}
3. 按条件动态全局加载组件
在入口文件引入全局组件,使用require.ensure或import根据条件动态加载组件,既能便于维护、减少引用、也能减少性能开销
javascript
// 异步加载全局弹窗,减少性能开销
Vue.component('IMessage', function (resolve) {// 指定条件全局加载,无需在具体页面中引用if (/^/pagea|pageb/.test(location.pathname)) {require.ensure(['./components/message/index.vue'], function() {resolve(require('./components/message/index.vue'));});}
});
4. babel-plugin-import的使用
babel-plugin-import
不是直接减少 import 的数量,而是通过优化 import 语句来减少打包体积,提高项目的加载性能。这对于使用了大型第三方库的项目来说是一个非常有价值的优化手段。
以arco-design
为例:
json
// .bablerc配置
{"plugins": [["import", {"libraryName": "@arco-design/web-react","libraryDirectory": "es", // 或者 "lib",依赖于具体使用的模块系统"style": true // 加载 CSS}, "@arco-design/web-react"]]
}
// 这个配置告诉 babel-plugin-import 自动将类似 import { Button } from '@arco-design/web-react'; 的导入语句转换为按需导入的形式,并且加载对应的 CSS 文件。
ts
// 业务中使用
import { Button } from '@arco-design/web-react';
// 将被bable编译成
import Button from '@arco-design/web-react/es/button';
import '@arco-design/web-react/es/button/style/css.js'; // 如果 style 配置为 true
总结
导致import占满全屏的原因有很多。但不用模块重导、require.context、import动态导入、webpack.ProvidePlugin
等手段,一定会让我们写出满屏的import😂🤣😅😇。
只有想不到的,没有做不到的。只要你想、相信就一定能如愿以偿。
相关文章:

import是如何“占领满屏“
import是如何“占领满屏“的? 《拒绝使用模块重导(Re-export)》 模块重导是一种通用的技术。在腾讯、字节、阿里等各大厂的组件库中都有大量使用。 如:字节的arco-design组件库中的组件:github.com/arco-design… …...
ceph /etc/ceph-csi-config/config.json: no such file or directory
环境 rook-ceph 部署的 ceph。 问题 kubectl describe pod dragonfly-redis-master-0Warning FailedMount 7m59s (x20 over 46m) kubelet MountVolume.MountDevice failed for volume "pvc-c63e159a-c940-4001-bf0d-e6141634cc55" : rpc error: cod…...

C语言——验证“哥德巴赫猜想”
问题描述: 验证"哥德巴赫猜想" 任何一个大于2的偶数都可以表示为两个质数之和。例如,4可以表示为22,6可以表示为33,8可以表示为35等 //验证"哥德巴赫猜想" //任何一个大于2的偶数都可以表示为两个质数之和…...

Flourish笔记:柱状图(Column chart (grouped))
文章目录 样式设定Chart Type:图表类型Controls & Filters:展示方式Colors:颜色bars:柱子的调整labels:柱子数字标注X axis:横坐标标签Y axis:纵坐标标签Plot BackgroundNumber FormatingLe…...

深度学习案例:DenseNet + SE-Net
本文为为🔗365天深度学习训练营内部文章 原作者:K同学啊 一 回顾DenseNet算法 DenseNet(Densely Connected Convolutional Networks)是一种深度卷积神经网络架构,提出的核心思想是通过在每一层与前面所有层进行直接连接…...
excel文件合并,每个excel名称插入excel列
import pandas as pd import os # 设置文件夹路径 folder_path rC:\test # 替换为您的下载文件夹路径 output_file os.path.join(folder_path, BOM材料.xlsx) # 创建一个空的 DataFrame 用于存储合并的数据 combined_data pd.DataFrame() # 遍历文件夹中的所有文件 for …...
Linux 如何设置特殊权限?
简介 通过使用 setuid、setgid 、sticky,它们是 Linux 中的特殊权限,可以对文件和目录的访问和执行方式提供额外的控制。 命令八进制数字功能setuid4当执行文件时,它以文件所有者的权限运行,而不是执行它的用户的权限运行。setg…...

零基础如何使用ChatGPT快速学习Python
引言 AI编程时代来临,没有编程基础可以快速上车享受时代的红利吗?答案是肯定的。本文旨在介绍零基础如何利用ChatGPT快速学习Python编程语言,开启AI编程之路。解决的问题包括:传统学习方式效率低、缺乏互动性以及学习资源质量参差…...

【开源】一款基于SpringBoot 的全开源充电桩平台
一、下载项目文件 下载源码项目文件口令:动作璆璜量子屏多好/~d1b8356ox2~:/复制口令后,进入夸克网盘app即可保存(如果复制到夸克app没有跳转资源,可以复制粘贴口令到夸克app的搜索框也可以打开(不用点搜索按钮&#…...

AI - RAG中的状态化管理聊天记录
AI - RAG中的状态化管理聊天记录 大家好,今天我们来聊聊LangChain和LLM中一个重要的话题——状态化管理聊天记录。在使用大语言模型(LLM)的时候,聊天记录(History)和状态(State)管理是非常关键的。那我们先…...

JAVA安全—SpringBoot框架MyBatis注入Thymeleaf模板注入
前言 之前我们讲了JAVA的一些组件安全,比如Log4j,fastjson。今天讲一下框架安全,就是这个也是比较常见的SpringBoot框架。 SpringBoot框架 Spring Boot是由Pivotal团队提供的一套开源框架,可以简化spring应用的创建及部署。它提…...

【STM32系列】提升ADC采样精度的方法
资料地址 兆易创新GigaDevice-资料下载兆易创新GD32 MCU ADC简介 ADC转换包括采样、保持、量化、编码四个步骤。的采样电容上,即在采样开关 SW 关闭的过程中,外部输入信号通过外部的输入电阻 RAIN 和以及 ADC 采样电阻 RADC 对采样电容 CADC 充电。采样…...

前端面试如何出彩
1、原型链和作用域链说不太清,主要表现在寄生组合继承和extends继承的区别和new做了什么。2、推荐我的两篇文章:若川:面试官问:能否模拟实现JS的new操作符、若川:面试官问:JS的继承 3、数组构造函数上有哪些…...
Linux 切换用户的两种方法
sudo -su user1 与 su - user1 都可以让当前用户切换到 user1 的身份执行命令或进入该用户的交互式 Shell。但它们在权限认证方式、环境变量继承和 Shell 初始化过程等方面存在一些差异。 权限认证方式 su - user1 su 是 “switch user” 的缩写,默认情况下需要你输…...

Spring Boot 3 中Bean的配置和实例化详解
一、引言 在Java企业级开发领域,Spring Boot凭借其简洁、快速、高效的特点,迅速成为了众多开发者的首选框架。Spring Boot通过自动配置、起步依赖等特性,极大地简化了Spring应用的搭建和开发过程。而在Spring Boot的众多核心特性中ÿ…...

Vue实现留言板(实现增删改查)注意:自己引入Vue.js哦
代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><scri…...

IDEA创建Spring Boot项目配置阿里云Spring Initializr Server URL【详细教程-轻松学会】
1.首先打开idea选择新建项目 2.选择Spring Boot框架(就是选择Spring Initializr这个) 3.点击中间界面Server URL后面的三个点更换为阿里云的Server URL Idea中默认的Server URL地址:https://start.spring.io/ 修改为阿里云Server URL地址:https://star…...

读取电视剧MP4视频的每一帧,检测出现的每一个人脸并保存
检测效果还不错,就是追踪有点难做 import cv2 import mediapipe as mp import os from collections import defaultdict# pip install msvc-runtime# 初始化OpenCV的MultiTracker # multi_tracker = cv2.MultiTracker_create() # multi_tracker = cv2.legacy.MultiTracker_cre…...

HTML前端开发-- Iconfont 矢量图库使用简介
一、SVG 简介及基础语法 1. SVG 简介 SVG(Scalable Vector Graphics)是一种基于 XML 的矢量图形格式,用于在网页上显示二维图形。SVG 图形可以无限缩放而不会失真,非常适合用于图标、图表和复杂图形。SVG 文件是文本文件&#x…...

使用Allure作为测试报告生成器(Java+Selenium)
背景 JAVA项目中原先用Jenkinsseleniumselenium grid来日常测试UI并记录。 问题 当某一个testSuite失败时,当需要确认UI regression issue还是selenium test case自身的问题,需要去jenkins中查log,一般得到的是“Can not find element xxx…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...