ES Modules(浏览器模块化标准规范)
- 模块系统(有兼容性)
- 与AMD比较在语言层面实现了模块规范
基本特性(语法特性)
- ES Module自动采用严格模式(use strict)
- 每个ES Module都是运行在单独的私有作用域中
- ES Module是通过CORS 的方式请求外部JS模块的(如果需要请求一个外部地址,则需要服务端支持CORS的请求,要不就会报跨域的问题,CORS不支持文件形式的访问,必须是http-serve(本地运行服务)的形式运行工作)
- ES Module的script标签会延迟执行脚本(网页渲染后再进行脚本运行,不会阻碍页面元素显示)
导入和导出(核心功能)import(模块内导入其他模块的接口-导入)export(模块内对外暴露接口-导出)
导出(export)
1.export class Person{}
2.// ES Moduls 第二种导出
let name='chenhan'
function hello(){}
class Person{}
export{ name ,hello,Person}
// 导出的方式为import { name ,hello,Person} from 'esModuleExport'
// 可以通过as对导出的名称进行重命名
export{name as fooName}
// 导入的方式为 import {fooName} from 'esModuleExport'
// ES Module 特殊导出情况
// 1.将导出的名称设置为default即export{name as default},在导入时需要使用as重新命名import {default as fooName} from 'esModuleExport'
// 2.直接通过export default name 导出变量名 ,在导入时,可以使用任意变量名接受export default导入过来的变量
// import name from 'esModuleExport' 或者 import foolName from 'esModuleExport'
导入和导出的注意事项
- export{}和import{}中的大括号是一个固定的语法,不是对象自变量,如果需要导出对象需要使用export default{}
- export导出的变量只是导出一个引用关系
- import导入的自变量只是一个只读,不能进行修改
导入用法import
- import在导入模块是from后面跟着的是路径,需要使用完整的路径名称:即(import {name} from './esModuleExport.js'),不能像在common.js中省略文件后缀(拓展名)(import {name} from './esModuleExport')
- ES Module中不能省略某个文件夹下的index.js,只能这样导入例如(import {name} from './utils/index.js'),不能像common.js中的(import {name} from './utils')
- import导入内部文件时from的路径必须是以点开头(.),如果不是以点开头,在ES module中会认为是第三方插件(模块),与common.js中用法相同
- ./是相对路径-用法(./module.js); /是绝对路径-用法(/04-import/module.js);通过url导入模块-用法(http://localhost:3000/04-import/module.js)(import {name} from 'http://localhost:3000/04-import/module.js'),
- 直接使用import{}from'./module.js'方式,只会执行模块,不会提取模块中的成员——————简写的语法 import './esModuleExport.js'
- 如果导出的成员多,在导入时可以使用*的方式表达,通过as方式重新命名到新的变量中(import * as mod from './esModuleExport.js'),需要导入的多个成员就会在mod对象中以属性的方式呈现
- import关键字只能出现在最顶层,不能嵌套在函数中或者if语句中,如何进行动态的导入模块:例如
import ('./esModuleExport.js').then(function(module){//import('./esModuleExport.js')导入会返回一个promise函数
console.log(module)//module对象中包含了参数
})
- 同时导出了命名成员(export {name,age})和默认成员export default {name,age},怎么样进行导入的处理的方式
<!-- 第一种 -->
import {name ,age ,default as other}from './esModuleExport.js'
<!-- 第二种 -->
impor other ,{name ,age} from './esModuleExport.js'//other是用于提取默认成员;命名方式任意取(import abs,{name,age} from './esModuleExport.js'),后面用于{}中提出命名成员
ES Modules 直接导出导入成员
<!-- 使用场景,在相同目录文件夹下多个不同的js文件中想要导出不同的自变量,且js名称不能命名为index.js,可以在index.js文件中直接使用export代替import先导入再导出 -->
//index.js
// import {a} from './abc.js'
// import {b} from './bcd.js'
// export {a,b}
// 简写方式
export {a} from './abc.js'
export {b} from './bcd.js'
//abc.js
export let a='123'
//bcd.js
export let b='456'
//最后要使用的地方other.js
import {a,b}from './component/index.js'
特殊情况:导出默认default,需求使用as进行重命名
//index.js
// 简写方式
export {default as a} from './abc.js'
export {b} from './bcd.js'
//abc.js
let a='123'
export default a
//bcd.js
export let b='456'
ES Modules in browser (浏览器)ie不兼容
Polyfill兼容方案支持ES Modules中绝大多数特性(兼容ie)
<!-- 以下操作只适合在开发环境(本地测试或者开发)的时候适用 -->
//由于polyfill是npm包,可以是用unpkg.com动态获取js文件
//unpkg.com/browser/browser-es-module-loader@0.4.1/dist/——这样可以dist文件夹下的文件内容(dist后面无/,会走默认文档),分别选择babel-browser-build.js(babel及时运行浏览器下文件)和browser-es-module-loader.js(es modules 核心)引用到页面
//在index.html文件中通过script中src属性进行添加到页面
//由于在ie浏览器中不支持promise需要针对ie浏览器额外引入一个promise-polyfill插件支持
//上述操作对于支持ES modules的浏览器会执行两次代码,需要借助于script中nomodule属性区分(nomodule会在不支持ES modules的浏览器中运行)
<script nomodule src="http://unpkg.com/promise-polyfill@8.1.3/dist/polyfill.min.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/babel-browser-build.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js"></script>
<script type="module">
import {name} from './esModuleExport.js'
// console.log('this is es module')
</script>