Es6-Module

JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require、Python 的import,甚至就连css 都有@import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。

在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

两个命令 expont 和 import

  expont  命令用于规定模块的对外接口

import命令用于输入其他模块提供的功能

 expont:

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量

下面是一个 JS 文件,里面使用export命令输出变量。

 // profile.js

  export var firstName = 'Michael';

 export var  lastName ='Jackson';

 export var year=1958;

 import

使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。

export default 命令

export default命令,为模块指定默认输出。

 // export-default .js

export default function(){console.log('foo');}

以上默认输出一个函数

export default命令用在非匿名函数前,也是可以的

// export-default .js

export default function foo(){console.log('foo');}

// 或者写成 function foo(){console.log('foo');}export default foo;

上面代码中,foo函数的函数名foo,在模块外部是无效的。加载的时候,视同匿名函数加载。

export 与 import 的复合写法

如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起。

export {foo,bar}   from    'my_module';

// 等同于 import  {foo,bar}  from   'my_module';

           export  {foo,bar};

import()的用法及场景

import命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适)。

// 报错if(x===2){

import MyModual   from   './myModual';

}

上面代码中,引擎处理import语句是在编译时,这时不会去分析或执行if语句,所以import语句放在if代码块之中毫无意义,因此会报句法错误,而不是执行时错误。也就是说,import和export命令只能在模块的顶层,不能在代码块之中(比如,在if代码块之中,或在函数之中)。

这样的设计,固然有利于编译器提高效率,但也导致无法在运行时加载模块。在语法上,条件加载就不可能实现。如果import命令要取代 Node 的require方法,这就形成了一个障碍。因为require是运行时加载模块,import命令无法取代require的动态加载功能。

const path='./'+ fileName;

const myModual=require(path);

上面的语句就是动态加载,require到底加载哪一个模块,只有运行时才知道。import语句做不到这一点。

import()返回一个 Promise 对象

const main=document.querySelector('main');

import(`./section-modules/${someVariable}.js`)

.then(module=>{module.loadPageInto(main);})

.catch(err=>{main.textContent=err.message;});

import()函数可以用在任何地方,不仅仅是模块,非模块的脚本也可以使用。它是运行时执行,也就是说,什么时候运行到这一句,也会加载指定的模块。另外,import()函数与所加载的模块没有静态连接关系,这点也是与import语句不相同。

import()类似于 Node 的require方法,区别主要是前者是异步加载,后者是同步加载。

场景:

1)按需加载。

import()可以在需要的时候,再加载某个模块。

(2)条件加载

import()可以放在if代码块,根据不同的情况,加载不同的模块

(3)动态的模块路径

import()允许模块路径动态生成。

你可能感兴趣的:(Es6-Module)