前端JavaScript模块化解析之ESModule用法示例

 更新时间:2025年07月11日 09:25:55   作者:果壳~  
ES Module是ECMAScript 2015引入的模块化规范,通过export和import关键字实现模块的导入导出,这篇文章主要介绍了前端JavaScript模块化解析之ESModule用法的相关资料,需要的朋友可以参考下

基本介绍

  • JavaScript没有模块化一直是它的痛点,所以才会产生我们前面学习的社区规范:CommonJSAMDCMD
    所以在ES推出自己的模块化系统时,大家也是兴奋异常。
  • ES Module和CommonJS的模块化有一些不同之处
  • 一方面它使用了import和export关键字:
  • 另一方面它采用编译期的静态分析,并且也加入了动态引用的方式
  • ES Module模块采用export和import关键字来实现模块化
    • export负责将模块内的内容导出,
    • import负责从其他模块导入内容;
  • 了解:采用ES Module将自动采用严格模式:use strict

基本使用

// foo.js
export const name = "why"
export const age = "18"
// main.js
import {name,age} from "./foo.js"

console.log(name)
console.log(age)
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
    <!--这里必须设置 type="module" 否则浏览是无法识别的-->
		<script src="main.js" type="module"></script>
	</body>
</html>

让模块化生效的两个前提条件

  1. script标签要加上 type=“module”
  2. index.html的访问必须是以服务器的方式访问。也就是访问协议必须是http或者https 直接本地文件打开file://这个协议是不支持的

导入导出方式3种

// foo.js
// 导出方式
// 1. 第一种方式: export 声明语句
export const name = "why"
export const age = "18"
export function foo(){
	console.log("foo function")
}
export class Person {}
// 2. 第二种: export 导出 和 声明分开
const name = "why"
const age = "18"
function foo(){
	console.log("foo function")
}
export {
	name,
	age,
	foo
}
// 3. 第三种方式:第二种导出时起别名
const name = "why"
const age = "18"
function foo(){
	console.log("foo function")
}
export {
 	name as fName,
 	age as fAge,
 	foo as fFoo
}

导入方式

// 导入方式
// 1.导入方式1:普通导入
import {name,age,foo,Person} from "./foo.js"
// 2.导入方式二:起别名
import {name as fName,age as fAge,foo as fFoo} from "./foo.js"
// 3.导入方式三:将所有哦的内容放到一个标识符中
import * as foo from "./foo.js"

console.log(foo.name)
console.log(foo.age)

console.log(name)
console.log(age)

结合使用

当我们某个目录下有很多js文件,导出了很多工具方法如下

// utils/math.js
function add(a,b){
	return a+b;
}

function sub(a,b){
	return a-b
}

export {
	add,
	sub
}
//  utils/format.js
function timeFormat(){
	return "2222-12-12"
}

function priceFormat(){
	return "222.22"
}

export {
	timeFormat,
	priceFormat
}

然后在main.js中引入这些模块的函数,代码会变的很麻烦如下

// main.js
import {add,sub} from "./utils/math.js"
import {timeFormat,priceFormat} from './format.js'

因此一般在utils目录下会统一定义一个index.js用来将该目录下的所有需要导出的变量进行一个统一导出。如下
这样mian.js就可以只导入utils/index.js即可

// utils/index.js
// 导出方式一
import {add,sub} from './math.js'
import {timeFormat,priceFormat} from './format.js'

export {
add,
sub,
timeFormat,
priceFormat
}

导出方式一还是显得太复杂,可以结合使用

// utils/index.js
// 导出方式二:
export {add,sub} from './math.js'
export {timeFormat,priceFormat} from './format.js'

// 如果要全部导出可如下写法
// 导出方式三:
export * from './math.js'
export * from './format.js'

default用法

当写的某一个变量,是非常常用的时候,可以使用默认导出。默认导出的方式如下

// foo.js
const name = "zxh"
const age = 18 
const foo = 'foo value'

// 1.默认导出的方式一:
export {
	name,
	age,
	foo as default
}

// 2.默认导出的方式二:常见
export default foo

// 注意默认导出只能有一个

main.js在导入默认导出的变量时 如下使用

// 不用进行结构,可自定义接收的变量名 实际上是将 foo.js中的  foo赋值到aaa上
import aaa from './foo.js'

console.log(aaa)

import函数

如下代码,在执行的时候是同步执行的,
首先浏览会先将要导入的文件下载下来,进行解析,然后才会执行后续的代码。

import {name,age,foo} from './foo.js'
console.log("导入的代码没有解析完之前,后续的代码是不会运行的")

如果希望异步执行:比如页面初始化的时候并不需要用到导出的函数,只是在特定时候才需要使用。那么就可以使用import函数来进行异步执行

import("./foo.js").then(res=>{
	console.log("res:",res.name)
})

console.log("main.js 执行成功")
// 查看控制台输出,可以看出是异步执行
main.js 执行成功
res:zxh

ES Module的解析流程

具体流程省略

导入的变量无法,导入方无法修改

需要重点提醒一下:导出的变量,是不允许在导入端被修改的
如下

// foo.js
export let name = "zifeiyu"
import {name} from "./foo.js"
// 这里修改是会报错的
name = 333
// 控制台报错
Uncaught TypeError: Assignment to constant variable.
    at main.js:3:6

导出的变量,只能由导出方进行修改

// foo.js
export let name = "zifeiyu"
setTimeout(() => {
	name = "Kobe"
},100)
// main.js
import {name} from "./foo.js"
console.log(name)
setTimeout(()=>{
	console.log(name)
},2000)

可以看到控制台输出,说明导出方可以修改这个值

zifeiyu
Kobe

如果确实想在导入这边对导出的值进行修改,可以自定义set回调函数

// foo.js
export let name = "zxh"
export function setName(a){
	name = a
}
import {name,setName} from "./foo.js"
console.log(name)
setName(3333333)
console.log(name)

CommonJS和ESModule相互引用

解释一下:

  1. 模块A通过commonJS进行导出,然后模块B通过ESModule的方式进行导入。
  2. 模块C通过ESModule的方式进行导出,然后模块B通过commonJS的方式进行导入。

能否实现呢?
得分情况

  1. 浏览器:不能实现,因为默认不支持CommonJS
  2. node环境下:分情况
    1. 之前的node版本,只支持CommonJS
    2. 现在node版本逐渐在转用ESModule
  3. 正常开发环境webpack: 可以使用

实验一下

# 在一个干净的目录下
# 1.通过npm帮我们初始化一下项目,也就是生成 package.json
npm init
# 2.要使用webpack 需要安装 webpack 和 webpack-cli
npm install webpack webpack-cli -D
# 3.新建目录src,因为webpack默认的打包入库是  src/index.js

编写几个js进行互相引用
这边案例是打算

  • foo.js 通过commonjs导出
  • bar.js 通过ESmodule导出
  • index.js
    • 通过ESmodule 导入foo.js
    • 通过commonjs导入bar.js

代码如下

// src/foo.js
const fooName = "foo"
const fooAge = 18
// commonjs导出
module.exports = {
	fooName,
	fooAge
}
// src/bar.js
const barName = "foo"
const barAge = 18
// esmodule导出
export{
	barName,
	barAge
}
// src/index.js
es module
import { fooName, fooAge } from "./foo"
console.log(fooName, fooAge)


// commonjs 导入
const {barName,barAge} = require('./bar')
console.log(barName, barAge)
# 打包 会在当前命令所在目录下 创建一个dist文件夹  dist文件夹下会有一个main.js
npx webpack 

在当前目录下创建index.js 对打包后的js进行引用即可

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script src="dist/main.js"></script>
	</body>
</html>

浏览器访问可以看到正常输出,说明互相引用是可以的。

具体原理还得看main.js webpack打包出来的文件

总结

到此这篇关于前端JavaScript模块化解析之ESModule用法示例的文章就介绍到这了,更多相关JS模块化ESModule内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Bootstrap 设置datetimepicker在屏幕上面弹出设置方法

    Bootstrap 设置datetimepicker在屏幕上面弹出设置方法

    datetimepicker默认是在输入框下面弹出的,但是遇到输入框在屏幕下面时,日期选择框会有一部分在屏幕下面,显示不了,因此需要能够从上面弹出,下面小编给大家介绍下Bootstrap 设置datetimepicker在屏幕上面弹出的设置方法
    2017-03-03
  • JS实现淡蓝色简洁竖向Tab点击切换效果

    JS实现淡蓝色简洁竖向Tab点击切换效果

    这篇文章主要介绍了JS实现淡蓝色简洁竖向Tab点击切换效果,通过JavaScript相应鼠标事件实现非常简单的css样式切换,简单实用,需要的朋友可以参考下
    2015-10-10
  • JS扩展类,克隆对象与混合类实例分析

    JS扩展类,克隆对象与混合类实例分析

    这篇文章主要介绍了JS扩展类,克隆对象与混合类,通过自定义extend,clone与augment函数实例分析了类的扩展,对象的克隆与混合类相关实现与使用技巧,需要的朋友可以参考下
    2016-11-11
  • 使用JavaScript实现点击循环切换图片效果

    使用JavaScript实现点击循环切换图片效果

    本文通过实例代码给大家介绍了通过js实现点击循环切换图片效果,需要的朋友参考下
    2017-09-09
  • 使用微信小程序制作核酸检测点查询工具

    使用微信小程序制作核酸检测点查询工具

    出门在外,没有核酸证明寸步难行,此文将教你如何通过小程序制作一个工具帮你在人生地不熟的情况如何迅速找到核酸检测点,实现核酸点查询、地图导航、拨号等功能,需要的朋友可以参考下
    2022-10-10
  • IE的事件传递-event.cancelBubble示例介绍

    IE的事件传递-event.cancelBubble示例介绍

    关于event.cancelBubble,Bubble就是一个事件可以从子节点向父节点传递,下面有个不错的示例,大家可以感受下
    2014-01-01
  • js解析xml字符串和xml文档实现原理及代码(针对ie与火狐)

    js解析xml字符串和xml文档实现原理及代码(针对ie与火狐)

    分别针对ie和火狐分别作了对xml文档和xml字符串的解析,考虑到了浏览器的兼容性,至于在ajax环境下解析xml,其实原理是一样的,只不过放在了ajax里,还是要对返回的xml进行解析,感兴趣的朋友可以了解下,或许对你学习js解析xml有所帮助
    2013-02-02
  • 基于JavaScript定位当前的地理位置

    基于JavaScript定位当前的地理位置

    这篇文章主要为大家详细介绍了基于JavaScript定位当前的地理位置,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • js实现点赞按钮功能的实例代码

    js实现点赞按钮功能的实例代码

    这篇文章主要介绍了js实现点赞按钮功能,本文通过实例代码给大家介绍的非常详细,对大家的工作或学习具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • es6函数之rest参数用法实例分析

    es6函数之rest参数用法实例分析

    这篇文章主要介绍了es6函数之rest参数用法,结合实例形式分析了es6函数rest参数功能、原理、用法及操作注意事项,需要的朋友可以参考下
    2020-04-04

最新评论