ES6中Module的加载实现

 1.浏览器加载

说明:浏览器脚本的默认语言时JS,因此type="application/javascript"。因此可以省略的,渲染引擎遇到<script>标签就会停下来,等到执行完脚本,再继续向下渲染。

1.1加载规则

说明:浏览器加载ES6模块,也是用script标签,但是要加入type="module"属性,这是异步加载,不会造成堵塞浏览器,等到整个页面渲染完,再执行模块脚本,等同于使用了defer属性。defer是“渲染完再执行”,async是“下载完就执行”。

<script src="url" defer></script>
<script src="url" async></script> 
<!-- defer是渲染完再执行,async是下载完就执行 -->

2.  ES6模块于CommonJS模块的差异

  1. CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用。
  2.  CommonJS模块是运行时加载,ES6模块是编译时输出接口。
  3. CommonJS模块的require()是同步加载模块,ES6模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。

3.Node.js的模块加载方法

说明:

js有两种模块,一种是ES6模块,简称ESM;另一种是CommonJS模块,简称CJS。

CommonJS模块是Node.js专用的,与ES6模块不兼容。语法上面CommonJS模块使用require()和module.exports,ES6模块使用import和export。

但是Node.js已经默认打开了ES6模块支持。Node.js要求ES6模块采用.mjs后缀文件名。也就是说,只要脚本文件里面使用import或者export。如果不希望将后缀名改成.mjs,可以在项目的package.json文件中,指定type字段为module。.mjs文件总是以 ES6 模块加载,.cjs文件总是以 CommonJS 模块加载,.js文件的加载取决于package.json里面type字段的设置。

4.package.json和main字段

说明: package.json文件有两个字段可以指定模块的入口文件;main和exports。比较简单的模块,可以只使用main,指定模块加载的入口文件。

  {   
    
        "main":"url"
    } 

5.package.json的exports字段

说明:exports字段的优先级高于main字段。它有多种用法。可以指定脚本或子目录的别名。

 {
        "exports":{
            "./src":"./src"
            // 第一个是新名字,第二个是旧名字
        }
    } 

 6.main的别名

说明: exports字段的别名如果是.,就代表模块的主入口,优先级高于main字段,并且可以直接写成exports字段的值。

 {
        "exports":{
            ".":"./src"
        }
    }
//相等
      {
        "exports":"./url"
      }

7.条件加载

说明:利用.别名,可以为ES6模块和CommonJS指定不同的入口。

{
  "type": "module",
  "exports": {
    ".": {
      "require": "./main.cjs",
      "default": "./main.js"
    }
  }
} 

8.ES6模块加载CommonJS模块

说明:ES6模块的import命令可以加载CommonJS模块,只能整体加载。

9.支持两种格式的模块

"exports":{
  "require": "./url",
  "import": "./url"
}

10.CommonJS模块的加载原理

说明:CommonJS 的一个模块,就是一个脚本文件。require命令第一次加载该脚本,就会执行整个脚本,然后在内存生成一个对象。CommonJS 模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存。

猜你喜欢

转载自blog.csdn.net/m0_62785037/article/details/130819926