• 再苦再累也必须要弄懂的:ES6的ES Module


    再苦再累也必须要弄懂的:ES6的ES Module

    Introduciton

    • 今天就来讲一讲,ES6 的模块化规范 ES Module。

    • 什么是模块化?

      百度百科解释道:模块化是指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程,有多种属性,分别反映其内部特性。

      我的理解:将代码按照 功能,作用,类别等,划分成一个个独立的文件,每个文件可以看做一个模块。

    • ES6 提供的模块化方案叫做 ES Module,简称 esm

    • 早期的 Javascript 是没有模块化的概念,如果想利用 Javascript 构建一个大型项目,就会有很多问题。例如 1.命名冲突;2.变量私有;2.依赖关系的管理等问题。

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

    运行ES Module规范的 js 文件

    在讲 ES Module 具体的知识点之前,必须要先讲,如何执行我们的 ES Module 的代码,方便后续我们调试。

    运行代码主要两个环境:浏览器和 NodeJs,我在这里分别做一下说明。

    浏览器环境

    前置逻辑

    正常的情况,我们可以在 html 页面中,直接使用 script 标签引入我们的 js 文件,如下述案例所示。

    <script src="./main.js"></script>
    <!-- <script type="application/javascript" src="./main.js"></script> -->
    
    • 1
    • 2

    script 标签有一个 type 属性,默认情况为:“application/javascript”。所以大多数情况都简写了。但是在 ES Module 中,为了告诉浏览器我们是用的 ES Module,需要修改 type属性为 “module”。

    如下所示:

    <script src="./main.js" type="module">script>
    
    • 1

    演示具体代码:

    错误的情况:

    // main.js
    /* 使用了 ES6 的命令 export */
    export var a = 1
    
    • 1
    • 2
    • 3
    <body>
      <script src="./main.js">script>
      /* 不写type属性的情况,会直接报错 */
      // Uncaught SyntaxError: Unexpected token 'export' (at main.js:1:1)
    body>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    正确的情况:

    <body>
      <script src="./main.js" type="module">script>
    body><body>
      <script type="module">
        import { a } from './main.js'
        console.log(a) // 1
      script>
    body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    本地直接打开 带有 加载文件的逻辑

    有上述的解释可以得到如下结论:

    <script type="module" src="./foo.js"></script>
    <!-- 等同于 -->
    <script type="module" src="./foo.js" defer></script>
    
    • 1
    • 2
    • 3

    所以 可以理解为,异步加载 ./foo.js 文件,等页面渲染完毕之后再开始执行我们的脚本。

    当然也可以给