向满屏的 Import 语句说再见!
在开发大型项目时,密集的导入语句不仅会影响代码的整洁性,也会让维护工作变得更加复杂。如何优雅地管理这些导入语句,避免“全屏占用”?本文将探讨生成大量导入语句的原因、可能带来的问题,以及如何从多个角度优化和管理导入语句。
拒绝使用模块重新导出
模块重新导出是一种常见的技术,广泛应用于大公司的组件库中,比如 Twitter、字节跳动和谷歌等。
示例:字节跳动的 Arco Design 组件库
在字节跳动的 arco-design 组件库 中,采用模块重新导出可以简化组件的使用:
// 不要使用命名导入
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'
通过 components/index.tsx
重新导出所有组件,简化了导入路径,使得代码更加简洁可读。
重新导出的几种形式
直接重新导出:从另一个模块导出特定成员。
export { foo, bar } from './moduleA';
重命名并重新导出:导入后重命名再导出。
export { foo as newFoo, bar as newBar } from './moduleA'; export { default as ModuleDDefault } from './moduleD';
重新导出整个模块(不包括默认导出):
export * from './moduleA';
合并导入和重新导出:
import { foo, bar } from './moduleA'; export { foo, bar };
这些方式让我们能够灵活管理模块,提升代码的组织性。
使用 require.context
require.context
是一个强大的工具,能够动态导入模块,尤其适用于项目路由和状态管理等场景。在有大量页面时,这可以减少显式的导入操作:
const routesContext = require.context('./routes', false, /.ts$/);
const routes = [];
routesContext.keys().forEach(modulePath => {
const route = routesContext(modulePath);
routes.push(route.default || route);
});
export default routes;
使用动态导入
动态导入可以按需加载模块,有效地减少初始包的大小,提高性能。与 require.context
类似,可以动态打包模块。
对 ProvidePlugin
的谨慎使用
webpack.ProvidePlugin
可以自动为项目提供全局变量,避免每次都导入常用库:
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.ProvidePlugin({
React: 'react',
_: 'lodash',
dayjs: 'dayjs',
})
]
};
虽然 ProvidePlugin
减少了导入操作,但它不能减少打包大小。因此应谨慎使用,只在必要时配置。
大量的 TypeScript 类型导入
在 TS 项目中,大量的类型导入可能使代码显得臃肿。使用 TypeScript 的命名空间可以减少导入量:
// account.ts
declare namespace IAccount {
type IList<T = IItem> = {
count: number;
list: T[];
};
interface IUser {
id: number;
name: string;
avatar: string;
}
}
// 使用时无需导入
const [list, setList] = useState<IAccount.IList | undefined>();
const [user, setUser] = useState<IAccount.IUser | undefined>();
充分利用 Babel 功能
React 17 之前,每个文件都需要显式导入 React
。从 17 版本开始,JSX 编译器会自动导入。对于较早版本的 React,可以通过 Babel 自动处理这些导入。
其他技巧
Webpack 和 TypeScript 别名:通过别名缩短导入路径。
resolve: { alias: { "@components": path.resolve(__dirname, 'src/components/') } }
Prettier 的
printWidth
配置:合理的printWidth
(如 120)可以避免过多换行,提升代码的可读性。Babel 插件
babel-plugin-import
:按需导入库,减少打包大小。{ "plugins": [ ["import", { "libraryName": "@arco-design/web-react", "libraryDirectory": "es", "style": true }] ] }
总结
大量导入语句常常是复杂项目的难题。通过模块重新导出、动态导入、webpack.ProvidePlugin
、TypeScript 命名空间等技术,我们可以大幅减少显式导入,提升代码的整洁性和可维护性。