前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[第20期] 全面了解 ES6 Modules

[第20期] 全面了解 ES6 Modules

作者头像
皮小蛋
发布2020-03-02 10:44:42
5120
发布2020-03-02 10:44:42
举报
文章被收录于专栏:前端皮小蛋

背景

当下, 模块化已经深入到我们日常开发中。即:把一个大的 Javascript 程序分割成不同的部分, 哪个部分要被用到,就取那一部分, 按需取用。

早期, NodeJS 拥有这样的能力。 后来越来越多的库和框架也拥有了模块化的能力, 比如 CommonJS, 或者基于AMD模型的实现(比如RequireJs),还有后续的Webpack, Babel等。

一眼看上去, 我们不发现, ES6的模型系统和CommonJS语法非常的相似,毕竟ES6 的模型系统是从CommonJS时代发展过来的, 深受 CommonJS 影响。

看个简单的例子,比如在CommonJs中:

而在ES6中:

语法上,是非常相似的。

下面我们就主要看 import 和 export,和几个相关的特性,了解ES6 Modules的更多方面。

模块化的好处

模块化的好处主要是两点:

代码语言:javascript
复制
1. 避免全局变量污染
2. 有效的处理依赖关系

随着时代的演进, 浏览器原生也开始支持es6 import 和 export 语法了。

先看个简单的例子:

如果要处理事件,也是一样:

代码语言:javascript
复制
如果你想跑这个demo, 注意要起个简单的服务:
代码语言:javascript
复制
$ http-server

否则,你会看到一个 CORS 抛错。

至于抛错的具体原因和其他细节,不是本文讨论的重点, 感兴趣的可以阅读文章底部链接了解原因和相关细节。

严格模式

'use strict' 声明我们都不陌生, 在 es5 时代我们也经常使用, 一般是在文件顶部加这个声明,目的就是禁用Javascript中不太友好的一部分,有助于我们写更严谨的代码。

这个特性,在es6语法中是默认开启的, 如果代码里面有不太严格的代码,则会报错。例如:

下面是我从MDN中摘取的一些在严格模式中被禁用的部分:

export

Export 总览:

ES6模块只支持静态导出,你只可以在模块的最外层作用域使用export,不可在条件语句中使用,也不能在函数作用域中使用。

从分类上级讲, exports 主要有三种:

  1. Named Exports
  2. Default Exports
  3. Hybrid Exports

下面我就介绍一下常见的 exports用法。

1. Named exports (导出每个函数/变量)

具名导出,这种方式导出多个函数,一般使用场景比如 utils、tools、common 之类的工具类函数集,或者全站统一变量等。

只需要在变量或函数前面加 export 关键字即可。

我们也可以直接导出一个列表,例如上面的lib.js可以改写成:

2. Default exports (导出一个默认 函数/类)

这种方式比较简单,一般用于一个类文件,或者功能比较单一的函数文件使用。

一个模块中只能有一个export default默认输出。

export default 与 export的主要区别有两个:

不需要知道导出的具体变量名, import时不需要加 {}.

导出一个类:

注意这里默认导出不需要用{}。

3. Mixed exports (混合导出)

混合导出,也就是 上面第一点和第二点结合在一起的情况。

比较常见的比如 Lodash,都是这种组合方式。

再比如 Lodash 的例子:

4. Re-exporting (别名导出)

一般情况下,export输出的变量就是在原文件中定义的名字,但也可以用 as 关键字来指定别名,这样做一般是为了简化或者语义化export的函数名。

5. Module Redirects (中转模块导出)

有时候为了避免上层模块导入太多的模块,我们可能使用底层模块作为中转,直接导出另一个模块的内容如下:

代码语言:javascript
复制
export 只支持在最外层静态导出、只支持导出变量、函数、类

import

import 的用法和 export 是一一对应的,但是import支持静态导入和动态导入两种方式,动态import支持晚一些,兼容性要差一些。

另外需要注意的是,带有Module tag 的script , 是默认defer的, 没有必要在标签<script type="module"> 里加 defer。

具体细节可以参考V8文档的Module 部分, 链接在文章底部的延伸阅读。

下面我就总结下import的基本用法:

1. Import All things

当export有多个函数或变量时,如文中export的第一点,可以使用 as 关键字来导出所有函数及变量,同时 as 后面跟着的名称做为 该模块的命名空间。

2. Import a single/multiple export from a module

从模块文件中导入单个或多个函数,与 * as namepage 方式不同,这个是按需导入。

如下例子:

3. Rename multiple exports during import

和 export 一样,也可以用 as 关键字来设置别名,当import的两个类的名字一样时,可以使用 as 来重设导入模块的名字,也可以用as 来简化名称。 比如:

4. Import a module for its side effects only

有时候我们只想import一个模块进来,比如样式,或者一个类库。

5. Dynamic Imports

静态import在首次加载时候会把全部模块资源都下载下来.

我们实际开发时候,有时候需要动态 import。

例如实际用到某个模块才去加载:

es7的新用法:

总结

以上, 我总结了ES6 Module 的简单背景和 常见的 import , export 用法, 但这远远不是它的全部。篇幅太长,影响阅读体验。

如果想了解更多细节, 可以阅读底部的延伸阅读部分。

延伸阅读

https://2ality.com/2014/09/es6-modules-final.html

https://jakearchibald.com/2017/es-modules-in-browsers/

https://imweb.io/topic/582293894067ce9726778be9

https://v8.dev/features/modules

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端皮小蛋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4. Re-exporting (别名导出)
  • 5. Module Redirects (中转模块导出)
  • 3. Rename multiple exports during import
  • 4. Import a module for its side effects only
  • 5. Dynamic Imports
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档