为何要模块?JavaScript能不要模块吗?
首先什么是模块?模块就是一个对外提供功能的逻辑单元,当其他地方需要这个功能时,直接引入它即可,不用再重复写相应的功能逻辑,达到功能复用的目的。所以为何需要模块?模块可以做到功能或逻辑的划分,让逻辑线变得清晰,减少冗余重复代码的出现,方便进行开发和测试,也更好进行项目的控制。
JavaScript能不用模块吗?当然可以,如果JavaScript程序总体简单,引入模块反而有害。如果应用总体偏大,就有模块的必须性了,引入模块可以带来上述好处。
js模块的历史
早期,JavaScript就被设计为一种简单、弱类型、动态的语言,初衷是为了做表单验证。浏览器通过http协议将装载js代码的文件加载并执行,由于早期网页逻辑总体比较简单,文件彼此独立、没什么关联性,所以这个时候模块的意义是不明显的。
后来随着互联网的发展以及web2.0的到来,JavaScript这门简单易学并且强大的语言的很多潜在的特性被挖掘出来:ajax的应用,给web页面带来了质的飞越。各大浏览器厂商也在不断地提升对JavaScript新特性的支持。web页面也越来越复杂,各个js文件之间的关联性也越来越强,引入模块的急迫性越来越强。
由于JavaScript语言设计的时候并没有考虑到模块的问题,因此这个任务就落到了社区的肩膀上,社区首先引入了AMD规范(Asynchronous module definition ),对应的方案就是require.js。这样我们就可以通过AMD规范来在浏览器JavaScript上使用模块了。
与AMD相似的有JavaScript服务端环境的方案Commonjs规范。
ES6模块简介
此前的JavaScript总体发展平缓,后来JavaScript推出了新版本ES6,直接在语言层面定义了模块。
定义模块
// module.js
//导出多个功能项目
export function sayHi(){
console.log('hello!')
}
export const name = 'Andy law'
//一次性导出多个项目
export { name,sayHi }
//导出一个默认功能项目
export default {
name,
sayHi
}
使用模块
//main.js
//引入单个功能项目
import { sayHi} from './module.js'
//引入多个功能项目
import { sayHi,name } from './module.js'
//引入默认项目
import moduleObj from './module.js'
moduleObj.sayHi();//console.log('hello!')
moduleObj.name;// 'Andy law'
修改引入模块的名称
这里指的是针对输出多个项目的模块而言的。
//module.js
export function sayHi(){
console.log('hello,world!')
}
export const name = name
//main.js。 引入功能项目
import { sayHi as greeting,name as person} from './module.js'
创建模块对象(给模块设置命名空间,功能在命名空间下.)
此种方法是引入了模块的所有功能到一个对象身上。
//module.js
export function sayHi(){
console.log('hello,world!')
}
export const name = 'Andy law'
//main.js
//引入功能项目
import * as moduleObj from './module.js'
moduleObj.sayHi();//'hello,world!'
console.log(moduleObj.name);//'Andy law'
如果模块是默认导出的话,不要这样写,看起来怪怪的,因为默认导出本身就可以设置一个命名空间了。
//
//module.js
export default function sayHi(){
console.log('hello,world!')
}
//main.js。引入功能模块
import * as moduleObj from './module.js'
moduleObj.default();//通过default访问方法
合并模块
有的时候想直接引入并导出某个模块的功能,实现模块合并,怎么做呢?
//module1.js
export function sayHi(){
console.log('hello,world!')
}
//module2.js
export default function saySorry(){
console.log('sorry!')
}
//module3.js
export function smile(){
console.log('smile!')
}
//main.js,合并模块---引入其他模块并导出
export * from './module1.js' //导出module1的所有功能
export { default as saySorry } from './module2.js'//导出module2的默认模块
export { smile } from './module3.js'//导出module3的smile方法
动态加载模块
有时候我没不想直接加载所有模块,实现按需加载。
//module.js
export function sayHi(){
console.log('hello,world!')
}
//main.js,引入模块
document.body.onclick = ()=>{
//点击后,加载模块
import('./module.js').then(module=>{
module.sayHi()
})
}
如何在浏览器中使用模块
目录






- 引入模块时,需要在路径中包含后缀名
- 不需要在html中通过script引入模块,只需要在模块文件中通过import引入依赖的模块即可
ES6模块的现状
由于IE浏览器不支持ES6模块,因此为了兼容性,打包工具都是将ES6模块,转化为可以兼容的类似requirejs的方案。所以ES6模块定义在语言层面上独有的性能提升暂时没有得到发挥。