浏览器端模块化方式es module详解
index.html
<script src="b.js" type="module"></script>
这样浏览器才能执行使用es module的js文件,定义之后就可以在对应的js文件中使用模块化的方式来编写文件,导出和导入的方式有几种,但都是相同的关键字,export 与 import,一起来看看可以如何定义导入导出。
a.js export const name = 'alice' export const age = 16 b.js import { name, age } from "./a.js"; console.log(name, age) // alice 16
第二种,先定义变量,再使用 export 一起导出,导入方式可以使用上面的方式,也可以通过一个 * 来将所有的导出内容定义为一个对象,从对象中再去取值 ,redux中定义的reducer、action在 index.js 中导出会经常使用这种方式
a.js const name = 'alice' const age = 16 export { name, age } b.js import * as obj from "./a.js"; console.log(obj.name, obj.age) // alice 16
第三种,给导出的变量取别名,导入的变量同样可以取别名,当名字发生冲突时、导出变量名太长时,都可以取个别名,取完别名之后,原先的名字就不可用了
a.js const name = 'alice' const age = 16 export { name as myName, age as myAge } b.js import { myName as aliceName, myAge } from "./a.js"; console.log(aliceName, myAge) // alice 16
第四种,默认导出,默认导出在一个js文件中只允许存在一个,默认导出可以不用定义变量名,在导入的时候可以随意起名,并且导入的时候不需要加 {} ,这样的定义方式在编写redux中的reducer函数时很常见
a.js export default function(){ return 'hello world' } b.js import foo from './a.js' console.log(foo()) // hello world
第五种,合并导出,在b.js文件导入a.js文件中导出的内容,b.js文件不对导入的内容做任何操作,直接导出,最后由index.js导入b.js并进行处理
a.js export const name = 'alice' b.js export { name } from './a.js' index.js import { name } from './b.js' console.log(name) // alice
以上是es module的具体的语法表现,导入导出的方式有很多,可以根据具体需要的场景进行判断和使用,另外,es module 还有一些特点。
<script src="index.js" type="module"></script> <script type="text/javascript"> console.log('hi') </script>
2、编译时解析,简单来说javascript的执行过程需要将原代码编译成抽象语法树,运行的时候再转成机器可识别的语言,在编译阶段解析数据,并不知道该不该加载此js文件,只有等到文件运行时,才知道文件里具体逻辑的执行过程,所以不能够在编译时解析的模块化方式出现类似条件判断,动态引入等代码
const flag = true if(flag){ import xxx from './a.js' }
如果真的需要根据一些条件才执行代码,可以通过 require 函数来动态的引入,require函数执行完是一个promise对象,可以通过then方法来获取所需要的数据
const flag = true if(flag){ import('./b.js') .then(({name})=>{ console.log(name) }) }
let name = 'alice'
export {
name: name
}
a.js let name = 'kiki', age = 18 setTimeout(()=>{ name = '嘻嘻嘻' }, 1000) export { name, age } b.js import { name, age } from './a.js' console.log(name) setTimeout(()=>{ console.log(name) },2000) // 依次打印 kiki 嘻嘻嘻
export 导出的内容有一个模块环境记录,用来记录导出时更改的变量,当变量更改时,使用新的变量值替换旧变量值
import { name } from './a.js'
name = '哈哈哈哈'
a.mjs const name = 'alice' const age = 18 export { name, age } b.js const a = require('./a.mjs') console.log(a)
以上代码执行会报错 Must use import to load ES Module,而如下的方式在高版本的nodejs中是可以的
a.js const name = 'alice' const age = 18 module.exports = { name, age } b.js import b from './b.js' console.log(b) // { name: 'alice', age: 18 }
以上就是浏览器端模块方式es module的概念与用法,模块化能够更好的将代码分块并复用,nodejs端也有常用实现模块化的方式,即commonjs,如果不熟悉可以看看这篇文章 -> nodejs端模块化方式comomjs详解