前端开发中为什么有些依赖必须import *引入使用详解

 更新时间:2026年03月11日 09:14:15   作者:石小石Orz  
模块化已经是现代 Web 开发必不可少的开发方式,频繁引入依赖包是一个常见的操作,这篇文章主要介绍了前端开发中为什么有些依赖必须import *引入使用的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在日常前端开发中,我们常常通过 import 来引入第三方库或模块。像这样:

import dayjs from "dayjs"
import { useState, useEffect } from 'react';

但你可能遇到过这样一种情况:有些依赖如果直接写成

import echarts from 'echarts';

会报错,或者运行时报 echarts is undefined,而必须写成:

import * as echarts from 'echarts';

这种现象可能会让你感到疑惑:为什么 ECharts 必须使用 import * 的方式?难道普通的默认导入不行吗?

本文将以 ECharts 为例,深入探讨这一问题的根源,并顺带梳理 ES Module(ESM)与 CommonJS(CJS)模块规范的差异,帮助你从底层理解 import * 背后的原因。

import的几种常见用法

在 ES Module 规范中,常见的几种导入方式包括:

默认导入

import xxx from 'module';

要求模块导出中必须有 export default xxx;

具名导入

import { a, b } from 'module';

要求模块内部有 export const aexport const b 等具名导出。

命名空间导入

import * as mod from 'module';

将模块的所有导出整合到一个对象 模块 上。

通过ECharts 的导出方式深入import *

ECharts 的导出方式

熟悉完ES6的import的命名空间导入用法,我想echarts为什么需要通过import *答案已经很明确了。我们来看看echarts的入口文件:

这三句话分别代表了三种不同的模块兼容策略:

  • import * as echarts from ...
    表示 ECharts 的所有导出都是 具名导出,并没有 export default
  • export as namespace echarts;
    这是为了兼容 UMD 模块,即在浏览器通过 <script> 直接引入时,可以挂载到全局变量 window.echarts 上。这样我们在代码里就能直接写:
echarts.init(document.getElementById('main'));
  • export = echarts;
    这是 CommonJS 风格的导出,相当于 module.exports = echarts,用于兼容 Node.js 或老的打包工具。在这种情况下,TypeScript 需要你用 import * as echarts 来导入,而不是 import echarts from 'echarts'

为什么 ECharts 没有用export default

看到这里,你可能还是有些困惑,如果导出入口改成

import * as echarts from './types/dist/echarts';
// Export for UMD module.
export as namespace echarts;
export default echarts;

我们代码里不是就可以使用下面的导入方式了吗?

import echarts from 'echarts';

原因主要有三点:

  • 兼容性考虑

ECharts 是一个全球用户量非常大的可视化库,既要兼容 ESM,又要兼容 CommonJS,还要兼容 UMD(通过 <script> 引入时挂到 window.echarts 上)。
如果用 export default,对 CJS/UMD 的支持会比较麻烦,而 export = 在 TypeScript 下能天然兼容多种模块系统。

  • 历史包袱

ECharts 最早是基于 UMD 格式发布的(早于 ES Module 普及)。
当时的入口写法更偏向:

if (typeof module === 'object' && module.exports) {
  module.exports = echarts;
} else {
  window.echarts = echarts;
}

后来迁移到 TypeScript 时,延续了 export = echarts 这种兼容写法,而不是强行改为 export default

  • API 设计思路

ECharts 官方的定位是“命名空间式 API”,也就是说,用户习惯通过 echarts.xxx() 方式调用。
为了保持这种语义一致性,团队没有提供 default export,而是把所有 API 都挂在一个 echarts 命名空间对象下。

import *的其他应用场景

除了 ECharts,还有一些库或工具函数常常需要使用 import *

  • 工具类库

有些工具库导出了非常多的函数,如果不想逐个引入,可以整合为一个命名空间对象。例如:lodash-es

import * as _ from 'lodash-es';

const arr = [1, 2, 2, 3, 4];
console.log(_.uniq(arr)); // [1, 2, 3, 4]
  • 配置性常量集合

当一个模块只导出大量的常量或枚举值时,import * 可以避免逐个列出,写法更整洁。

例如:Node.js 内置 path 模块(ESM 版本)

import * as path from 'path';

console.log(path.sep);   // 当前系统路径分隔符(Windows: '', Linux/Mac: '/')
console.log(path.resolve('./src'));

如何判断是否需要import *

如果你不确定一个库该怎么导入,可以采用以下几种方式:

看文档示例

查看源码或 d.ts 文件

如果不想找文档,可以直接打开项目的依赖

找到对应的包,导出方式在index.d.ts 文件中可以看到

Trae/Cursor智能提示

并不是所有第三方库都内置Ts支持,有index.d.ts文件,这个时候你可以借助AI编译器(如Trae或Cursor)的智能提示。

Trae的注释生成代码为例:

总结 

到此这篇关于前端开发中为什么有些依赖必须 import *引入使用的文章就介绍到这了,更多相关import *引入依赖详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Web Components入门教程示例详解

    Web Components入门教程示例详解

    这篇文章主要为大家介绍了Web Components入门教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • Echarts中legend属性使用的方法详解

    Echarts中legend属性使用的方法详解

    Echarts可以帮助我们快速构建柱状图、饼图、条形图,这对于多图形化展示数据来说尤其方便,可帮助我们快速开发,下面这篇文章主要给大家介绍了关于Echarts中legend属性使用的相关资料,需要的朋友可以参考下
    2022-04-04
  • thinkphp标签实现bootsrtap轮播carousel实例代码

    thinkphp标签实现bootsrtap轮播carousel实例代码

    这篇文章给大家介绍thinkphp标签实现bootsrtap轮播carousel实例代码,非常不错,具有参考借鉴价值,需要的的朋友参考下
    2017-02-02
  • JS实现简单抖动效果

    JS实现简单抖动效果

    这篇文章给大家结束了通过js实现抖动效果,非常不错,具有参考借鉴价值,感兴趣的朋友参考下吧
    2017-06-06
  • JS判断微信扫码的方法

    JS判断微信扫码的方法

    这篇文章通过代码给大家介绍了JS判断是否是微信扫码的方法,非常不错,需要的朋友参考下吧
    2017-08-08
  • js实现按钮加背景图片常用方法

    js实现按钮加背景图片常用方法

    这篇文章主要介绍了js实现按钮加背景图片常用方法,罗列了js事件触发控制背景图片、css样式控制以及图片按钮三种方法,非常具有实用价值,需要的朋友可以参考下
    2014-11-11
  • 深入分析js中的constructor和prototype

    深入分析js中的constructor和prototype

    在javascript的使用过程中,constructor 和prototype这两个概念是相当重要的,深入的理解这两个概念对理解js的一些核心概念非常的重要
    2012-04-04
  • 使用plupload自定义参数实现多文件上传

    使用plupload自定义参数实现多文件上传

    这篇文章主要介绍了使用plupload自定义参数实现多文件上传的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • JavaScript异步编程操作实现介绍

    JavaScript异步编程操作实现介绍

    异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念。在我们学习的传统单线程编程中,程序的运行是同步的,同步不意味着所有步骤同时运行,而是指步骤在一个控制流序列中按顺序执行,而异步的概念则是不保证同步的概念
    2022-09-09
  • JavaScript中数组的22种方法必学(推荐)

    JavaScript中数组的22种方法必学(推荐)

    这篇文章主要介绍了JavaScript中数组的22种方法必学(推荐)的相关资料,需要的朋友可以参考下
    2016-07-07

最新评论