Managing and Optimizing Import Statements in Frontend Projects
This article explains why import statements can fill an entire file, examines the problems caused by excessive imports, and presents practical techniques such as module re‑export, require.context, dynamic import, webpack ProvidePlugin, Vite plugins, TypeScript namespaces, aliasing, and Babel plugins to keep import sections concise and maintainable.
Preface
Seeing a file filled with import statements can be overwhelming and challenges code organization. This article explores why imports dominate a file, the issues they cause, and how to manage them elegantly.
How Do Imports Fill the Screen?
Rejecting Module Re‑export
Module re‑export is widely used in component libraries of major companies. For example, the Arco Design library exposes all components through components/index.tsx , allowing a single import to bring in many components.
// Without re‑export
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'
...
// With re‑export
import { Modal, Checkbox, Message } from '@arco-design/web-react'Re‑export typically gathers modules of the same type (e.g., components, routes, utils, hooks) into an index.tsx file, simplifying import paths and improving readability and maintainability.
Forms of Re‑export
1. Direct Re‑export
export { foo, bar } from './moduleA';2. Renamed Re‑export (including default)
// Named re‑export
export { foo as newFoo, bar as newBar } from './moduleA';
// Default re‑export renamed
export { default as ModuleDDefault } from './moduleD';3. Export Everything (excluding default)
export * from './moduleA';4. Import Then Re‑export
import { foo, bar } from './moduleA';
export { foo, bar };Choosing the appropriate form helps build a clearer and more efficient code structure.
Using require.context
require.context enables dynamic import of a group of modules without listing each one, which is especially useful for routing or state‑management files where many pages need to be imported.
// Without require.context
import A from '@/pages/A'
import B from '@/pages/B'
...
// Using require.context in routes/index.ts
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;Dynamic import()
Dynamic import() can achieve similar functionality to require.context , allowing on‑demand loading of modules.
webpack ProvidePlugin
The webpack.ProvidePlugin automatically injects specified modules (e.g., React, lodash, dayjs) wherever they are used, reducing repetitive import statements.
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.ProvidePlugin({
React: 'react',
_: 'lodash',
dayjs: 'dayjs',
Utils: path.resolve(__dirname, 'src/utils.js')
})
]
};While it cleans up code, it does not shrink bundle size because the libraries are still included.
Vite Alternative – vite-plugin-inject
import inject from 'vite-plugin-inject';
export default {
plugins: [
inject({
dayjs: 'dayjs',
// add other globals here
})
]
};Massive TypeScript Import Types
Using TypeScript namespaces can eliminate the need to import type definitions explicitly.
// accout.ts
declare namespace IAccount {
type IList
= {
count: number;
list: T[];
};
interface IUser {
id: number;
name: string;
avatar: string;
}
}
// Anywhere without import
const [list, setList] = useState
();
const [user, setUser] = useState
();Other Practical Tips
1. Configure Webpack/TS Aliases
resolve: {
alias: {
"@src": path.resolve(__dirname, 'src/'),
"@components": path.resolve(__dirname, 'src/components/'),
"@utils": path.resolve(__dirname, 'src/utils/')
}
}
// Usage
import MyComponent from '@components/MyComponent';2. Adjust Prettier printWidth
{
"printWidth": 120,
...
}3. Dynamically Load Global Components
// Asynchronously load a global modal
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. Use babel-plugin-import for On‑Demand Imports
// .babelrc
{
"plugins": [
["import", {
"libraryName": "@arco-design/web-react",
"libraryDirectory": "es",
"style": true
}, "@arco-design/web-react"]
]
}
// Transformed code
import Button from '@arco-design/web-react/es/button';
import '@arco-design/web-react/es/button/style/css.js';Conclusion
Various techniques—module re‑export, require.context , dynamic import() , webpack ProvidePlugin, Vite inject plugin, TypeScript namespaces, aliasing, and Babel plugins—can dramatically reduce the visual clutter of import statements and improve code maintainability.
When you think creatively, almost any import‑related problem can be solved.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.